package org.droidplanner.services.android.impl.core.gcs.roi; import android.os.Handler; import org.droidplanner.services.android.impl.core.MAVLink.command.doCmd.MavLinkDoCmds; import org.droidplanner.services.android.impl.core.drone.autopilot.MavLinkDrone; import org.droidplanner.services.android.impl.core.gcs.location.Location; import org.droidplanner.services.android.impl.core.gcs.location.Location.LocationReceiver; import org.droidplanner.services.android.impl.core.helpers.geoTools.GeoTools; import com.o3dr.services.android.lib.coordinate.LatLong; import com.o3dr.services.android.lib.coordinate.LatLongAlt; import java.util.concurrent.atomic.AtomicBoolean; /** * Uses location data from Android's FusedLocation LocationManager at 1Hz and * calculates new points at 10Hz based on Last Location and Last Velocity. */ public class ROIEstimator implements LocationReceiver { private static final int TIMEOUT = 100; protected Location realLocation; protected long timeOfLastLocation; protected final MavLinkDrone drone; protected Handler watchdog; protected Runnable watchdogCallback = new Runnable() { @Override public void run() { updateROI(); } }; protected final AtomicBoolean isFollowEnabled = new AtomicBoolean(false); public ROIEstimator(MavLinkDrone drone, Handler handler) { this.watchdog = handler; this.drone = drone; } public void enableFollow() { MavLinkDoCmds.resetROI(drone, null); isFollowEnabled.set(true); } public void disableFollow() { if (isFollowEnabled.compareAndSet(true, false)) { realLocation = null; MavLinkDoCmds.resetROI(drone, null); disableWatchdog(); } } @Override public final void onLocationUpdate(Location location) { if (!isFollowEnabled.get()) return; realLocation = location; timeOfLastLocation = System.currentTimeMillis(); disableWatchdog(); updateROI(); } @Override public void onLocationUnavailable() { disableWatchdog(); } protected void disableWatchdog() { watchdog.removeCallbacks(watchdogCallback); } protected void updateROI() { if (realLocation == null) { return; } LatLong gcsCoord = realLocation.getCoord(); double bearing = realLocation.getBearing(); double distanceTraveledSinceLastPoint = realLocation.getSpeed() * (System.currentTimeMillis() - timeOfLastLocation) / 1000f; LatLong goCoord = GeoTools.newCoordFromBearingAndDistance(gcsCoord, bearing, distanceTraveledSinceLastPoint); sendUpdateROI(goCoord); if (realLocation.getSpeed() > 0) watchdog.postDelayed(watchdogCallback, getUpdatePeriod()); } protected void sendUpdateROI(LatLong goCoord) { MavLinkDoCmds.setROI(drone, new LatLongAlt(goCoord.getLatitude(), goCoord.getLongitude(), (0.0)), null); } public boolean isFollowEnabled() { return isFollowEnabled.get(); } protected long getUpdatePeriod(){ return TIMEOUT; } }