package org.droidplanner.services.android.impl.core.mission.waypoints; import com.MAVLink.common.msg_mission_item; import com.MAVLink.enums.MAV_CMD; import com.o3dr.services.android.lib.coordinate.LatLong; import com.o3dr.services.android.lib.coordinate.LatLongAlt; import org.droidplanner.services.android.impl.core.helpers.geoTools.GeoTools; import org.droidplanner.services.android.impl.core.mission.MissionImpl; import org.droidplanner.services.android.impl.core.mission.MissionItemImpl; import org.droidplanner.services.android.impl.core.mission.MissionItemType; import org.droidplanner.services.android.impl.core.mission.survey.SurveyImpl; import org.droidplanner.services.android.impl.core.polygon.Polygon; import org.droidplanner.services.android.impl.core.survey.CameraInfo; import org.droidplanner.services.android.impl.core.survey.SurveyData; import org.droidplanner.services.android.impl.core.survey.grid.GridBuilder; import java.util.ArrayList; import java.util.List; public class StructureScannerImpl extends SpatialCoordItem { private double radius = 10.0; private double heightStep = 5; private int numberOfSteps = 2; private boolean crossHatch = false; SurveyData survey = new SurveyData(); public StructureScannerImpl(MissionImpl missionImpl, LatLongAlt coord) { super(missionImpl, coord); } public StructureScannerImpl(MissionItemImpl item) { super(item); } @Override public List<msg_mission_item> packMissionItem() { List<msg_mission_item> list = new ArrayList<msg_mission_item>(); packROI(list); packCircles(list); if (crossHatch) { packHatch(list); } return list; } private void packROI(List<msg_mission_item> list) { RegionOfInterestImpl roi = new RegionOfInterestImpl(missionImpl, new LatLongAlt(coordinate, (0.0))); list.addAll(roi.packMissionItem()); } private void packCircles(List<msg_mission_item> list) { double altitude = coordinate.getAltitude(); for (int iSteps = 0; iSteps < numberOfSteps; iSteps++) { CircleImpl circleImpl = new CircleImpl(missionImpl, new LatLongAlt(coordinate, altitude)); circleImpl.setRadius(radius); list.addAll(circleImpl.packMissionItem()); altitude+= heightStep; } } private void packHatch(List<msg_mission_item> list) { Polygon polygon = new Polygon(); for (double angle = 0; angle <= 360; angle += 10) { polygon.addPoint(GeoTools.newCoordFromBearingAndDistance(coordinate, angle, radius)); } LatLong corner = GeoTools.newCoordFromBearingAndDistance(coordinate, -45, radius * 2); survey.setAltitude(getTopHeight()); try { survey.update(0.0, survey.getAltitude(), survey.getOverlap(), survey.getSidelap(), survey.getLockOrientation()); GridBuilder grid = new GridBuilder(polygon, survey, corner); for (LatLong point : grid.generate(false).gridPoints) { list.add(SurveyImpl.packSurveyPoint(point, getTopHeight())); } survey.update(90.0, survey.getAltitude(), survey.getOverlap(), survey.getSidelap(), survey.getLockOrientation()); GridBuilder grid2 = new GridBuilder(polygon, survey, corner); for (LatLong point : grid2.generate(false).gridPoints) { list.add(SurveyImpl.packSurveyPoint(point, getTopHeight())); } } catch (Exception e) { // Should never fail, since it has good polygons } } public List<LatLong> getPath() { List<LatLong> path = new ArrayList<LatLong>(); for (msg_mission_item msg_mission_item : packMissionItem()) { if (msg_mission_item.command == MAV_CMD.MAV_CMD_NAV_WAYPOINT) { path.add(new LatLong(msg_mission_item.x, msg_mission_item.y)); } if (msg_mission_item.command == MAV_CMD.MAV_CMD_NAV_LOITER_TURNS) { for (double angle = 0; angle <= 360; angle += 12) { path.add(GeoTools.newCoordFromBearingAndDistance(coordinate, angle, radius)); } } } return path; } @Override public void unpackMAVMessage(msg_mission_item mavMsg) { } @Override public MissionItemType getType() { return MissionItemType.CYLINDRICAL_SURVEY; } private double getTopHeight() { return (coordinate.getAltitude() + (numberOfSteps - 1) * heightStep); } public double getEndAltitude() { return heightStep; } public int getNumberOfSteps() { return numberOfSteps; } public double getRadius() { return radius; } public LatLong getCenter() { return coordinate; } public void setRadius(int newValue) { radius = newValue; } public void enableCrossHatch(boolean isEnabled) { crossHatch = isEnabled; } public boolean isCrossHatchEnabled() { return crossHatch; } public void setAltitudeStep(int newValue) { heightStep = (newValue); } public void setNumberOfSteps(int newValue) { numberOfSteps = newValue; } public void setCamera(CameraInfo cameraInfo) { survey.setCameraInfo(cameraInfo); } public String getCamera() { return survey.getCameraName(); } public SurveyData getSurveyData() { return survey; } }