I'm trying to show the location of a DJI Drone on the Mapbox map and constantly update it's location.
This is what I'm doing.
private void addDroneMarker(double latitude, double longitude){
Bitmap bitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.aircraft_icon)).getBitmap();
AnnotationPlugin annotationAPI = AnnotationPluginImplKt.getAnnotations(mapView);
pointAnnotationManager = PointAnnotationManagerKt.createPointAnnotationManager(annotationAPI, new AnnotationConfig());
PointAnnotationOptions pointAnnotationOptions = new PointAnnotationOptions()
.withPoint(Point.fromLngLat(longitude, latitude))
.withIconImage(bitmap);
dronePoint = pointAnnotationManager.create(pointAnnotationOptions);
}
private void updateDroneMarker(double latitude, double longitude){
dronePoint.setPoint(Point.fromLngLat(longitude, latitude));
pointAnnotationManager.update(dronePoint);
}
private void initFlightController(){
BaseProduct product = FPVApplication.getProductInstance();
if (product != null && product.isConnected()) {
if (product instanceof Aircraft) {
mFlightController = ((Aircraft) product).getFlightController();
}
}
if (mFlightController != null) {
mFlightController.setStateCallback(new FlightControllerState.Callback() {
#Override
public void onUpdate(FlightControllerState djiFlightControllerCurrentState) {
droneLocationLat = djiFlightControllerCurrentState.getAircraftLocation().getLatitude();
droneLocationLng = djiFlightControllerCurrentState.getAircraftLocation().getLongitude();
updateDroneMarker(droneLocationLat, droneLocationLng);
}
});
}
}
I create the drone annotation when the map loads and everytime the drone gives me a new location from the callback I update its location.
But my problem is, sometimes when I'm moving the map it gives me an error
Error while setting camera options : std::exception
This error could cause the application to crash with a Fatal Error
Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x787c881d0c in tid 17420 (RenderThread), pid 17347
And I realized that this error was caused by the UpdateDroneMarker (maybe because of the camera Animation), so I'm trying to find a different way to update the drones location. Hope someone could help me, thank you.
Try running on ui thread. I don't know for specific for mapbox, however callbacks from dji are not running on ui thread, so I would try that first. Otherwise you will get all kinds of strange errors.
Related
I am trying to setup an ImageAnalyzer with my Android app so I can run object classification using Google's ML Kit API. The issue I am currently facing, as the title suggests, is constantly seeing the error "Failed to initialize detector".
I've reread this tutorial about three times now and followed this post about someone facing the same error (although for a different reason) to no avail. I've also made sure everything with the CameraX API (except the ImageAnalyzer code that I will show in a second) works as expected.
As mentioned in the ML Kit documentation, here is the code I have regarding setting up a LocalModel, a CustomObjectDetectorOptions, and an ObjectDetector:
LocalModel localModel = new LocalModel.Builder()
.setAssetFilePath("mobilenet_v1_1.0_224_quantized_1_metadata_1.tflite")
.build();
CustomObjectDetectorOptions customObjectDetectorOptions =
new CustomObjectDetectorOptions.Builder(localModel)
.setDetectorMode(CustomObjectDetectorOptions.STREAM_MODE)
.enableClassification()
.setClassificationConfidenceThreshold(0.5f)
.setMaxPerObjectLabelCount(3)
.build();
ObjectDetector objectDetector = ObjectDetection.getClient(customObjectDetectorOptions);
Here is the ImageAnalyzer code I have, which basically makes a call to the ML Kit API by way of the processImage helper method:
// Creates an ImageAnalysis for analyzing the camera preview feed
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setTargetResolution(new Size(224, 224))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(this),
new ImageAnalysis.Analyzer() {
#Override
public void analyze(#NonNull ImageProxy imageProxy) {
#SuppressLint("UnsafeExperimentalUsageError") Image mediaImage =
imageProxy.getImage();
if (mediaImage != null) {
Log.i(TAG, "Obtained ImageProxy object");
processImage(mediaImage, imageProxy)
.addOnCompleteListener(new OnCompleteListener<List<DetectedObject>>() {
#Override
public void onComplete(#NonNull Task<List<DetectedObject>> task) {
imageProxy.close();
}
});
}
}
});
Here is the processImage helper method, where I actually call objectDetector.process(...), the line of code that actually runs the tflite model.
private Task<List<DetectedObject>> processImage(Image mediaImage, ImageProxy imageProxy) {
InputImage image =
InputImage.fromMediaImage(mediaImage,
imageProxy.getImageInfo().getRotationDegrees());
return objectDetector.process(image)
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
String error = "Failed to process. Error: " + e.getMessage();
Log.i(TAG, error);
}
})
.addOnSuccessListener(new OnSuccessListener<List<DetectedObject>>() {
#Override
public void onSuccess(List<DetectedObject> results) {
String success = "Object(s) detected successfully!";
Log.i(TAG, success);
for (DetectedObject detectedObject : results) {
Rect boundingBox = detectedObject.getBoundingBox();
Integer trackingId = detectedObject.getTrackingId();
for (DetectedObject.Label label : detectedObject.getLabels()) {
String text = label.getText();
int index = label.getIndex();
float confidence = label.getConfidence();
Log.i(TAG, "Object detected: " + text + "; "
+ "Confidence: " + confidence);
}
}
}
});
}
Essentially, once I run the app, logcat just keeps logging these two lines on repeat. I know it means the ImageAnalyzer is continuously trying to analyze the image input, but for some reason the LocalModel just cannot process the input
2021-01-21 22:02:24.020 9328-9328/com.example.camerax I/MainActivity: Obtained ImageProxy object
2021-01-21 22:02:24.036 9328-9328/com.example.camerax I/MainActivity: Failed to process. Error: Failed to initialize detector.
I have only just started to work with Android, especially ML in Android, so any sort of help would be appreciated!
I managed to fix my issue before anyone answered, but in case anyone who just started to learn Android like me I'll leave my solution here.
Basically, remember to create an asset folder in the /src/main directory rather than the /src/androidTest directory :P
Once I did that, the model loaded correctly and now I just have to figure out how to display the results in my application.
// Do NOT compress tflite model files (need to call out to developers!)
aaptOptions {
noCompress "tflite"
}
add this line in build gradle for app under android tag
I use mapbox for android (java), when it tries to access the device location it gives me an error and closes the application. This problem does not occur when I try to use the app by simulating it.
It seems that this code doesn't work.
private void enableLocationComponent(#NonNull Style loadedMapStyle) {
if (PermissionsManager.areLocationPermissionsGranted(this)) {
locationComponent = mapboxMap.getLocationComponent();
LocationComponentActivationOptions locationComponentActivationOptions =
LocationComponentActivationOptions.builder(this, loadedMapStyle)
.useDefaultLocationEngine(false)
.build();
locationComponent.activateLocationComponent(locationComponentActivationOptions);
locationComponent.setLocationComponentEnabled(true);
locationComponent.setCameraMode(CameraMode.TRACKING);
locationComponent.setRenderMode(RenderMode.COMPASS);
initLocationEngine();
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}
What is the crash message in the logcat?
Are you passing a fully loaded map style through to enableLocationComponent()?
You might have already seen them, but fyi about https://docs.mapbox.com/help/tutorials/android-location-listening/ and https://docs.mapbox.com/android/maps/examples/#device-location
I have a project where in I have a source and a destination, but in between there can be any number of stop points. I need to display a route from source to destination covering all the stop points.
I started finding route between two points and is working fine. But the moment I add a extra point in between it gives a error saying
Location "Location 3" in "Stops" is unlocated. Location "Location 2" in "Stops" is on a soft-restricted network element. Cannot preserve last location "Location 3" in "Stops" because it is invalid. "Stops" does not contain valid input for any route.
I tried googling for this error but couldn't find any results.
I thought location 3 is not a valid location but when I try to find a route between source and location 3 it works fine. I am not sure what I am doing wrong. Below I have attached function which gives route result.
private void QueryDirections(final ArrayList<Point> stopPoints) {
dialog = ProgressDialog.show(RoutingSample.this, "Routing Sample",
"Calculating route...", true);
Thread t = new Thread() {
#Override
public void run() {
try {
// Start building up routing parameters
NAFeaturesAsFeature stops = new NAFeaturesAsFeature();
ArrayList<StopGraphic> stopGraphics = new ArrayList<StopGraphic>();
for(Point pt : stopPoints){
stopGraphics.add(new StopGraphic(pt));
}
Graphic[] stopGraphicsPrim = new Graphic[stopGraphics.size()];
stopGraphicsPrim = stopGraphics.toArray(stopGraphicsPrim);
stops.setSpatialReference(wm);
stops.setFeatures(stopGraphicsPrim);
stops.setCompressedRequest(true);
RouteParameters rp = mRouteTask
.retrieveDefaultRouteTaskParameters();
rp.setStops(stops);
rp.setReturnDirections(true);
rp.setFindBestSequence(true);
rp.setPreserveFirstStop(true);
rp.setOutSpatialReference(wm);
// I get error here. When routeTast.solve is called. Please help
mResults = mRouteTask.solve(rp);
mHandler.post(mUpdateResults);
} catch (Exception e) {
mException = e;
e.printStackTrace();
dialog.dismiss();
mHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),"directions cannot be found ",Toast.LENGTH_SHORT).show();
}
});
}
}
};
// Start the operation
t.start();
}
I was referring to a similar post Multiple Routing
But I wasn't able to get any solution from this. Please help. Thank You in advance.
I'm using the example code on this page (http://altbeacon.github.io/android-beacon-library/samples.html) in the Starting an App in the Background section and I've got a working app.
It detects whenever a beacon is in range even on background.
The problem is I need to know which beacon is it (UUID, Major, Minor) to then match it against my local database and throw a notification with the app still on background.
The didEnterRegion(Region region) function only has a matchesBeacon method, and I've tried doing the following to identify which of the beacons is being seen but it's throwing a NullPointerException:
public class SightSeeing extends Activity implements BootstrapNotifier, RangeNotifier {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Region region = new Region("sightRegion", null, null, null);
regionBootstrap = new RegionBootstrap(this, region);
BeaconManager.getInstanceForApplication(this).getBeaconParsers().add(
new BeaconParser(). setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")
);
BeaconManager.getInstanceForApplication(this).setRangeNotifier(this);
}
#Override
public void didEnterRegion(Region region) {
regionBootstrap.disable();
BeaconManager.getInstanceForApplication(this).setRangeNotifier(this);
try {
BeaconManager.getInstanceForApplication(this).startRangingBeaconsInRegion(region);
}
catch (RemoteException e) {
Log.e(TAG, "Can't start ranging");
}
}
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
Iterator<Beacon> beaconIterator = beacons.iterator();
while (beaconIterator.hasNext()) {
Beacon beacon = beaconIterator.next();
//check if beacon exists in our DB and throw notification
}
}
}
Am I missing something obvious or isn't this possible with this library?
EDIT:
I've updated the code sample to give you guys a broader idea and I've tried implementing the suggestion by FOliveira without any success.
EDIT2:
Updated code to reflect the davidgyoung's suggestion. Still no luck. I have a Log.d() right on the first line of the didRangeBeaconsInRegion() function and it isn't being called.
I've tried adding BeaconManager.getInstanceForApplication(this).setRangeNotifier(this); before the try/catch block and the result is the same.
Did I implement the suggestion wrong or is there any other way to get this working?
If you want the app to launch itself on beacon detection, then the RegionBootstrap is the easiest way to go. In order to combine this with Ranging needed to detect individual beacons, then add code in your didEnterRegion method like this:
try {
BeaconManager.getInstanceForApplication(this).startRangingBeaconsInRegion(region);
}
catch (RemoteException e) {
Log.e(TAG, "Can't start ranging");
}
Then implement a ranging callback like you have.
You also need to remove the code below, which is probably what is causing your NullPointerException, because the :
for(int i=0; i< beaconsList.size(); i++) {
Beacon b = new Beacon.Builder()
.setId1(beaconsList.get(i).get("uuid"))
.setId2(beaconsList.get(i).get("major"))
.setId3(beaconsList.get(i).get("minor"))
.build();
if(region.matchesBeacon(b)) {
//get info from DB and throw notification
}
}
EDIT: I have updated the library's reference application to show how this can be done successfully. See here: https://github.com/AltBeacon/android-beacon-library-reference/blob/master/src/org/altbeacon/beaconreference/BeaconReferenceApplication.java
you can implement RangeNotifier interface and you can access all the beacon information captured in the public void didRangeBeaconsInRegion(Collection<Beacon> Beacons, Region region) method of that interface. Hope i got the question right
I am using Google maps for my application using GWT technologies, the thing is am getting markers in map without any exception or warning in Development mode. But when when I run it in production mode am getting uncaught (TypeError):exception: cannot call method 'Id' of null and when I click Ok button map loads without marker. Can any one help how to solve(track) this exception.
final LatLng mLatLng = LatLng.create(24.675, 46.708);
myOptions = MapOptions.create();
myOptions.setZoom(9);
myOptions.setCenter(mLatLng);
myOptions.setMapTypeId(MapTypeId.ROADMAP);
myOptions.setMapTypeControl(true);
Timer load = new Timer() {
#Override
public void run() {
fullTrackingMap = GoogleMap.create(mapVp.getElement(),myOptions);
/* Service call here */
filterMap(hashMap); // hashmap<String, Marker>
}
};
load.schedule(1000);
private void filterMap(SortedMap<String, Marker> hashMap) {
if (hashMap.get(e.getKey()) != null) {
Marker marker = hashMap.get(e.getKey());
if (e.getValue().equalsIgnoreCase("false")) {
marker.setMap((GoogleMap) null);
} else {
marker.setMap(fullTrackingMap);
}
markers.add(marker);
}
}
I am getting values for hashmap from server-side not in code snippet above.
Check the initialization of objects. the issues in production mode is mainly because of object initialization.