Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Adobe AIR Development

Reply
Developer
jtegen
Posts: 6,541
Registered: ‎10-27-2010
My Device: HTC One, PlayBook, LE Z10, DE Q10
My Carrier: Verizon

Re: Using the compass in the AIR SDK Beta 10

On the Dev Alph device, the azimuth does change value from laying flat to standing up. For example:

Flat:
Azimuth = 0.5 (north) degrees
Pitch = 0.31 degrees
Roll = -0.02 degrees

Stand up still facing north:
Azimuth = -20 deg
Pitch = -36 deg
Roll = -89 deg
Please use plain text.
Developer
MauriceRice
Posts: 425
Registered: ‎03-17-2011
My Device: Developer
My Carrier: Telus

Re: Using the compass in the AIR SDK Beta 10


jtegen wrote:
On the Dev Alph device, the azimuth does change value from laying flat to standing up. For example:

Flat:
Azimuth = 0.5 (north) degrees
Pitch = 0.31 degrees
Roll = -0.02 degrees

Stand up still facing north:
Azimuth = -20 deg
Pitch = -36 deg
Roll = -89 deg

The roll is way off too. Are you comparing this to results on the PlayBook? Assuming that only pitch is changed, both azimuth and roll should be constant.  

 

When using my app on the Alpha (with my own ANE), I get expected results. When I increase the pitch and keep the device level (left-to-right), the azimuth remains constant . It's wrong but constantly wrong :smileywink:

 

I have just installed the SDK 10 beta but I haven't actually tried to compile and run anything yet.  Could you post your bare-bones test using the new SDK so that I can test it on my two PlayBooks and the Alpha Dev?    .                                                                                                                                                                      

_________________________
In the dark and need a sky map?
Discover What's up at App World.
Follow What's up on Facebook

Please use plain text.
Developer
jtegen
Posts: 6,541
Registered: ‎10-27-2010
My Device: HTC One, PlayBook, LE Z10, DE Q10
My Carrier: Verizon

Re: Using the compass in the AIR SDK Beta 10

Some of the code is from my framework, but you should be able to comment those parts out to something compileable:

