I implemented a GCS and it works fine with Navio2 for sending waypoints to drone and executing an autonomous missions in AUTO mode.
You can see a demo in this video
However, I found a problem with sending one waypoint to visit in GUIDED mode. In this case, the drone LAND instead of going to the waypoint. I repeated this experiments several times, but the same thing always happen. When I execute the same waypoint navigation on SITL, it works perfectly fine.
Here is the illustration of the problem in GUIDED mode
For the code use to send the GUIDED waypoint mission, it is the following in Java, which uses exactly the same parameters as in Droidplanner:
public static void gotoWaypoint(Drone drone, Location location) {
msg_mission_item msg = new msg_mission_item();
msg.seq = 0;
msg.current = 2; // TODO use guided mode enum
msg.frame = MAV_FRAME.MAV_FRAME_GLOBAL;
msg.command = MAV_CMD.MAV_CMD_NAV_WAYPOINT; //
msg.param1 = 0; // TODO use correct parameter
msg.param2 = 0; // TODO use correct parameter
msg.param3 = 0; // TODO use correct parameter
msg.param4 = 0; // TODO use correct parameter
msg.x = (float) location.getLatitude();
msg.y = (float) location.getLongitude();
msg.z = (float) location.getAltitude();
msg.autocontinue = 1; // TODO use correct parameter
msg.target_system = drone.getSystemID();
msg.target_component = 1;
try {
//code used for sending the mission for the drone
…
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
I solved the problem of the GUIDED mode.
It was a bug in the message frame, which was set to Global, which means altitude is going with respect to global GPS altitude, however, it was meant the relative altitude. See the code below:
public static void gotoWaypoint(Drone drone, Location location) {
msg_mission_item msg = new msg_mission_item();
msg.seq = 0;
msg.current = 2; // TODO use guided mode enum msg.frame = MAV_FRAME.MAV_FRAME_GLOBAL;
msg.command = MAV_CMD.MAV_CMD_NAV_WAYPOINT; //
msg.param1 = 0; // TODO use correct parameter
msg.param2 = 0; // TODO use correct parameter
msg.param3 = 0; // TODO use correct parameter
msg.param4 = 0; // TODO use correct parameter
msg.x = (float) location.getLatitude();
msg.y = (float) location.getLongitude();
msg.z = (float) location.getAltitude();
msg.autocontinue = 1; // TODO use correct parameter
msg.target_system = drone.getSystemID();
msg.target_component = 1;
try {
//code used for sending the mission for the drone
…
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
I just had to change the frame to
msg.frame = MAV_FRAME.MAV_FRAME_RELATIVE;
And now it is working fine.
For example, in my area, the GPS altitude is 600 m.
When you sent a altitude of 10 in the global frame, the copter think it needs to go down for 590 meters, that is why it was going to ground.
When we specify the frame as relative, then it will take the relative altitude found by the Baro.