DJI_Flight.cpp
Go to the documentation of this file.
00001 
00013 #include "DJI_Flight.h"
00014 #include <string.h>
00015 #include <math.h>
00016 
00017 using namespace DJI;
00018 using namespace DJI::onboardSDK;
00019 
00020 Flight::Flight(DJI::onboardSDK::CoreAPI *ControlAPI)
00021 {
00022   api = ControlAPI;
00023 #ifdef USE_SIMULATION  //! @note This functionality is not supported in this release.  
00024   simulating = 0;
00025 #endif // USE_SIMULATION
00026 }
00027 
00028 CoreAPI *Flight::getApi() const { return api; }
00029 
00030 void Flight::setApi(CoreAPI *value) { api = value; }
00031 
00032 #ifdef USE_SIMULATION   //! @note This functionality is not supported in this release.  
00033 bool Flight::isSimulating() const { return simulating; }
00034 void Flight::setSimulating(bool value) { simulating = value; }
00035 #endif // USE_SIMULATION
00036 
00037 void Flight::task(TASK taskname, CallBack TaskCallback, UserData userData)
00038 {
00039   taskData.cmdData = taskname;
00040   taskData.cmdSequence++;
00041 
00042   api->send(2, encrypt, SET_CONTROL, CODE_TASK, (unsigned char *)&taskData, sizeof(taskData),
00043       100, 3, TaskCallback ? TaskCallback : Flight::taskCallback, userData);
00044 }
00045 
00046 unsigned short Flight::task(TASK taskname, int timeout)
00047 {
00048   taskData.cmdData = taskname;
00049   taskData.cmdSequence++;
00050 
00051   api->send(2, encrypt, SET_CONTROL, CODE_TASK, (unsigned char *)&taskData, sizeof(taskData),
00052       100, 3, 0, 0);
00053 
00054   api->serialDevice->lockACK();
00055   api->serialDevice->wait(timeout);
00056   api->serialDevice->freeACK();
00057 
00058   return api->missionACKUnion.simpleACK;
00059 }
00060 
00061 void Flight::setArm(bool enable, CallBack ArmCallback, UserData userData)
00062 {
00063   uint8_t data = enable ? 1 : 0;
00064   api->send(2, encrypt, SET_CONTROL, CODE_SETARM, &data, 1, 0, 1,
00065       ArmCallback ? ArmCallback : Flight::armCallback, userData);
00066 }
00067 
00068 unsigned short Flight::setArm(bool enable, int timeout)
00069 {
00070   uint8_t data = enable ? 1 : 0;
00071   api->send(2, encrypt, SET_CONTROL, CODE_SETARM, &data, 1, 0, 1, 0, 0);
00072 
00073 
00074   api->serialDevice->lockACK();
00075   api->serialDevice->wait(timeout);
00076   api->serialDevice->freeACK();
00077 
00078   return api->missionACKUnion.simpleACK;
00079 }
00080 
00081 void Flight::control(uint8_t flag, float32_t x, float32_t y, float32_t z, float32_t yaw)
00082 {
00083   FlightData data;
00084   data.flag = flag;
00085   data.x = x;
00086   data.y = y;
00087   data.z = z;
00088   data.yaw = yaw;
00089   setFlight(&data);
00090 }
00091 
00092 
00093 void Flight::setMovementControl(uint8_t flag, float32_t x, float32_t y, float32_t z, float32_t yaw)
00094 {
00095   FlightData data;
00096   data.flag = flag;
00097   data.x = x;
00098   data.y = y;
00099   data.z = z;
00100   data.yaw = yaw;
00101   api->send(0, encrypt, SET_CONTROL, CODE_CONTROL, &data, sizeof(FlightData));
00102 }
00103 
00104 
00105 void Flight::setFlight(FlightData *data)
00106 {
00107   api->send(0, encrypt, SET_CONTROL, CODE_CONTROL, (unsigned char *)data, sizeof(FlightData));
00108 }
00109 
00110 QuaternionData Flight::getQuaternion() const
00111 {
00112 #ifdef USE_SIMULATION    
00113   if (simulating)
00114   {
00115     QuaternionData ans;
00117 
00118     return ans;
00119   }
00120   else
00121 #endif // USE_SIMULATION
00122   return api->getBroadcastData().q;
00123 }
00124 
00125 EulerAngle Flight::getEulerAngle() const {return Flight::toEulerAngle(api->getBroadcastData().q); }
00126 
00127 PositionData Flight::getPosition() const { return api->getBroadcastData().pos; }
00128 
00129 VelocityData Flight::getVelocity() const { return api->getBroadcastData().v; }
00130 
00132 CommonData Flight::getAcceleration() const { return api->getBroadcastData().a; }
00134 CommonData Flight::getYawRate() const { return api->getBroadcastData().w; }
00135 
00137 MagnetData Flight::getMagnet() const { return api->getBroadcastData().mag; }
00138 
00139 Flight::Device Flight::getControlDevice() const
00140 {
00141   return (Flight::Device)api->getBroadcastData().ctrlInfo.deviceStatus;
00142 }
00143 
00144 Flight::Status Flight::getStatus() const
00145 {
00146   return (Flight::Status)api->getBroadcastData().status;
00147 }
00148 
00149 Flight::Mode Flight::getControlMode() const
00150 {
00151   if (api->getSDKVersion() != versionM100_23)
00152     return (Flight::Mode)api->getBroadcastData().ctrlInfo.mode;
00153   return MODE_NOT_SUPPORTED;
00154 }
00155 
00156 Angle Flight::getYaw() const
00157 {
00158 #ifdef USE_SIMULATION
00159   if (simulating)
00160     return AngularSim.yaw;
00161   else
00162 #endif // USE_SIMULATION
00163   return toEulerAngle(api->getBroadcastData().q).yaw;
00164 }
00165 
00166 Angle Flight::getRoll() const
00167 {
00168 #ifdef USE_SIMULATION
00169   if (simulating)
00170     return AngularSim.roll;
00171   else
00172 #endif // USE_SIMULATION
00173   return toEulerAngle(api->getBroadcastData().q).roll;
00174 }
00175 
00176 Angle Flight::getPitch() const
00177 {
00178 #ifdef USE_SIMULATION
00179   if (simulating)
00180     return AngularSim.pitch;
00181   else
00182 #endif // USE_SIMULATION
00183   return toEulerAngle(api->getBroadcastData().q).pitch;
00184 }
00185 
00186 void Flight::armCallback(CoreAPI *api, Header *protocolHeader, UserData userData __UNUSED)
00187 {
00188   unsigned short ack_data;
00189   if (protocolHeader->length - EXC_DATA_SIZE <= 2)
00190   {
00191     memcpy((unsigned char *)&ack_data, ((unsigned char *)protocolHeader) + sizeof(Header),
00192         (protocolHeader->length - EXC_DATA_SIZE));
00193     switch (ack_data)
00194     {
00195       case ACK_ARM_SUCCESS:
00196         API_LOG(api->getDriver(), STATUS_LOG, "Success,0x000%x\n", ack_data);
00197         break;
00198       case ACK_ARM_NEED_CONTROL:
00199         API_LOG(api->getDriver(), STATUS_LOG, "Need to obtain control first, 0x000%x\n", ack_data);
00200         break;
00201       case ACK_ARM_ALREADY_ARMED:
00202         API_LOG(api->getDriver(), STATUS_LOG, "Already done, 0x000%x\n", ack_data);
00203         break;
00204       case ACK_ARM_IN_AIR:
00205         API_LOG(api->getDriver(), STATUS_LOG, "Cannot execute while in air, 0x000%x\n", ack_data);
00206         break;
00207     }
00208   }
00209   else
00210   {
00211     API_LOG(api->getDriver(), ERROR_LOG, "ACK is exception,session id %d,sequence %d\n",
00212         protocolHeader->sessionID, protocolHeader->sequenceNumber);
00213   }
00214 }
00215 
00216 void Flight::taskCallback(CoreAPI *api, Header *protocolHeader, UserData userData __UNUSED)
00217 {
00218   unsigned short ack_data;
00219   if (protocolHeader->length - EXC_DATA_SIZE <= 2)
00220   {
00221     memcpy((unsigned char *)&ack_data, ((unsigned char *)protocolHeader) + sizeof(Header),
00222         (protocolHeader->length - EXC_DATA_SIZE));
00223     API_LOG(api->getDriver(), STATUS_LOG, "Task running successfully,%d\n", ack_data);
00224   }
00225  else
00226   {
00227     API_LOG(api->getDriver(), ERROR_LOG, "ACK is exception,session id %d,sequence %d\n",
00228         protocolHeader->sessionID, protocolHeader->sequenceNumber);
00229   }
00230 }
00231 
00233 EulerianAngle Flight::toEulerianAngle(QuaternionData data)
00234 {
00235   EulerianAngle ans;
00236 
00237   double q2sqr = data.q2 * data.q2;
00238   double t0 = -2.0 * (q2sqr + data.q3 * data.q3) + 1.0;
00239   double t1 = +2.0 * (data.q1 * data.q2 + data.q0 * data.q3);
00240   double t2 = -2.0 * (data.q1 * data.q3 - data.q0 * data.q2);
00241   double t3 = +2.0 * (data.q2 * data.q3 + data.q0 * data.q1);
00242   double t4 = -2.0 * (data.q1 * data.q1 + q2sqr) + 1.0;
00243 
00244   t2 = t2 > 1.0 ? 1.0 : t2;
00245   t2 = t2 < -1.0 ? -1.0 : t2;
00246 
00247   ans.pitch = asin(t2);
00248   ans.roll = atan2(t3, t4);
00249   ans.yaw = atan2(t1, t0);
00250 
00251   return ans;
00252 }
00253 
00254 
00255 EulerAngle Flight::toEulerAngle(QuaternionData quaternionData)
00256 {
00257   EulerAngle ans;
00258 
00259   double q2sqr = quaternionData.q2 * quaternionData.q2;
00260   double t0 = -2.0 * (q2sqr + quaternionData.q3 * quaternionData.q3) + 1.0;
00261   double t1 = +2.0 * (quaternionData.q1 * quaternionData.q2 + quaternionData.q0 * quaternionData.q3);
00262   double t2 = -2.0 * (quaternionData.q1 * quaternionData.q3 - quaternionData.q0 * quaternionData.q2);
00263   double t3 = +2.0 * (quaternionData.q2 * quaternionData.q3 + quaternionData.q0 * quaternionData.q1);
00264   double t4 = -2.0 * (quaternionData.q1 * quaternionData.q1 + q2sqr) + 1.0;
00265 
00266   t2 = t2 > 1.0 ? 1.0 : t2;
00267   t2 = t2 < -1.0 ? -1.0 : t2;
00268 
00269   ans.pitch = asin(t2);
00270   ans.roll = atan2(t3, t4);
00271   ans.yaw = atan2(t1, t0);
00272 
00273   return ans;
00274 }
00275 
00276 QuaternionData Flight::toQuaternion(EulerianAngle eulerAngleData)
00277 {
00278   QuaternionData ans;
00279   double t0 = cos(eulerAngleData.yaw * 0.5);
00280   double t1 = sin(eulerAngleData.yaw * 0.5);
00281   double t2 = cos(eulerAngleData.roll * 0.5);
00282   double t3 = sin(eulerAngleData.roll * 0.5);
00283   double t4 = cos(eulerAngleData.pitch * 0.5);
00284   double t5 = sin(eulerAngleData.pitch * 0.5);
00285 
00286   ans.q0 = t2 * t4 * t0 + t3 * t5 * t1;
00287   ans.q1 = t3 * t4 * t0 - t2 * t5 * t1;
00288   ans.q2 = t2 * t5 * t0 + t3 * t4 * t1;
00289   ans.q3 = t2 * t4 * t1 - t3 * t5 * t0;
00290   return ans;
00291 }


dji_sdk_lib
Author(s):
autogenerated on Thu Jun 6 2019 17:55:25