package pages
{
	import com.lib.playbook.pages.ActionPage;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import qnx.events.RotationMatrixEvent;
	import qnx.fuse.ui.buttons.LabelButton;
	import qnx.fuse.ui.events.ActionEvent;
	import qnx.fuse.ui.events.NavigationEvent;
	import qnx.fuse.ui.text.Label;
	import qnx.fuse.ui.text.TextArea;
	import qnx.fuse.ui.text.TextFormat;
	import qnx.sensors.RotationMatrix;
	
	import shared.SharedData;
	
	public class RotationPage extends ActionPage
	{
		private var shared_data :SharedData = SharedData.instance;
		
		private var label     : Label = new Label();
		private var start_btn : LabelButton = new LabelButton();
		
		private var epsilon   : Label = new Label();
		
		private var matrix    : TextArea = new TextArea();
		
		private var azimuth   : Label = new Label();
		private var pitch     : Label = new Label();
		private var roll      : Label = new Label();
		
		private var rotation_service : RotationMatrix = new RotationMatrix();
		
		///////////////////////////////////////////////////////////
		public function RotationPage()
		{
			super();
			
			this.actionbar.showBackButton();
			this.actionbar.addEventListener( ActionEvent.ACTION_SELECTED, ActionSelected );
			this.actionbar.addEventListener( NavigationEvent.BACK_CLICKED, BackSelected );
			
			this.rotation_service.skipDuplicateEvents( true );
			this.rotation_service.setRequestedUpdateInterval( 750 );
			this.rotation_service.addEventListener(RotationMatrixEvent.UPDATE, GyroUpdate );
			
			var f:TextFormat = new TextFormat();
			f.color = 0xFFFFFF;
			f.size = 16 * 2;//this.shared_data.app.tabletRatio;
			
			this.label.text = 'Rotation';
			this.label.format = f;
			this.label.setActualSize( 200, 50 );
			this.addChild( this.label );
			
			this.epsilon.text = 'e=';
			this.epsilon.format = f;
			this.epsilon.setActualSize( 200, 50 );
			this.addChild( this.epsilon );
			
			this.addChild( this.matrix );
			
			this.azimuth.text = 'azimuth=';
			this.azimuth.format = f;
			this.azimuth.setActualSize( 600, 50 );
			this.addChild( this.azimuth );
			
			this.pitch.text = 'pitch=';
			this.pitch.format = f;
			this.pitch.setActualSize( 600, 50 );
			this.addChild( this.pitch );
			
			this.roll.text = 'roll=';
			this.roll.format = f;
			this.roll.setActualSize( 600, 50 );
			this.addChild( this.roll );
			
			this.start_btn.label = 'Start';
			this.start_btn.addEventListener(MouseEvent.CLICK, ToggleService );
			this.addChild( this.start_btn );
		}
		
		///////////////////////////////////////////////////////////////////////
		private function ToggleService( event :Event ) : void
		{
			if( this.start_btn.label == 'Start' )
			{
			  this.rotation_service.start();
			  this.start_btn.label = 'Stop';
			}
			else
			{
				this.rotation_service.stop();
				this.start_btn.label = 'Start';
			}
		}
		
		////////////////////////////////////////////////////////////////////
		override public function aboutToBeRemoved():void
		{
			if( this.start_btn.label == 'Stop' )
			{
				this.rotation_service.stop();
				this.start_btn.label = 'Start';
			}
		}
		
		///////////////////////////////////////////////////////////////////////
		private function GyroUpdate( event : RotationMatrixEvent ) : void
		{
			this.matrix.text = 'Matrix= ' + event.matrix.toString();
			this.epsilon.text = 'e= ' + event.accuracy;
			
			var az : Number = 0;
			var pi : Number = 0;
			var rl : Number = 0;
			
			if( event.matrix.length == 9 )
			{
				az = Math.atan2( event.matrix[1], event.matrix[4] );
				pi = Math.asin( -event.matrix[7] );
				rl = Math.atan2( -event.matrix[6], event.matrix[8] );
			}
			else
			{
				az = Math.atan2( event.matrix[1], event.matrix[5] );
				pi = Math.asin( -event.matrix[9] );
				rl = Math.atan2( -event.matrix[8], event.matrix[10] );
			}
			
			this.azimuth.text = 'azimuth= ' + ( az * 180 / Math.PI ).toFixed(2);
			this.pitch.text = 'pitch= ' + ( pi * 180 / Math.PI ).toFixed(2);
			this.roll.text = 'roll= ' + ( rl * 180 / Math.PI ).toFixed(2);
				
		}
		
		///////////////////////////////////////////////////////////////////////
		private function BackSelected( event :Event ) : void
		{
			this.shared_data.dispatchEvent( new Event( SharedData.SHOW_HOME_PAGE ) );
		}
		
		///////////////////////////////////////////////////////////////////////
		private function ActionSelected( event :Event ) : void
		{
			
		}
		
		/////////////////////////////////////////////////////////////////////
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList( unscaledWidth, unscaledHeight );
			this.label.setPosition( 10, 10 );
			this.start_btn.setPosition( 10, this.label.y + this.label.height + 10 );
			this.epsilon.setPosition( 10, this.start_btn.y + this.start_btn.height + 10 );
			
			this.matrix.setPosition( 10, this.epsilon.y + this.epsilon.height + 10 );
			this.matrix.setActualSize( unscaledWidth - 20, 500 );
			
			this.azimuth.setPosition( 10, this.matrix.y + this.matrix.height + 10 );
			this.pitch.setPosition( 10, this.azimuth.y + this.azimuth.height + 10 );
			this.roll.setPosition( 10, this.pitch.y + this.pitch.height + 10 );
		}
	}
}

 

Please use plain text.
Developer
MauriceRice
Posts: 425
Registered: ‎03-17-2011
My Device: Developer
My Carrier: Telus

Re: Using the compass in the AIR SDK Beta 10

Thanks for the code.

_________________________
In the dark and need a sky map?
Discover What's up at App World.
Follow What's up on Facebook

Please use plain text.
Developer
jtegen
Posts: 6,541
Registered: ‎10-27-2010
My Device: HTC One, PlayBook, LE Z10, DE Q10
My Carrier: Verizon

Re: Using the compass in the AIR SDK Beta 10

I had the device upside down when I lifted it from flat to upright (darn that power chord).

Flat:

Azimuth: 0.1 (north)

Pitch: -0.2

Roll: 0.05

 

Lifted so device is straight up:

Azimuth: -10

Pitch: -89

Roll: -14

 

So it seems it is OK.  Azimuth is very sensitive when the device is held upright.  But should be OK. 

Please use plain text.
Developer
MauriceRice
Posts: 425
Registered: ‎03-17-2011
My Device: Developer
My Carrier: Telus

Re: Using the compass in the AIR SDK Beta 10


jtegen wrote:

I had the device upside down when I lifted it from flat to upright (darn that power chord).

