2011-09-28 21:51:12 -03:00
|
|
|
/*
|
|
|
|
* AP_MavlinkCommand.cpp
|
|
|
|
*
|
|
|
|
* Created on: Apr 30, 2011
|
|
|
|
* Author: jgoppert
|
|
|
|
*/
|
|
|
|
|
2011-10-26 15:59:40 -03:00
|
|
|
#include "../FastSerial/FastSerial.h"
|
2011-09-28 21:51:12 -03:00
|
|
|
#include "AP_MavlinkCommand.h"
|
|
|
|
|
|
|
|
namespace apo {
|
|
|
|
|
|
|
|
AP_MavlinkCommand::AP_MavlinkCommand(const AP_MavlinkCommand & v) :
|
2011-10-26 13:31:11 -03:00
|
|
|
_data(v._data), _seq(v._seq) {
|
|
|
|
//if (FastSerial::getInitialized(0)) Serial.println("copy ctor");
|
2011-09-28 21:51:12 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
AP_MavlinkCommand::AP_MavlinkCommand(uint16_t index, bool doLoad) :
|
2011-10-26 13:31:11 -03:00
|
|
|
_data(k_commands + index), _seq(index) {
|
|
|
|
|
|
|
|
if (FastSerial::getInitialized(0)) {
|
|
|
|
Serial.println("index ctor");
|
|
|
|
Serial.println("++");
|
|
|
|
Serial.print("index: ");
|
|
|
|
Serial.println(index);
|
|
|
|
Serial.print("key: ");
|
|
|
|
Serial.println(k_commands + index);
|
|
|
|
Serial.println("++");
|
|
|
|
}
|
|
|
|
|
|
|
|
// default values for structure
|
|
|
|
_data.get().command = MAV_CMD_NAV_WAYPOINT;
|
|
|
|
_data.get().autocontinue = true;
|
|
|
|
_data.get().frame = MAV_FRAME_GLOBAL;
|
|
|
|
_data.get().param1 = 0;
|
|
|
|
_data.get().param2 = 10; // radius of 10 meters
|
|
|
|
_data.get().param3 = 0;
|
|
|
|
_data.get().param4 = 0;
|
|
|
|
_data.get().x = 0;
|
|
|
|
_data.get().y = 0;
|
|
|
|
_data.get().z = 1000;
|
|
|
|
|
|
|
|
// This is a failsafe measure to stop trying to load a command if it can't load
|
|
|
|
if (doLoad && !load()) {
|
|
|
|
Serial.println("load failed, reverting to home waypoint");
|
|
|
|
_data = AP_MavlinkCommand::home._data;
|
|
|
|
_seq = AP_MavlinkCommand::home._seq;
|
|
|
|
}
|
2011-09-28 21:51:12 -03:00
|
|
|
}
|
|
|
|
|
2011-10-06 13:00:45 -03:00
|
|
|
AP_MavlinkCommand::AP_MavlinkCommand(const mavlink_waypoint_t & cmd) :
|
2011-10-26 13:31:11 -03:00
|
|
|
_data(k_commands + cmd.seq), _seq(cmd.seq) {
|
|
|
|
setCommand(MAV_CMD(cmd.command));
|
|
|
|
setAutocontinue(cmd.autocontinue);
|
|
|
|
setFrame(MAV_FRAME(cmd.frame));
|
|
|
|
setParam1(cmd.param1);
|
|
|
|
setParam2(cmd.param2);
|
|
|
|
setParam3(cmd.param3);
|
|
|
|
setParam4(cmd.param4);
|
|
|
|
setX(cmd.x);
|
|
|
|
setY(cmd.y);
|
|
|
|
setZ(cmd.z);
|
|
|
|
save();
|
|
|
|
|
2011-11-19 23:20:06 -04:00
|
|
|
// reload home if sent, home must be a global waypoint
|
|
|
|
if ( (cmd.seq == 0) && (cmd.frame == MAV_FRAME_GLOBAL)) home.load();
|
2011-10-26 13:31:11 -03:00
|
|
|
|
|
|
|
Serial.println("============================================================");
|
|
|
|
Serial.println("storing new command from mavlink_waypoint_t");
|
|
|
|
Serial.print("key: ");
|
|
|
|
Serial.println(_data.key(),DEC);
|
|
|
|
Serial.print("number: ");
|
|
|
|
Serial.println(cmd.seq,DEC);
|
|
|
|
Serial.print("command: ");
|
|
|
|
Serial.println(getCommand());
|
|
|
|
Serial.print("autocontinue: ");
|
|
|
|
Serial.println(getAutocontinue(),DEC);
|
|
|
|
Serial.print("frame: ");
|
|
|
|
Serial.println(getFrame(),DEC);
|
|
|
|
Serial.print("1000*param1: ");
|
|
|
|
Serial.println(int(1000*getParam1()),DEC);
|
|
|
|
Serial.print("1000*param2: ");
|
|
|
|
Serial.println(int(1000*getParam2()),DEC);
|
|
|
|
Serial.print("1000*param3: ");
|
|
|
|
Serial.println(int(1000*getParam3()),DEC);
|
|
|
|
Serial.print("1000*param4: ");
|
|
|
|
Serial.println(int(1000*getParam4()),DEC);
|
|
|
|
Serial.print("1000*x0: ");
|
|
|
|
Serial.println(int(1000*cmd.x),DEC);
|
|
|
|
Serial.print("1000*y0: ");
|
|
|
|
Serial.println(int(1000*cmd.y),DEC);
|
|
|
|
Serial.print("1000*z0: ");
|
|
|
|
Serial.println(int(1000*cmd.z),DEC);
|
|
|
|
Serial.print("1000*x: ");
|
|
|
|
Serial.println(int(1000*getX()),DEC);
|
|
|
|
Serial.print("1000*y: ");
|
|
|
|
Serial.println(int(1000*getY()),DEC);
|
|
|
|
Serial.print("1000*z: ");
|
|
|
|
Serial.println(int(1000*getZ()),DEC);
|
|
|
|
|
|
|
|
load();
|
|
|
|
|
|
|
|
Serial.print("1000*x1: ");
|
|
|
|
Serial.println(int(1000*getX()),DEC);
|
|
|
|
Serial.print("1000*y1: ");
|
|
|
|
Serial.println(int(1000*getY()),DEC);
|
|
|
|
Serial.print("1000*z1: ");
|
|
|
|
Serial.println(int(1000*getZ()),DEC);
|
|
|
|
Serial.println("============================================================");
|
|
|
|
Serial.flush();
|
2011-09-28 21:51:12 -03:00
|
|
|
}
|
|
|
|
|
2011-10-06 13:00:45 -03:00
|
|
|
mavlink_waypoint_t AP_MavlinkCommand::convert(uint8_t current) const {
|
2011-10-26 13:31:11 -03:00
|
|
|
mavlink_waypoint_t mavCmd;
|
|
|
|
mavCmd.seq = getSeq();
|
|
|
|
mavCmd.command = getCommand();
|
|
|
|
mavCmd.frame = getFrame();
|
|
|
|
mavCmd.param1 = getParam1();
|
|
|
|
mavCmd.param2 = getParam2();
|
|
|
|
mavCmd.param3 = getParam3();
|
|
|
|
mavCmd.param4 = getParam4();
|
|
|
|
mavCmd.x = getX();
|
|
|
|
mavCmd.y = getY();
|
|
|
|
mavCmd.z = getZ();
|
|
|
|
mavCmd.autocontinue = getAutocontinue();
|
|
|
|
mavCmd.current = (getSeq() == current);
|
|
|
|
mavCmd.target_component = mavlink_system.compid;
|
|
|
|
mavCmd.target_system = mavlink_system.sysid;
|
|
|
|
return mavCmd;
|
2011-09-28 21:51:12 -03:00
|
|
|
}
|
|
|
|
|
2011-10-06 13:00:45 -03:00
|
|
|
float AP_MavlinkCommand::bearingTo(const AP_MavlinkCommand & next) const {
|
2011-10-26 13:31:11 -03:00
|
|
|
float deltaLon = next.getLon() - getLon();
|
|
|
|
/*
|
|
|
|
Serial.print("Lon: "); Serial.println(getLon());
|
|
|
|
Serial.print("nextLon: "); Serial.println(next.getLon());
|
|
|
|
Serial.print("deltaLonDeg * 1e7: "); Serial.println(deltaLon*rad2DegInt);
|
|
|
|
*/
|
|
|
|
float bearing = atan2(
|
|
|
|
sin(deltaLon) * cos(next.getLat()),
|
|
|
|
cos(getLat()) * sin(next.getLat()) - sin(getLat()) * cos(
|
|
|
|
next.getLat()) * cos(deltaLon));
|
|
|
|
return bearing;
|
2011-09-28 21:51:12 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
float AP_MavlinkCommand::bearingTo(int32_t latDegInt, int32_t lonDegInt) const {
|
2011-10-26 13:31:11 -03:00
|
|
|
// have to be careful to maintain the precision of the gps coordinate
|
|
|
|
float deltaLon = (lonDegInt - getLon_degInt()) * degInt2Rad;
|
|
|
|
float nextLat = latDegInt * degInt2Rad;
|
|
|
|
float bearing = atan2(
|
|
|
|
sin(deltaLon) * cos(nextLat),
|
|
|
|
cos(getLat()) * sin(nextLat) - sin(getLat()) * cos(nextLat)
|
|
|
|
* cos(deltaLon));
|
|
|
|
if (bearing < 0)
|
|
|
|
bearing += 2 * M_PI;
|
|
|
|
return bearing;
|
2011-09-28 21:51:12 -03:00
|
|
|
}
|
|
|
|
|
2011-10-06 13:00:45 -03:00
|
|
|
float AP_MavlinkCommand::distanceTo(const AP_MavlinkCommand & next) const {
|
2011-10-26 13:31:11 -03:00
|
|
|
float sinDeltaLat2 = sin((getLat() - next.getLat()) / 2);
|
|
|
|
float sinDeltaLon2 = sin((getLon() - next.getLon()) / 2);
|
|
|
|
float a = sinDeltaLat2 * sinDeltaLat2 + cos(getLat()) * cos(
|
|
|
|
next.getLat()) * sinDeltaLon2 * sinDeltaLon2;
|
|
|
|
float c = 2 * atan2(sqrt(a), sqrt(1 - a));
|
|
|
|
return rEarth * c;
|
2011-09-28 21:51:12 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
float AP_MavlinkCommand::distanceTo(int32_t lat_degInt, int32_t lon_degInt) const {
|
2011-10-26 13:31:11 -03:00
|
|
|
float sinDeltaLat2 = sin(
|
|
|
|
(lat_degInt - getLat_degInt()) * degInt2Rad / 2);
|
|
|
|
float sinDeltaLon2 = sin(
|
|
|
|
(lon_degInt - getLon_degInt()) * degInt2Rad / 2);
|
|
|
|
float a = sinDeltaLat2 * sinDeltaLat2 + cos(getLat()) * cos(
|
|
|
|
lat_degInt * degInt2Rad) * sinDeltaLon2 * sinDeltaLon2;
|
|
|
|
float c = 2 * atan2(sqrt(a), sqrt(1 - a));
|
|
|
|
/*
|
|
|
|
Serial.print("wp lat_degInt: "); Serial.println(getLat_degInt());
|
|
|
|
Serial.print("wp lon_degInt: "); Serial.println(getLon_degInt());
|
|
|
|
Serial.print("lat_degInt: "); Serial.println(lat_degInt);
|
|
|
|
Serial.print("lon_degInt: "); Serial.println(lon_degInt);
|
|
|
|
Serial.print("sinDeltaLat2: "); Serial.println(sinDeltaLat2);
|
|
|
|
Serial.print("sinDeltaLon2: "); Serial.println(sinDeltaLon2);
|
|
|
|
*/
|
|
|
|
return rEarth * c;
|
2011-09-28 21:51:12 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
//calculates cross track of a current location
|
2011-10-06 13:00:45 -03:00
|
|
|
float AP_MavlinkCommand::crossTrack(const AP_MavlinkCommand & previous,
|
2011-10-26 13:31:11 -03:00
|
|
|
int32_t lat_degInt, int32_t lon_degInt) const {
|
|
|
|
float d = previous.distanceTo(lat_degInt, lon_degInt);
|
|
|
|
float bCurrent = previous.bearingTo(lat_degInt, lon_degInt);
|
|
|
|
float bNext = previous.bearingTo(*this);
|
|
|
|
return asin(sin(d / rEarth) * sin(bCurrent - bNext)) * rEarth;
|
2011-09-28 21:51:12 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
// calculates along track distance of a current location
|
2011-12-04 02:25:14 -04:00
|
|
|
float AP_MavlinkCommand::alongTrack(const AP_MavlinkCommand & previous,
|
2011-10-26 13:31:11 -03:00
|
|
|
int32_t lat_degInt, int32_t lon_degInt) const {
|
2011-12-04 02:25:14 -04:00
|
|
|
float dXt = crossTrack(previous,lat_degInt,lon_degInt);
|
|
|
|
float d = previous.distanceTo(getLat_degInt(),getLon_degInt());
|
2011-12-04 02:36:53 -04:00
|
|
|
float bCurrent = previous.bearingTo(lat_degInt, lon_degInt);
|
|
|
|
float bNext = previous.bearingTo(*this);
|
|
|
|
float y = acos(cos(d/rEarth)/cos(dXt/rEarth))*rEarth;
|
|
|
|
if (cos(bCurrent-bNext) < 0) y = -y;
|
|
|
|
return y;
|
2011-09-28 21:51:12 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AP_MavlinkCommand AP_MavlinkCommand::home = AP_MavlinkCommand(0,false);
|
|
|
|
|
2011-10-26 15:59:40 -03:00
|
|
|
} // namespace apo
|
|
|
|
// vim:ts=4:sw=4:expandtab
|