Go to the documentation of this file.00001 #include "FlightController.hpp"
00002
00003 #include <iostream>
00004
00005 namespace fcu {
00006
00007 FlightController::FlightController(const std::string &device, const uint baudrate) {
00008 client.connect(device, baudrate);
00009 client.start();
00010 }
00011
00012 FlightController::~FlightController() {
00013 client.stop();
00014 }
00015
00016 void FlightController::waitForConnection() {
00017 std::cout<<"Wait for FC..."<<std::endl;
00018 msp::msg::Ident ident;
00019 while(!client.request(ident, 0.5));
00020 std::cout<<"MultiWii version "<<uint(ident.version)<<" ready"<<std::endl;
00021 }
00022
00023 void FlightController::initialise() {
00024
00025 while(client.request(ident, 0.5)==-1);
00026
00027 msp::msg::ApiVersion api;
00028 if(client.request(api)) {
00029
00030 firmware = FirmwareType::CLEANFLIGHT;
00031 std::cout<<"Cleanflight API "<<api.major<<"."<<api.minor<<"."<<api.protocol<<" ready"<<std::endl;
00032 }
00033 else {
00034
00035 firmware = FirmwareType::MULTIWII;
00036 std::cout<<"MultiWii version "<<uint(ident.version)<<" ready"<<std::endl;
00037 }
00038
00039
00040 msp::msg::Status status;
00041 client.request(status);
00042 sensors = status.sensors;
00043
00044
00045 initBoxes();
00046
00047
00048 if(isFirmwareMultiWii()) {
00049
00050 channel_map.clear();
00051 for(uint8_t i(0); i<MAX_MAPPABLE_RX_INPUTS; i++) {
00052 channel_map.push_back(i);
00053 }
00054 }
00055 else {
00056
00057 msp::msg::RxMap rx_map;
00058 client.request(rx_map);
00059 channel_map = rx_map.map;
00060 }
00061 }
00062
00063 bool FlightController::isFirmware(const FirmwareType firmware_type) {
00064 return firmware == firmware_type;
00065 }
00066
00067 void FlightController::initBoxes() {
00068 client.setPrintWarnings(true);
00069
00070 msp::msg::BoxNames box_names;
00071 if(!client.request(box_names))
00072 throw std::runtime_error("Cannot get BoxNames!");
00073
00074
00075 msp::msg::BoxIds box_ids;
00076 if(!client.request(box_ids))
00077 throw std::runtime_error("Cannot get BoxIds!");
00078
00079 assert(box_names.box_names.size()==box_ids.box_ids.size());
00080
00081 box_name_ids.clear();
00082 for(uint ibox(0); ibox<box_names.box_names.size(); ibox++) {
00083 if(isFirmwareCleanflight()) {
00084
00085
00086
00087 box_name_ids[box_names.box_names[ibox]] = ibox;
00088 }
00089 else {
00090 box_name_ids[box_names.box_names[ibox]] = box_ids.box_ids[ibox];
00091 }
00092 }
00093 client.setPrintWarnings(false);
00094 }
00095
00096 bool FlightController::isStatusActive(const std::string& status_name) {
00097 if(box_name_ids.count(status_name)==0) {
00098
00099 throw std::runtime_error("Box ID of "+status_name+" is unknown! You need to call 'initBoxes()' first.");
00100 }
00101
00102 msp::msg::Status status;
00103 client.request(status);
00104
00105
00106 return status.active_box_id.count(box_name_ids.at(status_name));
00107 }
00108
00109 bool FlightController::setRc(const uint16_t roll, const uint16_t pitch,
00110 const uint16_t yaw, const uint16_t throttle,
00111 const uint16_t aux1, const uint16_t aux2,
00112 const uint16_t aux3, const uint16_t aux4,
00113 const std::vector<uint16_t> auxs)
00114 {
00115 if(isFirmwareMultiWii() && hasDynBal()) {
00116 throw std::runtime_error(
00117 "DYNBALANCE is active!\n"
00118 "RC commands will have no effect on motors.");
00119 }
00120
00121 msp::msg::SetRc rc;
00122
00123 rc.channels.resize(MAX_MAPPABLE_RX_INPUTS);
00124 rc.channels[channel_map[0]] = roll;
00125 rc.channels[channel_map[1]] = pitch;
00126 rc.channels[channel_map[2]] = yaw;
00127 rc.channels[channel_map[3]] = throttle;
00128 rc.channels[channel_map[4]] = aux1;
00129 rc.channels[channel_map[5]] = aux2;
00130 rc.channels[channel_map[6]] = aux3;
00131 rc.channels[channel_map[7]] = aux4;
00132
00133
00134 rc.channels.insert(std::end(rc.channels), std::begin(auxs), std::end(auxs));
00135
00136
00137 return client.respond(rc, false);
00138 }
00139
00140 bool FlightController::setRc(const std::vector<uint16_t> channels) {
00141 msp::msg::SetRc rc;
00142 rc.channels = channels;
00143 return client.respond(rc, false);
00144 }
00145
00146 bool FlightController::setMotors(const std::array<uint16_t,msp::msg::N_MOTOR> &motor_values) {
00147 if(isFirmwareMultiWii() && !hasDynBal()) {
00148 throw std::runtime_error(
00149 "DYNBALANCE is not active!\n"
00150 "Set '#define DYNBALANCE' in your MultiWii 'config.h'");
00151 }
00152
00153 msp::msg::SetMotor motor;
00154 motor.motor = motor_values;
00155 return client.respond(motor);
00156 }
00157
00158 bool FlightController::arm(const bool arm) {
00159
00160
00161
00162
00163
00164 const uint16_t yaw = arm ? 2000 : 1000;
00165
00166 return setRc(1500, 1500, yaw, 1000, 1000, 1000, 1000, 1000);
00167 }
00168
00169 bool FlightController::arm_block() {
00170
00171 while(isArmed()==false) {
00172 arm(true);
00173 std::this_thread::sleep_for(std::chrono::milliseconds(1));
00174 }
00175 return true;
00176 }
00177
00178 bool FlightController::disarm_block() {
00179
00180 while(isArmed()==true) {
00181 arm(false);
00182 std::this_thread::sleep_for(std::chrono::milliseconds(1));
00183 }
00184 return true;
00185 }
00186
00187 int FlightController::updateFeatures(const std::set<std::string> &add,
00188 const std::set<std::string> &remove)
00189 {
00190
00191 msp::msg::Feature feature_in;
00192 if(!client.request(feature_in))
00193 return -1;
00194
00195
00196 msp::msg::SetFeature feature_out;
00197 feature_out.features = feature_in.features;
00198
00199 for(const std::string &a : add) {
00200 feature_out.features.insert(a);
00201 }
00202
00203 for(const std::string &rem : remove) {
00204 feature_out.features.erase(rem);
00205 }
00206
00207
00208 if(feature_out.features==feature_in.features)
00209 return 0;
00210
00211 if(!client.respond(feature_out))
00212 return -1;
00213
00214
00215 if(!writeEEPROM())
00216 return -1;
00217 if(!reboot())
00218 return -1;
00219
00220 return 1;
00221 }
00222
00223 bool FlightController::reboot() {
00224 return client.respond(msp::msg::Reboot());
00225 }
00226
00227 bool FlightController::writeEEPROM() {
00228 return client.respond(msp::msg::WriteEEPROM());
00229 }
00230
00231 }