... 

So it seems it is OK.  Azimuth is very sensitive when the device is held upright.  But should be OK. 

Excellent - looks like you're good to go.. It's so sensitive when it's near upright because the horizontal component of the magnetic field is relatively small with the device in this orientation. It's a bit of a pain for my astronomy app but shouldn't be a big deal for a mapping app where the device can stay relatively flat.
How is accuracy on your Alpha device? Does it appear to be pointing somewhere near magnetic north? I would also appreciate you trying out the code for the geomagnetic model (just to make sure I pasted in all of the code).

 

_________________________
In the dark and need a sky map?
Discover What's up at App World.
Follow What's up on Facebook

Please use plain text.
Developer
jtegen
Posts: 6,541
Registered: ‎10-27-2010
My Device: HTC One, PlayBook, LE Z10, DE Q10
My Carrier: Verizon

Re: Using the compass in the AIR SDK Beta 10

I'm not certain how accurate it is.  Compared to a playbook compass app (and looking at where the sun is early in the morning), when laying the dev alpha flat and the top to the north (as shown from the playbook), the azimuth is -67 deg.  Standing up, it is ~-90 deg.  Pitch and yaw look correct.

 

Once I have assurance the azimuth is reporting correctly, adding the lat/lon correction will be the next step.

 

The device would probably never be held flat.  It would either be held at a pitch of about 45 deg or upright in a car mount.  So if the azimuth cannot be done that well, it would probably not work out. 

Please use plain text.
Developer
MauriceRice
Posts: 425
Registered: ‎03-17-2011
My Device: Developer
My Carrier: Telus

Re: Using the compass in the AIR SDK Beta 10

I am posting a test app in the hope that RIM can use it to hasten bug fixes. The main problem with the current API is that the setting for event interval has no impact on the rate that events are dispactched. This appears to create a bottleneck causing the readings to be inaccurate and to drift in random directions. I moved the rendering to a timer function and this seems to help the situation. I had to do a similar thing with my own ANE because the AS3 side of the ANE is just not able to cope with a high volume of events in the queue.

 

