package org.droidplanner.services.android.impl.core.mission.survey;
import com.MAVLink.common.msg_mission_item;
import com.MAVLink.enums.MAV_CMD;
import com.MAVLink.enums.MAV_FRAME;
import com.o3dr.services.android.lib.coordinate.LatLong;
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.commands.CameraTriggerImpl;
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.Grid;
import org.droidplanner.services.android.impl.core.survey.grid.GridBuilder;
import java.util.ArrayList;
import java.util.List;
public class SurveyImpl extends MissionItemImpl {
public Polygon polygon = new Polygon();
public SurveyData surveyData = new SurveyData();
public Grid grid;
private boolean startCameraBeforeFirstWaypoint;
public SurveyImpl(MissionImpl missionImpl, List<LatLong> points) {
super(missionImpl);
polygon.addPoints(points);
}
public void update(double angle, double altitude, double overlap, double sidelap, boolean lockOrientation) {
surveyData.update(angle, altitude, overlap, sidelap, lockOrientation);
}
public boolean isStartCameraBeforeFirstWaypoint() {
return startCameraBeforeFirstWaypoint;
}
public void setStartCameraBeforeFirstWaypoint(boolean startCameraBeforeFirstWaypoint) {
this.startCameraBeforeFirstWaypoint = startCameraBeforeFirstWaypoint;
}
public void setCameraInfo(CameraInfo camera) {
surveyData.setCameraInfo(camera);
}
public void build() throws Exception {
// TODO find better point than (0,0) to reference the grid
grid = null;
GridBuilder gridBuilder = new GridBuilder(polygon, surveyData, new LatLong(0, 0));
polygon.checkIfValid();
grid = gridBuilder.generate(true);
}
@Override
public List<msg_mission_item> packMissionItem() {
try {
List<msg_mission_item> list = new ArrayList<msg_mission_item>();
build();
packSurveyPoints(list);
return list;
} catch (Exception e) {
return new ArrayList<msg_mission_item>();
}
}
private void packSurveyPoints(List<msg_mission_item> list) {
//Generate the camera trigger
CameraTriggerImpl camTrigger = new CameraTriggerImpl(missionImpl, surveyData.getLongitudinalPictureDistance());
//Add it if the user wants it to start before the first waypoint.
if(startCameraBeforeFirstWaypoint){
list.addAll(camTrigger.packMissionItem());
}
final double altitude = surveyData.getAltitude();
//Add the camera trigger after the first waypoint if it wasn't added before.
boolean addToFirst = !startCameraBeforeFirstWaypoint;
for (LatLong point : grid.gridPoints) {
msg_mission_item mavMsg = getSurveyPoint(point, altitude);
list.add(mavMsg);
if(surveyData.getLockOrientation()) {
msg_mission_item yawMsg = getYawCondition(surveyData.getAngle());
list.add(yawMsg);
}
if(addToFirst){
list.addAll(camTrigger.packMissionItem());
addToFirst = false;
}
}
list.addAll((new CameraTriggerImpl(missionImpl, (0.0)).packMissionItem()));
}
protected msg_mission_item getSurveyPoint(LatLong point, double altitude){
return packSurveyPoint(point, altitude);
}
public static msg_mission_item packSurveyPoint(LatLong point, double altitude) {
msg_mission_item mavMsg = new msg_mission_item();
mavMsg.autocontinue = 1;
mavMsg.frame = MAV_FRAME.MAV_FRAME_GLOBAL_RELATIVE_ALT;
mavMsg.command = MAV_CMD.MAV_CMD_NAV_WAYPOINT;
mavMsg.x = (float) point.getLatitude();
mavMsg.y = (float) point.getLongitude();
mavMsg.z = (float) altitude;
mavMsg.param1 = 0f;
mavMsg.param2 = 0f;
mavMsg.param3 = 0f;
mavMsg.param4 = 0f;
return mavMsg;
}
private msg_mission_item getYawCondition(double angle){
msg_mission_item mavMsg = new msg_mission_item();
mavMsg.autocontinue = 1;
mavMsg.frame = MAV_FRAME.MAV_FRAME_LOCAL_ENU;
mavMsg.command = MAV_CMD.MAV_CMD_CONDITION_YAW;
mavMsg.x = 0f;
mavMsg.y = 0f;
mavMsg.z = 0f;
mavMsg.param1 = (float)angle;
//yaw craft a 30 degrees per second (value is relatively insignificant since it only applies when approaching first waypoint of mission)
mavMsg.param2 = 30;
mavMsg.param3 = 0;
mavMsg.param4 = 0;
return mavMsg;
}
@Override
public void unpackMAVMessage(msg_mission_item mavMsg) {
}
@Override
public MissionItemType getType() {
return MissionItemType.SURVEY;
}
}