Speed not updating when using GeoCoordinateWatcher - windows-phone-7

When using the GeoCoordinateWatcher class to get updated GPS position and speed inside my Windows Phone application, the latitude and longitude updates, but the speed remains at a constant value: 5.95 (as well as the course).
I initialize the Geo Watcher with the following code:
GeoCoordinateWatcher GeoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
And start the listening process using the snipped:
GeoWatcher.StatusChanged += GeoWatcherStatusChanged;
GeoWatcher.PositionChanged += OnGeoWatcherPositionChanged;
GeoWatcher.MovementThreshold = 0.5;
GeoWatcher.Start();
And finally, the method OnGeoWatcherPositionChanged contains the following code:
textSpeed.Text = args.Position.Location.Speed.ToString();
Where textSpeed is a simple TextBox.
Does anyone know why Speed remains at a constant value? Thanks in advance.

Related

What are the stages for initialising and executing a WayPoint Mission in DJI Windows SDK?

I am using the following code to try and initialise a Waypoint Mission and load it to the aircraft ( a DJI Mavic Air).
I first check the state of the waypoint handler, then initialise a waypoint, add it to the list, then include the list in the initialised waypoint mission. The method for loading the waypoint mission to the aircraft is then run and the state checked afterwards. The output from the debugs is seen below:
Waypoint state = READY_TO_UPLOAD;
New waypoint location - 55.555549621582,0.555555522441864
Load mission return value - INVALID_REQUEST_IN_CURRENT_STATE
Waypoint state = READY_TO_UPLOAD
The state of READY_TO_UPLOAD suggests that it is in a suitable state to upload the waypoint mission according to the Windows SDK documentation, however clearly the upload fails and the state remains unchanged.
What needs to be changed in order for the waypoint mission to successfully load so it can be run by the aircraft?
//Check the initial state of the waypoint handler
var currentState = DJISDKManager.Instance.WaypointMissionManager.GetWaypointMissionHandler(0).GetCurrentState();
Debug.WriteLine("Waypoint state = {0}", currentState);
//Initialise new location coordinate
randomLocation.X = 55.55555;
randomLocation.Y = 0.55555555;
Debug.WriteLine("New waypoint location - {0},{1}", randomLocation.X, randomLocation.Y);
LocationCoordinate2D waypointLocation = new LocationCoordinate2D { latitude = randomLocation.X, longitude = randomLocation.Y };
// Create a waypoint instance and add to waypoint list
Waypoint waypoint = new Waypoint { location = waypointLocation };
waypointList.Add(waypoint);
//Create new waypoint mission instance and load in the waypoint list
WaypointMission waypointMission = new WaypointMission
{
waypointCount = 1,
autoFlightSpeed = 2.5,
finishedAction = WaypointMissionFinishedAction.NO_ACTION,
headingMode = WaypointMissionHeadingMode.USING_WAYPOINT_HEADING,
flightPathMode = WaypointMissionFlightPathMode.CURVED,
repeatTimes = 0,
waypoints = waypointList,
missionID = 1
};
//load the waypoint mission to the aircraft and check the current state
var load_retval = DJISDKManager.Instance.WaypointMissionManager.GetWaypointMissionHandler(0).LoadMission(waypointMission); ;
Debug.WriteLine("Load mission return value - {0}", load_retval);
currentState = DJISDKManager.Instance.WaypointMissionManager.GetWaypointMissionHandler(0).GetCurrentState();
Debug.WriteLine("Waypoint state = {0}", currentState);
After a long time of trail and error I figured out the steps needed to start a waypoint mission:
Setting the SDK into ground station mode
First you have to set the SDK into ground station mode with the following method:
DJISDKManager.Instance.ComponentManager.GetFlightControllerHandler(0, 0).SetGroundStationModeEnabledAsync(new BoolMsg() { value = true })
Loading the mission
Second you have to load your waypoint mission to the SDK, using the following method:
DJISDKManager.Instance.WaypointMissionManager.GetWaypointMissionHandler(0).
LoadMission(waypointMission)
Where waypointMission could bethe waypoint mission in your question. This waypoit mission have to follow some restrictions. For example the total distance can't be to long(not sure what the exact number is). This methode will return an SDKError if there is something wrong with the mission.
Uploading the waypoint mission to the drone
After the mission is loaded to the SDK it still has to be uploaden to the drone. This is done with the following method:
DJISDKManager.Instance.WaypointMissionManager.GetWaypointMissionHandler(0).
UploadMission()
(optional) Stating the simulator
At this point you could start simulation mode if you don't want your drone to actually take off. This can be done with the following code:
FlightControllerHandler _flightControllerHandler = DJISDKManager.Instance.ComponentManager.GetFlightControllerHandler(0, 0);
var simSettings = new SimulatorInitializationSettings()
{
latitude = 0,
longitude = 0,
satelliteCount = 12
};
await _flightControllerHandler.StartSimulatorAsync(simSettings);
It's important that the satelliteCount is above 10. Else the SDK wil give and error about the GPS signal strength not being good enough.
Starting the mission
Finaly you can start the waypoint mission as follows
DJISDKManager.Instance.WaypointMissionManager.GetWaypointMissionHandler(0).StartMission()
Other things to note:
Most of these calls are async and are best awaited.
Even if you await the calls I noticed uploading the mission would not be finished at the time the method finished. So if you would call StartMission() right after UploadMission() this could result in a INVALID_REQUEST_IN_CURRENT_STATE
I worked around this by having a seperate button for loading and starting the mission.This way I can wait for the mission to be uploaded before I start the mission.
All of the above methods return a SDKError type. If all went well this would be a NO_ERROR it's important to check if this is the case for every call.

