I offer a service which needs the correct location and heading of the mobile device the user is accessing my service with. It was relatively easy to get the information but now I am stuck at finding out how accurate the heading I received is.
Since I'm not using any framework for this or develop in Android/iOS, where there are solutions for that problem, I'd need a solution only depending on javascript (+ 3rd party libraries).
I've found the Generic Sensor API from W3C but couldn't find any sensor which hold that information. Neither the Accelerometer-, nor the AbsoluteOrientationSensor held the needed information.
My current code looks like that..
let accelerometer = null;
try {
accelerometer = new Accelerometer({ frequency: 60 });
accelerometer.addEventListener('error', event => {
// Handle runtime errors.
if (event.error.name === 'NotAllowedError') {
console.log('Permission to access sensor was denied.');
} else if (event.error.name === 'NotReadableError') {
console.log('Cannot connect to the sensor.');
}
});
accelerometer.addEventListener('reading', (event) => {
console.log(accelerometer);
console.log(event);
});
accelerometer.start();
.. but since the problem if more of a 'finding the right tool to do the job'-type, it won't help much in better depicting my problems. Further, Google uses kind of the same functionality I'm aiming for in Google Maps, so theoretically there must be a way to get the heading accuracy.
So, in conclusion, is there any way to retrieve the heading accuracy in a simple javascript environment?
Thanks!
Related
When I initiate auto-landing in the DJI Fly app I sometimes get the following message, especially under bad lighting conditions:
Now, in my own code, when I call DJIFlightController.startLandingWithCompletion, the drone would not land and the completion block gets executed without any error.
My question is, how can I intercept the equivalent to DJIs error message as shown above? What code is relevant for that?
EDIT 1:
I am also checking if a landing confirmation is needed with the following code:
func observeConfirmLanding() {
guard let confirmLandingKey = DJIFlightControllerKey(param: DJIFlightControllerParamConfirmLanding) else { return }
DJISDKManager.keyManager()?.startListeningForChanges(on: confirmLandingKey, withListener: self) { (oldValue: DJIKeyedValue?, newValue: DJIKeyedValue?) in
DispatchQueue.main.async {
if let oldBoolValue = oldValue?.boolValue,
let newBoolValue = newValue?.boolValue,
oldBoolValue != newBoolValue {
self.landingConfirmationNeeded = newBoolValue
self.logger.debug("Landing confirmation is needed")
}
}
}
}
It never enters the closure.
As I understood the landing confirmation might be needed at a height of 0.3m, but in my case, the landing process gets interrupted at different heights that are more than 0.3m, e.g. already at 2m or 1.5m
EDIT 2:
I have changed the surface below the drone in my basement by adding a bright carpet with a distinct pattern. This improves the whole stability of the drone AND even more important: The drone just lands without being interrupted. I do not get the warning message in the DJI Fly app any more.
I check for isLandingConfirmation the way Brien suggests in his comment, I finally get true when testing this in the simulator.
extension FlightControllerObserver: DJIFlightControllerDelegate {
func flightController(_ fc: DJIFlightController, didUpdate state: DJIFlightControllerState) {
if (landingConfirmationNeeded != state.isLandingConfirmationNeeded) {
landingConfirmationNeeded = state.isLandingConfirmationNeeded
}
}
But, when I test this in my basement (flight mode "OPTI") and outside (flight mode "GPS") the drone just lands without waiting for any confirmation.
While I learned a lot, it is still a miracle to me which class in the DJI Mobile SDK is responsible for "throwing" that warning message.
If the completion handler completes without any error you might need to check if isLandingConfirmationNeeded in DJIFlightControllerState is set to true. If thats the case then you will need to implement the function confirmLandingWithCompletion.
Sounds relevant to your experience looking at the documentation
(void)confirmLandingWithCompletion:(DJICompletionBlock)completion Confirms continuation of landing action. When the clearance between
the aircraft and the ground is less than 0.3m, the aircraft will pause
landing and wait for user's confirmation. Can use
isLandingConfirmationNeeded in DJIFlightControllerState to check if
confirmation is needed. It is supported by flight controller firmware
3.2.0.0 and above.
The landingProtectionState property of the DJIVisionControlState class could be a good place to look for the cause of that error message. One of the potential states that sounds relevant is
DJIVisionLandingProtectionStateNotSafeToLand -> Landing area is not flat
enough to be considered safe for landing. The aircraft should be moved
to an area that is more flat and an auto-land should be attempted
again or the user should land the aircraft manually.
Also within a section of DJI's documentation there is a section on an article about flight control that talks about landing protection and forcing a landing. I couldn't see any functions in the SDK to force a landing.
You should be aware of that the fly app does not use the sdk internally. It uses the middlelayer directly.
You often get different behaivor when using the SDK compared to the app. Some functions are not available at all.
I usually disable it completly, I want it to land when I say so :-)
(exit_landing_ground_not_smooth_enable g_config.landing.exit_landing_ground_not_smooth_enable)
I am trying to get the location accurate to 50m on android.
this.geolocation.getCurrentPosition(posOptions).then((resp) => {
// resp.coords.longitude
console.log(resp);
if(resp.coords.accuracy<50)
{
this.loading.hide();
}
else{
alert("The accuracy is "+ resp.coords.accuracy + " m. Location Accuracy is too low. Please Restart your phone.");
this.loading.hide();
return false ;
}
}).catch((error) => {
console.log('Error getting location', error);
});
Here I tried to submit location multiple time always it gives error
low accuracy as the location accuracy is 1500m regardless of the fact
that accuracy on android phone is set to "High Accuracy".
No matter how many time I submit the accuracy does not increase until I restart the mobile phone.
Also on the google map the location is incorrect.
How to achieve location precision?
What should be done here in order to get the accurate location without restarting or doing anything as such. The accuracy must be under 100m. Here I am using Ionic Native geolocation PLugin Link.
Please suggest a way to achieve this.
Are there any other service providing location data other than google Map api?
I have a leaflet project where I am delivering a continuous stream of 'coordinates' via WebSockets to the client browser. I need to be able to display markers corresponding to those locations for a set period of time (something like 1 or 2 seconds) and then remove them (to make room for more locations).
Can anyone help me out or point me in the direction of resources wherein I could find some help?
Thanks!
Edit : Why the downvote? Its a legitimate and common question and one without a lot of solutions online.
Here is some code from the documentation (http://leafletjs.com/reference-1.0.3.html#layer):
var layer = L.Marker(latLng).addTo(map);
layer.addTo(map);
layer.remove();
So in order to remove it after 2 seconds, I think you could try this one:
var layer = L.Marker(latLng).addTo(map);
layer.addTo(map);
setTimeout(function() {
layer.remove();
}, 2000);
Example
Okay, so I have spent a large amount of time searching the internet for help on this to no success, so I would like some help.
I am making a game with SpriteKit, and I have decided to implement my own leaderboard style, rather than the clunky Game Center default. I have managed to log the user into GC, but cannot find the correct (and working) Swift 3 code for pulling information from the leaderboard. I want to pull the top 10 score, along with the current user score (if they aren't already in the top 10). The information I would like from them is position, username and score.
I know this is a fairly simple concept, but every tutorial online either uses the default GC view, or is extremely old/outdated code which no longer works. I just need to know how to pull this information from the leaderboard, then I can process it all myself!
Thank you for any help in advance!
It seems like Apple doesn't have proper example code in Swift, but here's a Swift version loosely based on their Objective-C example:
let leaderboard = GKLeaderboard()
leaderboard.playerScope = .global
leaderboard.timeScope = .allTime
leaderboard.identifier = "YourIdentifier"
leaderboard.loadScores { scores, error in
guard let scores = scores else { return }
for score in scores {
print(score.value)
}
}
Note, this is just a translation from Apple's Objective-C code, and I haven't tested it with real data.
I'm creating a Google Earth tour and I'd really like to be able to make this interactive so users can choose where they go.
I was thinking I could create each "scene" as a separate tour each ending with a decision (most likely through a placemark with a balloon containing a question and links for each possible answer).
However I'm having difficulties finding a way to load the next tour like this. Each tour will be available in a KMZ format and I'm open to if the new tour should be loaded from within the existing tour or from an external eventListener in the Google Earth API.
Any help or pointers would be gratefully received.
Dave
I presume you have already worked out how to play a tour using the plugin.If not, check this link
then you need to open a balloon at the end of each tour, which is two steps. Determine when the tour is ended, and then open a balloon which has a button or buttons to choose next tour.
To determine if the tour has ended use this function
function checkTour() {
// checks to see if it can read the time of the tour
// if it can it completes rest of function
try {
var duration = ge.getTourPlayer().getDuration();
var cTime = ge.getTourPlayer().getCurrentTime();
} catch (e) {
alert('error');
return false;
}
if (duration == cTime) {
// tour is over
tourOverSoOpenBalloonFunction();
} else {
// wait 1 second and check again
setTimeout('checkTour()',1000);
}
}
then use this example page of creating a balloon with a button in it that executes some javascript to load the next tour
essentially you would be changing this line
balloon.setContentString(
'Alert!');
to
balloon.setContentString(
'Tour 1<br/>Tour 2');
I might have missed something, but this should get you going in the right direction