The normal orientation (i'e the directions of the x, y axes) are different on PlayBook and the Dev Alpha. For the Alpha, the device is held in portrait position with the barcode pointing toward you. It is a devil to achieve a good calibration. It takes some patience to get a consistent accuracy of 3 (highest) but if it remains at 3 most of the time then the readings are fairly accurate. Restarting the service and/or the app is sometimes required.

 

Implementing the following code should help you test your app while we are waiting for RIM to fix the bugs. Here is the code:

 

package 
{
	//import com.lib.playbook.pages.ActionPage;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import qnx.events.RotationMatrixEvent;
	import qnx.fuse.ui.buttons.LabelButton;
	import qnx.fuse.ui.events.ActionEvent;
	import qnx.fuse.ui.events.NavigationEvent;
	import qnx.fuse.ui.text.Label;
	import qnx.fuse.ui.text.TextArea;
	import qnx.fuse.ui.text.TextFormat;
	import qnx.sensors.RotationMatrix;
	
	//import shared.SharedData;
	[SWF(width="1024", height="600", backgroundColor="#000000", frameRate="30")]
	public class OrientationTest extends Sprite
	{
		
		private var label     : Label = new Label();
		private var start_btn : LabelButton = new LabelButton();
		
		private var azimuth1   : Label = new Label();
		
		private var matrix    : TextArea = new TextArea();
		
		private var azimuth   : Label = new Label();
		private var pitch     : Label = new Label();
		private var roll      : Label = new Label();
		
		private var rotation_service : RotationMatrix = new RotationMatrix();
		private var rotationMatrixEvent:RotationMatrixEvent;
		
		private var worker:Timer = new Timer( 200 ); 
		
		///////////////////////////////////////////////////////////
		public function OrientationTest()
		{
			super();
			
				
			this.rotation_service.skipDuplicateEvents( true );
			this.rotation_service.setRequestedUpdateInterval( rotation_service.getDelayDefault()  );
			this.rotation_service.addEventListener(RotationMatrixEvent.UPDATE, this.matrixUpdate );
			
			worker.addEventListener( TimerEvent.TIMER, render );
			
			var f:TextFormat = new TextFormat();
			f.color = 0xFFFFFF;
			f.size =  50;
			
			this.label.text = '';
			this.label.format = f;
			//this.label.setActualSize( 200, 50 );
			label.height = 60;
			label.width = 1200;
			this.addChild( this.label );
			
			this.azimuth1.text = '';
			this.azimuth1.format = f;
			azimuth1.height = 60;
			azimuth1.width = 1200
			this.addChild( this.azimuth1 );
			
			this.azimuth.text = '';
			azimuth.format = f;
			azimuth.height = 60;
			azimuth.width = 1200;
			this.addChild( this.azimuth );
			
			this.pitch.text = '';
			this.pitch.format = f;
			pitch.height = 60;
			pitch.width = 1200
			this.addChild( this.pitch );
			
			this.roll.text = '';
			this.roll.format = f;
			roll.height = 60;
			roll.width = 1200
			this.addChild( this.roll );
			
			this.start_btn.label = 'Start';
			this.start_btn.addEventListener(MouseEvent.CLICK, ToggleService );
			this.addChild( this.start_btn );
			
			//super.updateDisplayList( unscaledWidth, unscaledHeight );
			this.start_btn.setPosition( 10, 10 );
			this.label.setPosition( 10, this.start_btn.y + this.start_btn.height + 10 );
			this.azimuth1.setPosition( 10, this.label.y + this.label.height + 10 );
			
			this.azimuth.setPosition( 10, this.azimuth1.y + this.azimuth1.height + 10 );
			this.pitch.setPosition( 10, this.azimuth.y + this.azimuth.height + 10 );
			this.roll.setPosition( 10, this.pitch.y + this.pitch.height + 10 );
			showHelp();
			
			trace( "default delay=" + rotation_service.getDelayDefault() );
			trace( "max delay=" + rotation_service.getDelayMax() );
			trace( "min delay=" + rotation_service.getDelayMin() );
		}
		
		///////////////////////////////////////////////////////////////////////
		private function ToggleService( event :Event ) : void
		{
			if( this.start_btn.label == 'Start' )
			{
				worker.start();
				this.rotation_service.start();
				this.start_btn.label = 'Stop';
			}
			else
			{
				worker.stop();
				this.rotation_service.stop();
				this.start_btn.label = 'Start';
				showHelp();
			}
		}
		
		////////////////////////////////////////
		private function showHelp():void{
			label.text="Using default interval= " + String(rotation_service.getDelayDefault())+ " although this"; 
			azimuth1.text="setting has no effect on frequency of events."
			azimuth.text="Roll, spin and tilt device until accuracy=3. If ";
			pitch.text="readings are incorrect, stop service then restart.";
			roll.text="Restart the app if calibration is futile.";
		}
		
		///////////////////////////////////////////////////////////////////////
		private function render( evt:Event ):void
		{
			if (rotationMatrixEvent==null) return;
			var az : Number = 0;
			var pi : Number = 0;
			var rl : Number = 0;
			
			this.label.text = 'accuracy= ' +String(rotationMatrixEvent.accuracy);
			
			//calc totation around z axis (azimuth), y axis (pitch) and z axis (roll))
			az = Math.atan2( rotationMatrixEvent.matrix[1], rotationMatrixEvent.matrix[4] );
			pi = Math.asin( -rotationMatrixEvent.matrix[7] );
			rl = Math.atan2( -rotationMatrixEvent.matrix[6], rotationMatrixEvent.matrix[8] );
			
			az = az * 180 / Math.PI; //radians to degrees
			var az1:Number = rev(az);
			this.azimuth1.text = 'raw azimuth  = ' + az.toFixed(2);
			this.azimuth.text =  'normalized az= ' + az1.toFixed(2);
			this.pitch.text = 'pitch= ' + ( pi * 180 / Math.PI ).toFixed(2);
			this.roll.text = 'roll= ' + ( rl * 180 / Math.PI ).toFixed(2);
		}
		
		
		///////////////////////////////////////////////////////////////////////
		private function matrixUpdate( event : RotationMatrixEvent ) : void
		{
	
			rotationMatrixEvent = event;
		}
		
		///////////////////////////////////////////////////////////////////////
		//normalizes a number to be in the range 0 to 360
		private static function rev( x:Number ):Number {
			if (x<=0) x += 360;
			return x - Math.floor(x / 360.0) * 360.0;
		}
	}
}

 

_________________________
In the dark and need a sky map?
Discover What's up at App World.
Follow What's up on Facebook

Please use plain text.
Developer
jtegen
Posts: 6,541
Registered: ‎10-27-2010
My Device: HTC One, PlayBook, LE Z10, DE Q10
My Carrier: Verizon

Re: Using the compass in the AIR SDK Beta 10

Thanks. I will try to time updates to see if that will settle out the numbers a little. I did notice that too about the interval update not having any changes.
Please use plain text.