00001
00002
00003
00004 #ifndef MSP_MSG_HPP
00005 #define MSP_MSG_HPP
00006
00007 #include <string>
00008 #include <array>
00009 #include <sstream>
00010 #include <set>
00011 #include <climits>
00012 #include <cassert>
00013
00014 #include "types.hpp"
00015
00016 #include "deserialise.hpp"
00017
00018 namespace msp {
00019 namespace msg {
00020
00021 const static uint N_SERVO = 8;
00022 const static uint N_MOTOR = 8;
00023
00024 const static uint BOARD_IDENTIFIER_LENGTH = 4;
00025
00026 const static uint BUILD_DATE_LENGTH = 11;
00027 const static uint BUILD_TIME_LENGTH = 8;
00028 const static uint GIT_SHORT_REVISION_LENGTH = 7;
00029
00030 enum class MultiType : uint8_t {
00031 TRI = 1,
00032 QUADP,
00033 QUADX,
00034 BI,
00035 GIMBAL,
00036 Y6,
00037 HEX6,
00038 FLYING_WING,
00039 Y4,
00040 HEX6X,
00041 OCTOX8,
00042 OCTOFLATP,
00043 OCTOFLATX,
00044 AIRPLANE,
00045 HELI_120_CCPM,
00046 HELI_90_DEG,
00047 VTAIL4,
00048 HEX6H,
00049 DUALCOPTER = 20,
00050 SINGLECOPTER,
00051 };
00052
00053 enum class Capability {
00054 BIND,
00055 DYNBAL,
00056 FLAP,
00057 NAVCAP,
00058 EXTAUX
00059 };
00060
00061 enum class Sensor {
00062 Accelerometer,
00063 Barometer,
00064 Magnetometer,
00065 GPS,
00066 Sonar
00067 };
00068
00069 const static uint NAUX = 4;
00070
00071 enum class SwitchPosition : uint {
00072 LOW = 0,
00073 MID = 1,
00074 HIGH = 2,
00075 };
00076
00077 static const std::vector<std::string> FEATURES = {
00078 "RX_PPM", "VBAT", "INFLIGHT_ACC_CAL", "RX_SERIAL", "MOTOR_STOP",
00079 "SERVO_TILT", "SOFTSERIAL", "GPS", "FAILSAFE",
00080 "SONAR", "TELEMETRY", "AMPERAGE_METER", "3D", "RX_PARALLEL_PWM",
00081 "RX_MSP", "RSSI_ADC", "LED_STRIP", "DISPLAY", "ONESHOT125",
00082 "BLACKBOX", "CHANNEL_FORWARDING", "TRANSPONDER", "OSD"
00083 };
00084
00087
00088
00089 struct ApiVersion : public Request {
00090 ID id() const { return ID::MSP_API_VERSION; }
00091
00092 uint protocol;
00093 uint major;
00094 uint minor;
00095
00096 void decode(const std::vector<uint8_t> &data) {
00097 protocol = data[0];
00098 major = data[1];
00099 minor = data[2];
00100 }
00101 };
00102
00103
00104 struct FcVariant : public Request {
00105 ID id() const { return ID::MSP_FC_VARIANT; }
00106
00107 std::string identifier;
00108
00109 void decode(const std::vector<uint8_t> &data) {
00110 identifier = std::string(data.begin(), data.end());
00111 }
00112 };
00113
00114
00115 struct FcVersion : public Request {
00116 ID id() const { return ID::MSP_FC_VERSION; }
00117
00118 uint major;
00119 uint minor;
00120 uint patch_level;
00121
00122 void decode(const std::vector<uint8_t> &data) {
00123 major = data[0];
00124 minor = data[1];
00125 patch_level = data[2];
00126 }
00127 };
00128
00129
00130 struct BoardInfo : public Request {
00131 ID id() const { return ID::MSP_BOARD_INFO; }
00132
00133 std::string identifier;
00134 uint16_t version;
00135 uint8_t type;
00136
00137 void decode(const std::vector<uint8_t> &data) {
00138 identifier = std::string(data.begin(), data.begin()+BOARD_IDENTIFIER_LENGTH);
00139 version = deserialise_uint16(data,BOARD_IDENTIFIER_LENGTH);
00140 type = data[BOARD_IDENTIFIER_LENGTH+2];
00141 }
00142 };
00143
00144
00145 struct BuildInfo : public Request {
00146 ID id() const { return ID::MSP_BUILD_INFO; }
00147
00148 std::string buildDate;
00149 std::string buildTime;
00150 std::string shortGitRevision;
00151
00152 void decode(const std::vector<uint8_t> &data) {
00153 buildDate = std::string((const char*)&data[0], BUILD_DATE_LENGTH);
00154 buildTime = std::string((const char*)&data[BUILD_DATE_LENGTH], BUILD_TIME_LENGTH);
00155 shortGitRevision = std::string((const char*)&data[BUILD_DATE_LENGTH+BUILD_TIME_LENGTH], GIT_SHORT_REVISION_LENGTH);
00156 }
00157 };
00158
00159
00160 struct Feature : public Request {
00161 ID id() const { return ID::MSP_FEATURE; }
00162
00163 std::set<std::string> features;
00164
00165 void decode(const std::vector<uint8_t> &data) {
00166 const uint32_t mask = deserialise_uint32(data,0);
00167 for(uint ifeat(0); ifeat<FEATURES.size(); ifeat++) {
00168 if(mask & (1<<ifeat))
00169 features.insert(FEATURES[ifeat]);
00170 }
00171 }
00172 };
00173
00174
00175 struct SetFeature : public Response {
00176 ID id() const { return ID::MSP_SET_FEATURE; }
00177
00178 std::set<std::string> features;
00179
00180 std::vector<uint8_t> encode() const {
00181 std::vector<uint8_t> data;
00182 uint32_t mask = 0;
00183 for(uint ifeat(0); ifeat<FEATURES.size(); ifeat++) {
00184 if(features.count(FEATURES[ifeat]))
00185 mask |= 1<<ifeat;
00186 }
00187 serialise_uint32(mask, data);
00188 return data;
00189 }
00190 };
00191
00192
00193 struct RxConfig : public Request {
00194 ID id() const { return ID::MSP_RX_CONFIG; }
00195
00196 uint8_t serialrx_provider;
00197 uint16_t maxcheck;
00198 uint16_t midrc;
00199 uint16_t mincheck;
00200 uint8_t spektrum_sat_bind;
00201 uint16_t rx_min_usec;
00202 uint16_t rx_max_usec;
00203
00204 void decode(const std::vector<uint8_t> &data) {
00205 serialrx_provider = data[0];
00206 maxcheck = deserialise_uint16(data, 1);
00207 midrc = deserialise_uint16(data, 3);
00208 mincheck = deserialise_uint16(data, 5);
00209 spektrum_sat_bind = data[7];
00210 rx_min_usec = deserialise_uint16(data, 8);
00211 rx_max_usec = deserialise_uint16(data, 10);
00212 }
00213 };
00214
00215
00216 struct RxMap : public Request {
00217 ID id() const { return ID::MSP_RX_MAP; }
00218
00219 std::vector<uint8_t> map;
00220
00221 void decode(const std::vector<uint8_t> &data) {
00222 map = data;
00223 }
00224 };
00225
00226
00227 struct SetRxMap : public Response {
00228 ID id() const { return ID::MSP_SET_RX_MAP; }
00229
00230 std::vector<uint8_t> map;
00231
00232 std::vector<uint8_t> encode() const {
00233 return map;
00234 }
00235 };
00236
00237
00238 struct Reboot : public Response {
00239 ID id() const { return ID::MSP_REBOOT; }
00240 std::vector<uint8_t> encode() const {
00241 return std::vector<uint8_t>();
00242 }
00243 };
00244
00245
00248
00249
00250 struct Ident : public Request {
00251 ID id() const { return ID::MSP_IDENT; }
00252
00253 uint version;
00254 MultiType type;
00255 uint msp_version;
00256 std::set<Capability> capabilities;
00257
00258 void decode(const std::vector<uint8_t> &data) {
00259 version = data[0];
00260
00261
00262 type = MultiType(data[1]);
00263
00264 msp_version = data[2];
00265
00266 const uint32_t capability = deserialise_uint32(data, 3);
00267 if(capability & (1 << 0))
00268 capabilities.insert(Capability::BIND);
00269 if(capability & (1 << 2))
00270 capabilities.insert(Capability::DYNBAL);
00271 if(capability & (1 << 3))
00272 capabilities.insert(Capability::FLAP);
00273 if(capability & (1 << 4))
00274 capabilities.insert(Capability::NAVCAP);
00275 if(capability & (1 << 5))
00276 capabilities.insert(Capability::EXTAUX);
00277 }
00278
00279 bool has(const Capability &cap) const { return capabilities.count(cap); }
00280
00281 bool hasBind() const { return has(Capability::BIND); }
00282
00283 bool hasDynBal() const { return has(Capability::DYNBAL); }
00284
00285 bool hasFlap() const { return has(Capability::FLAP); }
00286 };
00287
00288
00289 struct Status : public Request {
00290 ID id() const { return ID::MSP_STATUS; }
00291
00292 uint16_t time;
00293 uint16_t errors;
00294 std::set<Sensor> sensors;
00295 uint current_setting;
00296 std::set<uint> active_box_id;
00297
00298 void decode(const std::vector<uint8_t> &data) {
00299 time = deserialise_uint16(data, 0);
00300
00301 errors = deserialise_uint16(data, 2);
00302
00303
00304 sensors.clear();
00305 const uint16_t sensor = deserialise_uint16(data, 4);
00306 if(sensor & (1 << 0))
00307 sensors.insert(Sensor::Accelerometer);
00308 if(sensor & (1 << 1))
00309 sensors.insert(Sensor::Barometer);
00310 if(sensor & (1 << 2))
00311 sensors.insert(Sensor::Magnetometer);
00312 if(sensor & (1 << 3))
00313 sensors.insert(Sensor::GPS);
00314 if(sensor & (1 << 4))
00315 sensors.insert(Sensor::Sonar);
00316
00317
00318 active_box_id.clear();
00319 const uint32_t flag = deserialise_uint32(data, 6);
00320 for(uint ibox(0); ibox<sizeof(flag)*CHAR_BIT; ibox++) {
00321 if(flag & (1 << ibox))
00322 active_box_id.insert(ibox);
00323 }
00324
00325 current_setting = data[10];
00326 }
00327
00328 bool hasAccelerometer() const { return sensors.count(Sensor::Accelerometer); }
00329
00330 bool hasBarometer() const { return sensors.count(Sensor::Barometer); }
00331
00332 bool hasMagnetometer() const { return sensors.count(Sensor::Magnetometer); }
00333
00334 bool hasGPS() const { return sensors.count(Sensor::GPS); }
00335
00336 bool hasSonar() const { return sensors.count(Sensor::Sonar); }
00337 };
00338
00339
00340 struct ImuRaw : public Request {
00341 ID id() const { return ID::MSP_RAW_IMU; }
00342
00343 std::array<int16_t, 3> acc;
00344 std::array<int16_t, 3> gyro;
00345 std::array<int16_t, 3> magn;
00346
00347 void decode(const std::vector<uint8_t> &data) {
00348 acc = {{deserialise_int16(data, 0), deserialise_int16(data, 2), deserialise_int16(data, 4)}};
00349 gyro = {{deserialise_int16(data, 6), deserialise_int16(data, 8), deserialise_int16(data, 10)}};
00350 magn = {{deserialise_int16(data, 12), deserialise_int16(data, 14), deserialise_int16(data, 16)}};
00351 }
00352 };
00353
00354
00355 struct ImuSI {
00356 std::array<float, 3> acc;
00357 std::array<float, 3> gyro;
00358 std::array<float, 3> magn;
00359
00360 ImuSI(const ImuRaw &imu_raw,
00361 const float acc_1g,
00362 const float gyro_unit,
00363 const float magn_gain,
00364 const float si_unit_1g
00365 )
00366 {
00367 acc = {{imu_raw.acc[0]/acc_1g*si_unit_1g,
00368 imu_raw.acc[1]/acc_1g*si_unit_1g,
00369 imu_raw.acc[2]/acc_1g*si_unit_1g}};
00370
00371 gyro = {{imu_raw.gyro[0]*gyro_unit,
00372 imu_raw.gyro[1]*gyro_unit,
00373 imu_raw.gyro[2]*gyro_unit}};
00374
00375 magn = {{imu_raw.magn[0]*magn_gain,
00376 imu_raw.magn[1]*magn_gain,
00377 imu_raw.magn[2]*magn_gain}};
00378 }
00379 };
00380
00381
00382 struct Servo : public Request {
00383 ID id() const { return ID::MSP_SERVO; }
00384
00385 uint16_t servo[N_SERVO];
00386
00387 void decode(const std::vector<uint8_t> &data) {
00388 for(unsigned int i=0; i<N_SERVO; i++)
00389 servo[i] = deserialise_uint16(data, 2*i);
00390 }
00391 };
00392
00393
00394 struct Motor : public Request {
00395 ID id() const { return ID::MSP_MOTOR; }
00396
00397 uint16_t motor[N_MOTOR];
00398
00399 void decode(const std::vector<uint8_t> &data) {
00400 for(unsigned int i=0; i<N_MOTOR; i++)
00401 motor[i] = deserialise_uint16(data, 2*i);
00402 }
00403 };
00404
00405
00406 struct Rc : public Request {
00407 ID id() const { return ID::MSP_RC; }
00408
00409 std::vector<uint16_t> channels;
00410
00411 void decode(const std::vector<uint8_t> &data) {
00412 channels.clear();
00413
00414
00415
00416 for(uint i(0); i<data.size(); i+=sizeof(uint16_t)) {
00417 channels.push_back(deserialise_uint16(data, i));
00418 }
00419 }
00420 };
00421
00422
00423 struct RawGPS : public Request {
00424 ID id() const { return ID::MSP_RAW_GPS; }
00425
00426 uint8_t fix;
00427 uint8_t numSat;
00428 uint32_t lat;
00429 uint32_t lon;
00430 uint16_t altitude;
00431 uint16_t speed;
00432 uint16_t ground_course;
00433
00434 void decode(const std::vector<uint8_t> &data) {
00435 fix = data[0];
00436 numSat = data[1];
00437 lat = deserialise_uint32(data, 2);
00438 lon = deserialise_uint32(data, 6);
00439 altitude = deserialise_uint16(data, 10);
00440 speed = deserialise_uint16(data, 12);
00441 ground_course = deserialise_uint16(data, 14);
00442 }
00443 };
00444
00445
00446 struct CompGPS : public Request {
00447 ID id() const { return ID::MSP_COMP_GPS; }
00448
00449 uint16_t distanceToHome;
00450 uint16_t directionToHome;
00451 uint8_t update;
00452
00453 void decode(const std::vector<uint8_t> &data) {
00454 distanceToHome = deserialise_uint16(data, 0);
00455 directionToHome = deserialise_uint16(data, 2);
00456 update = data[4];
00457 }
00458 };
00459
00460
00461 struct Attitude : public Request {
00462 ID id() const { return ID::MSP_ATTITUDE; }
00463
00464 float ang_x;
00465 float ang_y;
00466 int16_t heading;
00467
00468 void decode(const std::vector<uint8_t> &data) {
00469 ang_x = deserialise_int16(data, 0)/10.0f;
00470 ang_y = deserialise_int16(data, 2)/10.0f;
00471 heading = deserialise_int16(data, 4);
00472 }
00473 };
00474
00475
00476 struct Altitude : public Request {
00477 ID id() const { return ID::MSP_ALTITUDE; }
00478
00479 float altitude;
00480 float vario;
00481
00482 void decode(const std::vector<uint8_t> &data) {
00483 altitude = deserialise_int32(data, 0)/100.0f;
00484 vario = deserialise_int16(data, 4)/100.0f;
00485 }
00486 };
00487
00488
00489 struct Analog : public Request {
00490 ID id() const { return ID::MSP_ANALOG; }
00491
00492 float vbat;
00493 float powerMeterSum;
00494 uint rssi;
00495 float amperage;
00496
00497 void decode(const std::vector<uint8_t> &data) {
00498 vbat = data[0]/10.0f;
00499 powerMeterSum = deserialise_uint16(data, 1)/1000.0f;
00500 rssi = deserialise_uint16(data, 3);
00501 amperage = deserialise_uint16(data, 5)/10.0f;
00502 }
00503 };
00504
00505
00506 struct RcTuning : Request {
00507 ID id() const { return ID::MSP_RC_TUNING; }
00508
00509 double RC_RATE;
00510 double RC_EXPO;
00511 double RollPitchRate;
00512 double YawRate;
00513 double DynThrPID;
00514 double Throttle_MID;
00515 double Throttle_EXPO;
00516
00517 void decode(const std::vector<uint8_t> &data) {
00518 RC_RATE = data[0] / 100.0;
00519 RC_EXPO = data[1] / 100.0;
00520 RollPitchRate = data[2] / 100.0;
00521 YawRate = data[3] / 100.0;
00522 DynThrPID = data[4] / 100.0;
00523 Throttle_MID = data[5] / 100.0;
00524 Throttle_EXPO = data[6] / 100.0;
00525 }
00526 };
00527
00528
00529 struct PidTerms {
00530 float P;
00531 float I;
00532 float D;
00533
00534 PidTerms() { }
00535
00536 PidTerms(const uint8_t P, const uint8_t I, const uint8_t D)
00537 : P(P/10.0f), I(I/10.0f), D(D/10.0f)
00538 { }
00539 };
00540
00541
00542 struct Pid : public Request {
00543 ID id() const { return ID::MSP_PID; }
00544
00545 PidTerms roll, pitch, yaw, alt;
00546 PidTerms pos, posr, navr, level, mag, vel;
00547
00548 void decode(const std::vector<uint8_t> &data) {
00549 roll = PidTerms(data[0], data[1], data[2]);
00550 pitch = PidTerms(data[3], data[4], data[5]);
00551 yaw = PidTerms(data[6], data[7], data[8]);
00552 alt = PidTerms(data[9], data[10], data[11]);
00553 pos = PidTerms(data[12], data[13], data[14]);
00554 posr = PidTerms(data[15], data[16], data[17]);
00555 navr = PidTerms(data[18], data[19], data[20]);
00556 level = PidTerms(data[21], data[22], data[23]);
00557 mag = PidTerms(data[24], data[25], data[26]);
00558 vel = PidTerms(data[27], data[28], data[29]);
00559 }
00560 };
00561
00562
00563 struct Box : public Request {
00564 ID id() const { return ID::MSP_BOX; }
00565
00566
00567 std::vector<std::array<std::set<SwitchPosition>,NAUX>> box_pattern;
00568
00569 void decode(const std::vector<uint8_t> &data) {
00570 box_pattern.clear();
00571 for(uint i(0); i<data.size(); i+=2) {
00572 const uint16_t box_conf = deserialise_uint16(data, i);
00573
00574
00575 std::array<std::set<SwitchPosition>,NAUX> aux_sp;
00576 for(uint iaux(0); iaux<NAUX; iaux++) {
00577 for(uint ip(0); ip<3; ip++) {
00578 if(box_conf & (1<<(iaux*3+ip)))
00579 aux_sp[iaux].insert(SwitchPosition(ip));
00580 }
00581 }
00582 box_pattern.push_back(aux_sp);
00583 }
00584 }
00585 };
00586
00587
00588 struct Misc : public Request {
00589 ID id() const { return ID::MSP_MISC; }
00590
00591 uint powerTrigger;
00592 uint minThrottle, maxThrottle, failsafeThrottle;
00593 uint minCommand;
00594 uint arm, lifetime;
00595 float mag_declination;
00596 float vbatScale, vbatLevelWarn1, vbatLevelWarn2, vbatLevelCrit;
00597
00598 void decode(const std::vector<uint8_t> &data) {
00599 powerTrigger = deserialise_uint16(data, 0);
00600 minThrottle = deserialise_uint16(data, 2);
00601 maxThrottle = deserialise_uint16(data, 4);
00602 minCommand = deserialise_uint16(data, 6);
00603
00604 failsafeThrottle = deserialise_uint16(data, 8);
00605 arm = deserialise_uint16(data, 10);
00606 lifetime = deserialise_uint32(data, 12);
00607 mag_declination = deserialise_uint16(data, 16) / 10.0f;
00608
00609 vbatScale = data[18] / 10.0f;
00610 vbatLevelWarn1 = data[19] / 10.0f;
00611 vbatLevelWarn2 = data[20] / 10.0f;
00612 vbatLevelCrit = data[21] / 10.0f;
00613 }
00614 };
00615
00616
00617 struct MotorPins : public Request {
00618 ID id() const { return ID::MSP_MOTOR_PINS; }
00619
00620 uint8_t pwm_pin[N_MOTOR];
00621
00622 void decode(const std::vector<uint8_t> &data) {
00623 for(uint i(0); i<N_MOTOR; i++)
00624 pwm_pin[i] = data[i];
00625 }
00626 };
00627
00628
00629 struct BoxNames : public Request {
00630 ID id() const { return ID::MSP_BOXNAMES; }
00631
00632 std::vector<std::string> box_names;
00633
00634 void decode(const std::vector<uint8_t> &data) {
00635 box_names.clear();
00636
00637 std::stringstream ss(std::string(data.begin(), data.end()));
00638 std::string bname;
00639 while(getline(ss, bname, ';')) {
00640 box_names.push_back(bname);
00641 }
00642 }
00643 };
00644
00645
00646 struct PidNames : public Request {
00647 ID id() const { return ID::MSP_PIDNAMES; }
00648
00649 std::vector<std::string> pid_names;
00650
00651 void decode(const std::vector<uint8_t> &data) {
00652 pid_names.clear();
00653
00654 std::stringstream ss(std::string(data.begin(), data.end()));
00655 std::string pname;
00656 while(getline(ss, pname, ';')) {
00657 pid_names.push_back(pname);
00658 }
00659 }
00660 };
00661
00662
00663 struct WayPoint : public Request {
00664 ID id() const { return ID::MSP_WP; }
00665
00666 uint8_t wp_no;
00667 uint32_t lat;
00668 uint32_t lon;
00669 uint32_t altHold;
00670 uint16_t heading;
00671 uint16_t staytime;
00672 uint8_t navflag;
00673
00674 void decode(const std::vector<uint8_t> &data) {
00675 wp_no = data[0];
00676 lat = deserialise_uint32(data, 1);
00677 lon = deserialise_uint32(data, 5);
00678 altHold = deserialise_uint32(data, 9);
00679 heading = deserialise_uint16(data, 13);
00680 staytime = deserialise_uint16(data, 15);
00681 navflag = data[18];
00682 }
00683 };
00684
00685
00686 struct BoxIds : public Request {
00687 ID id() const { return ID::MSP_BOXIDS; }
00688
00689 std::vector<uint8_t> box_ids;
00690
00691 void decode(const std::vector<uint8_t> &data) {
00692 box_ids.clear();
00693
00694 for(uint8_t bi : data)
00695 box_ids.push_back(bi);;
00696 }
00697 };
00698
00699 struct ServoConfRange {
00700 uint16_t min;
00701 uint16_t max;
00702 uint16_t middle;
00703 uint8_t rate;
00704 };
00705
00706
00707 struct ServoConf : public Request {
00708 ID id() const { return ID::MSP_SERVO_CONF; }
00709
00710 ServoConfRange servo_conf[N_SERVO];
00711
00712 void decode(const std::vector<uint8_t> &data) {
00713 for(uint i(0); i<N_SERVO; i++) {
00714 servo_conf[i].min = deserialise_uint16(data, 7*i);
00715 servo_conf[i].max = deserialise_uint16(data, 7*i+2);
00716 servo_conf[i].middle = deserialise_uint16(data, 7*i+4);
00717 servo_conf[i].rate = data[7*i+6];
00718 }
00719 }
00720 };
00721
00722
00723 struct NavStatus: public Request {
00724 ID id() const { return ID::MSP_NAV_STATUS; }
00725
00726 uint8_t GPS_mode;
00727 uint8_t NAV_state;
00728 uint8_t mission_action;
00729 uint8_t mission_number;
00730 uint8_t NAV_error;
00731 int16_t target_bearing;
00732
00733 void decode(const std::vector<uint8_t> &data) {
00734 GPS_mode = data[0];
00735 NAV_state = data[1];
00736 mission_action = data[2];
00737 mission_number = data[3];
00738 NAV_error = data[4];
00739 target_bearing = deserialise_int16(data, 5);
00740 }
00741 };
00742
00743
00744 struct GpsConf {
00745 uint8_t filtering;
00746 uint8_t lead_filter;
00747 uint8_t dont_reset_home_at_arm;
00748 uint8_t nav_controls_heading;
00749
00750 uint8_t nav_tail_first;
00751 uint8_t nav_rth_takeoff_heading;
00752 uint8_t slow_nav;
00753 uint8_t wait_for_rth_alt;
00754
00755 uint8_t ignore_throttle;
00756 uint8_t takeover_baro;
00757
00758 uint16_t wp_radius;
00759 uint16_t safe_wp_distance;
00760 uint16_t nav_max_altitude;
00761 uint16_t nav_speed_max;
00762 uint16_t nav_speed_min;
00763
00764 uint8_t crosstrack_gain;
00765 uint16_t nav_bank_max;
00766 uint16_t rth_altitude;
00767 uint8_t land_speed;
00768 uint16_t fence;
00769
00770 uint8_t max_wp_number;
00771
00772 uint8_t checksum;
00773 };
00774
00775
00776 struct NavConfig: public Request {
00777 ID id() const { return ID::MSP_NAV_CONFIG; }
00778
00779 GpsConf gps_conf;
00780
00781 void decode(const std::vector<uint8_t> &data) {
00782 gps_conf.filtering = data[0];
00783 gps_conf.lead_filter = data[1];
00784 gps_conf.dont_reset_home_at_arm = data[2];
00785 gps_conf.nav_controls_heading = data[3];
00786
00787 gps_conf.nav_tail_first = data[4];
00788 gps_conf.nav_rth_takeoff_heading = data[5];
00789 gps_conf.slow_nav = data[6];
00790 gps_conf.wait_for_rth_alt = data[7];
00791
00792 gps_conf.ignore_throttle = data[8];
00793 gps_conf.takeover_baro = data[9];
00794
00795 gps_conf.wp_radius = deserialise_uint16(data, 10);
00796 gps_conf.safe_wp_distance = deserialise_uint16(data, 12);
00797 gps_conf.nav_max_altitude = deserialise_uint16(data, 14);
00798 gps_conf.nav_speed_max = deserialise_uint16(data, 16);
00799 gps_conf.nav_speed_min = deserialise_uint16(data, 18);
00800
00801 gps_conf.crosstrack_gain = data[20];
00802 gps_conf.nav_bank_max = deserialise_uint16(data, 21);
00803 gps_conf.rth_altitude = deserialise_uint16(data, 23);
00804 gps_conf.land_speed = data[25];
00805 gps_conf.fence = deserialise_uint16(data, 26);
00806
00807 gps_conf.max_wp_number = data[28];
00808
00809 gps_conf.checksum = data[29];
00810 }
00811 };
00812
00813
00814 struct DebugMessage : public Request {
00815 ID id() const { return ID::MSP_DEBUGMSG; }
00816
00817 std::string msg;
00818
00819 void decode(const std::vector<uint8_t> &data) {
00820 msg = std::string(data.begin(), data.end());
00821 }
00822 };
00823
00824
00825 struct Debug : public Request {
00826 ID id() const { return ID::MSP_DEBUG; }
00827
00828 uint16_t debug1;
00829 uint16_t debug2;
00830 uint16_t debug3;
00831 uint16_t debug4;
00832
00833 void decode(const std::vector<uint8_t> &data) {
00834 debug1 = deserialise_uint16(data, 0);
00835 debug2 = deserialise_uint16(data, 2);
00836 debug3 = deserialise_uint16(data, 4);
00837 debug4 = deserialise_uint16(data, 6);
00838 }
00839 };
00840
00841
00844
00845
00846
00847
00848
00849 struct SetRc : public Response {
00850 ID id() const { return ID::MSP_SET_RAW_RC; }
00851
00852 std::vector<uint16_t> channels;
00853
00854 std::vector<uint8_t> encode() const {
00855 std::vector<uint8_t> data;
00856 for(const uint16_t c : channels) {
00857 serialise_uint16(c, data);
00858 }
00859 return data;
00860 }
00861 };
00862
00863
00864 struct SetRawGPS : public Request {
00865 ID id() const { return ID::MSP_SET_RAW_GPS; }
00866
00867 uint8_t fix;
00868 uint8_t numSat;
00869 uint32_t lat;
00870 uint32_t lon;
00871 uint16_t altitude;
00872 uint16_t speed;
00873
00874 std::vector<uint8_t> encode() const {
00875 std::vector<uint8_t> data;
00876 data.push_back(fix);
00877 data.push_back(numSat);
00878 serialise_uint32(lat, data);
00879 serialise_uint32(lon, data);
00880 serialise_uint16(altitude, data);
00881 serialise_uint16(speed, data);
00882 assert(data.size()==14);
00883 return data;
00884 }
00885 };
00886
00887
00888 struct SetRcTuning : public Response {
00889 ID id() const { return ID::MSP_SET_RC_TUNING; }
00890
00891 double RC_RATE;
00892 double RC_EXPO;
00893 double RollPitchRate;
00894 double YawRate;
00895 double DynThrPID;
00896 double Throttle_MID;
00897 double Throttle_EXPO;
00898
00903 SetRcTuning(const RcTuning &rc_tuning) {
00904 RC_RATE = rc_tuning.RC_RATE;
00905 RC_EXPO = rc_tuning.RC_EXPO;
00906 RollPitchRate = rc_tuning.RollPitchRate;
00907 YawRate = rc_tuning.YawRate;
00908 DynThrPID = rc_tuning.DynThrPID;
00909 Throttle_MID = rc_tuning.Throttle_MID;
00910 Throttle_EXPO = rc_tuning.Throttle_EXPO;
00911 }
00912
00913 std::vector<uint8_t> encode() const {
00914 std::vector<uint8_t> data(7);
00915 data[0] = uint8_t(RC_RATE * 100);
00916 data[1] = uint8_t(RC_EXPO * 100);
00917 data[2] = uint8_t(RollPitchRate * 100);
00918 data[3] = uint8_t(YawRate * 100);
00919 data[4] = uint8_t(DynThrPID * 100);
00920 data[5] = uint8_t(Throttle_MID * 100);
00921 data[6] = uint8_t(Throttle_EXPO * 100);
00922 return data;
00923 }
00924 };
00925
00926
00927 struct AccCalibration : public Response {
00928 ID id() const { return ID::MSP_ACC_CALIBRATION; }
00929 std::vector<uint8_t> encode() const {
00930 return std::vector<uint8_t>();
00931 }
00932 };
00933
00934
00935 struct MagCalibration : public Response {
00936 ID id() const { return ID::MSP_MAG_CALIBRATION; }
00937 std::vector<uint8_t> encode() const {
00938 return std::vector<uint8_t>();
00939 }
00940 };
00941
00942
00943 struct ResetConfig : public Response {
00944 ID id() const { return ID::MSP_RESET_CONF; }
00945 std::vector<uint8_t> encode() const {
00946 return std::vector<uint8_t>();
00947 }
00948 };
00949
00950
00951 struct SelectSetting : public Response {
00952 ID id() const { return ID::MSP_SELECT_SETTING; }
00953
00954 uint current_setting;
00955
00956 std::vector<uint8_t> encode() const {
00957 std::vector<uint8_t> data(1);
00958 data[0] = uint8_t(current_setting);
00959 return data;
00960 }
00961 };
00962
00963
00964 struct SetHeading : public Response {
00965 ID id() const { return ID::MSP_SET_HEAD; }
00966
00967 int heading;
00968
00969 std::vector<uint8_t> encode() const {
00970 std::vector<uint8_t> data;
00971 serialise_int16(int16_t(heading), data);
00972 assert(data.size()==2);
00973 return data;
00974 }
00975 };
00976
00977
00978 struct SetMotor : public Response {
00979 ID id() const { return ID::MSP_SET_MOTOR; }
00980
00981 std::array<uint16_t,N_MOTOR> motor;
00982
00983 std::vector<uint8_t> encode() const {
00984 std::vector<uint8_t> data;
00985 for(uint i(0); i<N_MOTOR; i++)
00986 serialise_uint16(motor[i], data);
00987 assert(data.size()==N_MOTOR*2);
00988 return data;
00989 }
00990 };
00991
00992
00993 struct WriteEEPROM : public Response {
00994 ID id() const { return ID::MSP_EEPROM_WRITE; }
00995 std::vector<uint8_t> encode() const {
00996 return std::vector<uint8_t>();
00997 }
00998 };
00999
01000 }
01001 }
01002
01003 #endif // MSP_MSG_HPP