msp_msg.hpp
Go to the documentation of this file.
00001 // MSP message definitions
00002 // http://www.multiwii.com/wiki/index.php?title=Multiwii_Serial_Protocol
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,              // 2
00033     QUADX,              // 3
00034     BI,                 // 4
00035     GIMBAL,             // 5
00036     Y6,                 // 6
00037     HEX6,               // 7
00038     FLYING_WING,        // 8
00039     Y4,                 // 9
00040     HEX6X,              // 10
00041     OCTOX8,             // 11
00042     OCTOFLATP,          // 12
00043     OCTOFLATX,          // 13
00044     AIRPLANE,           // 14
00045     HELI_120_CCPM,  // 15
00046     HELI_90_DEG,    // 16
00047     VTAIL4,             // 17
00048     HEX6H,              // 18
00049     DUALCOPTER      = 20,
00050     SINGLECOPTER,   // 21
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 // MSP_API_VERSION: 1
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 // MSP_FC_VARIANT: 2
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 // MSP_FC_VERSION: 3
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 // MSP_BOARD_INFO: 4
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 // MSP_BUILD_INFO: 5
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 // MSP_FEATURE: 36
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 // MSP_SET_FEATURE: 37
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 // MSP_RX_CONFIG: 44
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 // MSP_RX_MAP: 64
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 // MSP_SET_RX_MAP: 65
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 // MSP_REBOOT: 68
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 // MSP_IDENT: 100
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         // determine multicopter type
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 // MSP_STATUS: 101
00289 struct Status : public Request {
00290     ID id() const { return ID::MSP_STATUS; }
00291 
00292     uint16_t    time;   // in us
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         // get sensors
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         // check active boxes
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 // MSP_RAW_IMU: 102
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 // Imu in SI units
00355 struct ImuSI {
00356     std::array<float, 3> acc;   // m/s^2
00357     std::array<float, 3> gyro;  // deg/s
00358     std::array<float, 3> magn;  // uT
00359 
00360     ImuSI(const ImuRaw &imu_raw,
00361           const float acc_1g,       // sensor value at 1g
00362           const float gyro_unit,    // resolution in 1/(deg/s)
00363           const float magn_gain,    // scale magnetic value to uT (micro Tesla)
00364           const float si_unit_1g    // acceleration at 1g (in m/s^2)
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 // MSP_SERVO: 103
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 // MSP_MOTOR: 104
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 // MSP_RC: 105
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         // If feature 'RX_MSP' is active but "USE_RX_MSP" is undefined for the target,
00414         // no RC data is provided as feedback. See also description at 'MSP_SET_RAW_RC'.
00415         // In this case, return 0 for all RC channels.
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 // MSP_RAW_GPS: 106
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 // MSP_COMP_GPS: 107
00446 struct CompGPS : public Request {
00447     ID id() const { return ID::MSP_COMP_GPS; }
00448 
00449     uint16_t distanceToHome;    // meter
00450     uint16_t directionToHome;   // degree
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 // MSP_ATTITUDE: 108
00461 struct Attitude : public Request {
00462     ID id() const { return ID::MSP_ATTITUDE; }
00463 
00464     float ang_x;        // degree
00465     float ang_y;        // degree
00466     int16_t heading;    // degree
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 // MSP_ALTITUDE: 109
00476 struct Altitude : public Request {
00477     ID id() const { return ID::MSP_ALTITUDE; }
00478 
00479     float altitude; // m
00480     float vario;    // m/s
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 // MSP_ANALOG: 110
00489 struct Analog : public Request {
00490     ID id() const { return ID::MSP_ANALOG; }
00491 
00492     float vbat;           // Volt
00493     float powerMeterSum;  // Ah
00494     uint rssi;  // Received Signal Strength Indication [0; 1023]
00495     float amperage;       // Ampere
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 // MSP_RC_TUNING: 111
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 // PID struct for messages 112 and 204
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 // MSP_PID: 112
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 // MSP_BOX: 113
00563 struct Box : public Request {
00564     ID id() const { return ID::MSP_BOX; }
00565 
00566     // box activation pattern
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             //box_conf.push_back(deser16(data, i));
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                 } // each position (L,M,H)
00581             } // each aux switch
00582             box_pattern.push_back(aux_sp);
00583         } // each box
00584     }
00585 };
00586 
00587 // MSP_MISC: 114
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; // degree
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 // MSP_MOTOR_PINS: 115
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 // MSP_BOXNAMES: 116
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 // MSP_PIDNAMES: 117
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 // MSP_WP: 118
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 // MSP_BOXIDS: 119
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 // MSP_SERVO_CONF: 120
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 // MSP_NAV_STATUS: 121
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; // degrees
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;           // in cm
00759   uint16_t safe_wp_distance;    // in meter
00760   uint16_t nav_max_altitude;    // in meter
00761   uint16_t nav_speed_max;       // in cm/s
00762   uint16_t nav_speed_min;       // in cm/s
00763 
00764   uint8_t  crosstrack_gain;     // * 100 (0-2.56)
00765   uint16_t nav_bank_max;        // degree * 100; (3000 default)
00766   uint16_t rth_altitude;        // in meter
00767   uint8_t  land_speed;          // between 50 and 255 (100 approx = 50cm/sec)
00768   uint16_t fence;               // fence control in meters
00769 
00770   uint8_t  max_wp_number;
00771 
00772   uint8_t  checksum;
00773 };
00774 
00775 // MSP_NAV_CONFIG: 122
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 // MSP_DEBUGMSG: 253
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 // MSP_DEBUG: 254
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 // MSP_SET_RAW_RC: 200
00846 // This message is accepted but ignored on betaflight 3.0.1 onwards
00847 // if "USE_RX_MSP" is not defined for the target. In this case, you can manually
00848 // add "#define USE_RX_MSP" to your 'target.h'.
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 // MSP_SET_RAW_GPS: 201
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 // MSP_SET_RC_TUNING: 204
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 // MSP_ACC_CALIBRATION: 205
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 // MSP_MAG_CALIBRATION: 206
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 // MSP_RESET_CONF: 208
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 // MSP_SELECT_SETTING: 210
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 // MSP_SET_HEAD: 211
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 // MSP_SET_MOTOR: 214
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 // MSP_EEPROM_WRITE: 250
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 } // namespace msg
01001 } // namespace msp
01002 
01003 #endif // MSP_MSG_HPP


msp
Author(s): Christian Rauch
autogenerated on Mon Oct 9 2017 03:02:14