Application crashes when asking for a frame that involves COORDINATE_FRAME_CAMERA_DEPTH

I'm using the JPointCloud sample app, and modifying it a little bit:
In JPointCloud.java : SetUpExtrinsics(), I added:
TangoPoseData depth2devicePose = new TangoPoseData();
framePair.baseFrame = TangoPoseData.COORDINATE_FRAME_DEVICE;
framePair.targetFrame = TangoPoseData.COORDINATE_FRAME_CAMERA_DEPTH;
try {
depth2devicePose = mTango.getPoseAtTime(0.0, framePair);
} catch (TangoErrorException e) {
Toast.makeText(getApplicationContext(), R.string.TangoError,
Toast.LENGTH_SHORT).show();
The application crashes when reaching the line:
depth2devicePose = mTango.getPoseAtTime(0.0, framePair);
I tried with other combinations of frame, but each time COORDINATE_FRAME_CAMERA_DEPTH is included, the app crashes.
Did I forget something ? Maybe to ask some kind of special permission for the depth camera ?
It indeed crashes on me as well.
However, according to the Java pointcloud example code (extrinsic query part), the correct way of querying the DEPTH_CAMERA w.r.t(with respect to) DEVICE transformation is using 'the inverse of DEVICE w.r.t IMU' multiply 'CAMAER w.r.t IMU', which is:
deive_T_camera = inverse(imu_T_device) * imu_T_camera
Also, note that the color camera, depth camera and camera are the same camera on the hardware level, so they actually share the same extrinsic.
Hope this helps.
Edit: the crashes actually throw an com.google.atap.tangoservice.TangoInvalidException. This might just be a frame pair not supported from API level, as mentioned before, the suggested way would be using other two matrices to compose the desired matrix in this case..

GPS accuracy Issues

I am developing a windows phone sports tracker app, that uses gps sensors to calculate the distance travelled by the runner, I am using geocoordinatewatcher class for the same, setting the movement threshold to 100. But, I find my app giving distance values even when the device is kept stationary. My app should give distance only when the device changes its position. I found the same bug in othere apps that are on the marketplace, please tell me where am I doing wrong?
My Code.
watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
watcher.MovementThreshold = 150;
watcher.PositionChanged += watcher_PositionChanged;
watcher.Start();
{
latitudeCurrent = e.Position.Location.Latitude;
longitudeCurrent = e.Position.Location.Longitude;
if (stepCounter == 0)
{
latitudePrevious = latitudeCurrent;
longitudePrevious = longitudeCurrent;
distanceTravelled += Math.Round(Calculate(latitudePrevious,longitudePrevious,latitudeCurrent,longitudeCurrent),2);
txbDistanceTravelled.Text = distanceTravelled.ToString();
txbCalories.Text=string.Format("{0:f0}", distanceTravelled * 65);
stepCounter++;
var millisPerKilometer = (distanceTravelled) * (System.Environment.TickCount - _previousPositionChangeTick);
txbPace.Text = TimeSpan.FromMilliseconds(millisPerKilometer).ToString(#"mm\:ss");
double hrs = counterTick / 3600;
if (!double.IsNaN((distanceTravelled / hrs)))
{
txbSpeed.Text = (distanceTravelled / hrs).ToString();
}
else
{
txbSpeed.Text = "0";
}
}
}
You are developing your app for Windows Phone 7 or Windows Phone 8? IF you are developing for the later, you need to use the new Geolocator class and not GeoCoordinateWatcher.
Also, as LewisBenge said, if you are testing This indoor you can get WiFi positions or even cellular data. It could be better to test outdoor.
Your GPS signal might be weak in the place where you are testing. Try it in the outdoor location.

Geolocator and accuracy in Windows Phone 8

I have a few questions about Geolocator and property DesiredAccuracy.
I have the method GetMyPosition:
public async Task<Geoposition> GetMyPosition()
{
Geoposition myGeoposition = null;
Geolocator myGeolocator = new Geolocator();
myGeolocator.DesiredAccuracy = PositionAccuracy.High;
try
{
myGeoposition = await myGeolocator.GetGeopositionAsync();
return myGeoposition;
}
catch (Exception ex)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Can't get the position");
});
return null;
}
}
1) Why
Geolocator.DesiredAccuracy = PositionAccuracy.High;
Geolocator.GetGeopositionAsync();
always return Geoposition.Coordinate.PositionSource = Cellular with accuracy 400 - 1600 m (on device Nokia Lumia 520)?
2) Under what settings I can get a high accuracy (50 - 100 m) and PositionSource = Satellite?
3) If I have the loaded maps on my device and I activated the airplane mode on the device, then code
Geolocator myGeolocator = new Geolocator();
myGeolocator.DesiredAccuracy = PositionAccuracy.High;
try
{
myGeoposition = await myGeolocator.GetGeopositionAsync();
return myGeoposition;
}
will work? Without a celluar, only a satellite?
4) How strong is the precision of coordinates depends on the device?
Thanks in advance!
Taken from MSDN
Although the Location Service uses multiple sources of location information, and any of the sources may not be available at any given time (for example, no GPS satellites or cell phone towers may be accessible), the native code layer handles the work of evaluating the available data and choosing the best set of sources. All your application needs to do is to choose between high accuracy or the default, power-optimized setting. You can set this value when you initialize the main Location Service class, GeoCoordinateWatcher.
C#
GeoCoordinateWatcher watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
So it seems like you can't control which source is used but rather the available source will be used based on the specified position accuracy on GeoCoordinateWatcher. Try initializing a GeoCoordinateWatcher with high accuracy and see what happens
var geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
You can use
Geolocator myGeolocator = new Geolocator();
myGeolocator.DesiredAccuracyInMeters = 20;
...
to explicitly state how accurate you want the location to be which would allow the device to manage its power a little better but whether you get close to that accuracy with your result depends on the quality of the location the device can get. If you're inside a building for example you're not going to get something that accurate without connecting to WIFI

How to Monitor If my current Location is getting close to a preset Location

say, I have setUp a location I wanted to go for example Time Square ( LatLon :40.760586,-73.984852) in my WP App. Suppose, I want to travel in a taxi to go to Time Square and with my app turn on. How do I keep tracking my current GPS is getting closer to that place?? How to determine I am withing the range?? The below code is for current GPS.
GeoCoordinateWatcher tracker;
void tracker_PositionChanged(object sender, GeoPositionChangedEventArgs e)
{
textLatitude.Text = e.Position.Location.Latitude.ToString("0.000");
textLongitude.Text = e.Position.Location.Longitude.ToString("0.000");
}
Thank in advance. Appreciate your help.
The GeoCoordinate class already has GetDistanceTo() method
It can be used as follows:
GeoCoordinate start = new GeoCoordinate(startLatitude, startLongitude);
GeoCoordinate end = new GeoCoordinate(endLatitude, endLongitude);
double distance = start.GetDistanceTo(end);
You can set this to be calculated every time the GeoCoordinateWatcher class fires the "PositionChanged" event

Resources