dji_sdk_node_main.cpp
Go to the documentation of this file.
00001 
00013 #include <dji_sdk/dji_sdk_node.h>
00014 #include <functional>
00015 #include <dji_sdk/DJI_LIB_ROS_Adapter.h>
00016 //----------------------------------------------------------
00017 // timer spin_function 50Hz
00018 //----------------------------------------------------------
00019 
00020 void DJISDKNode::transparent_transmission_callback(uint8_t *buf, uint8_t len)
00021 {
00022         dji_sdk::TransparentTransmissionData transparent_transmission_data;
00023         transparent_transmission_data.data.resize(len);
00024         memcpy(&transparent_transmission_data.data[0], buf, len);
00025         data_received_from_remote_device_publisher.publish(transparent_transmission_data);
00026 
00027 }
00028 void DJISDKNode::broadcast_callback()
00029 {
00030     DJI::onboardSDK::BroadcastData bc_data = rosAdapter->coreAPI->getBroadcastData();
00031 
00032     DJI::onboardSDK::Version version = rosAdapter->coreAPI->getSDKVersion();
00033     unsigned short msg_flags = bc_data.dataFlag;
00034 
00035     static int frame_id = 0;
00036     frame_id ++;
00037    
00038     auto current_time = ros::Time::now();
00039 
00040     if(msg_flags & HAS_TIME){
00041         time_stamp.header.frame_id = "/time";
00042         time_stamp.header.stamp = current_time;
00043         time_stamp.time = bc_data.timeStamp.time;
00044         time_stamp.time_ns = bc_data.timeStamp.nanoTime;
00045         time_stamp.sync_flag = bc_data.timeStamp.syncFlag;
00046         time_stamp_publisher.publish(time_stamp);
00047     }
00048 
00049     //update attitude msg
00050     if ( (msg_flags & HAS_Q) && (msg_flags & HAS_W) ) {
00051         attitude_quaternion.header.frame_id = "/world";
00052         attitude_quaternion.header.stamp = current_time;
00053         attitude_quaternion.q0 = bc_data.q.q0;
00054         attitude_quaternion.q1 = bc_data.q.q1;
00055         attitude_quaternion.q2 = bc_data.q.q2;
00056         attitude_quaternion.q3 = bc_data.q.q3;
00057         attitude_quaternion.wx = bc_data.w.x;
00058         attitude_quaternion.wy = bc_data.w.y;
00059         attitude_quaternion.wz = bc_data.w.z;
00060         attitude_quaternion.ts = bc_data.timeStamp.time;
00061         attitude_quaternion_publisher.publish(attitude_quaternion);
00062     }
00063 
00064     //update global_position msg
00065     if (msg_flags & HAS_POS) {
00066         global_position.header.frame_id = "/world";
00067         global_position.header.stamp = current_time;
00068         global_position.ts = bc_data.timeStamp.time;
00069         global_position.latitude = bc_data.pos.latitude * 180.0 / C_PI;
00070         global_position.longitude = bc_data.pos.longitude * 180.0 / C_PI;
00071         global_position.height = bc_data.pos.height;
00072         global_position.altitude = bc_data.pos.altitude;
00073         global_position.health = bc_data.pos.health;
00074         global_position_publisher.publish(global_position);
00075 
00076         //TODO:
00077         // FIX BUG about flying at lat = 0
00078         if (global_position.ts != 0 && global_position_ref_seted == 0 && global_position.latitude != 0 && global_position.health > 3) {
00079             global_position_ref = global_position;
00080             global_position_ref_seted = 1;
00081         }
00082 
00083         //update local_position msg
00084         local_position.header.frame_id = "/world";
00085         local_position.header.stamp = current_time;
00086         gps_convert_ned(
00087                 local_position.x,
00088                 local_position.y,
00089                 global_position.longitude,
00090                 global_position.latitude,
00091                 global_position_ref.longitude,
00092                 global_position_ref.latitude
00093                 );
00094         local_position.z = global_position.height;
00095         local_position.ts = global_position.ts;
00096         local_position_ref = local_position;
00097         local_position_publisher.publish(local_position);
00098     }
00099 
00100 
00101     //update velocity msg
00102     if (msg_flags & HAS_V) {
00103         velocity.header.frame_id = "/world";
00104         velocity.header.stamp = current_time;
00105         velocity.ts = bc_data.timeStamp.time;
00106         velocity.vx = bc_data.v.x;
00107         velocity.vy = bc_data.v.y;
00108         velocity.vz = bc_data.v.z;
00109         velocity.health_flag = bc_data.v.health;
00110         velocity_publisher.publish(velocity);
00111     }
00112 
00113     //update acceleration msg
00114     if (msg_flags & HAS_A) {
00115         acceleration.header.frame_id = "/world";
00116         acceleration.header.stamp = current_time;
00117         acceleration.ts = bc_data.timeStamp.time;
00118         acceleration.ax = bc_data.a.x;
00119         acceleration.ay = bc_data.a.y;
00120         acceleration.az = bc_data.a.z;
00121         acceleration_publisher.publish(acceleration);
00122     }
00123     
00124 
00125     //update odom msg
00126     if ( (msg_flags & HAS_POS) && (msg_flags & HAS_Q) && (msg_flags & HAS_W) && (msg_flags & HAS_V) ) {
00127         odometry.header.frame_id = "/world";
00128         odometry.header.stamp = current_time;
00129         odometry.pose.pose.position.x = local_position.x;
00130         odometry.pose.pose.position.y = local_position.y;
00131         odometry.pose.pose.position.z = local_position.z;
00132         odometry.pose.pose.orientation.w = attitude_quaternion.q0;
00133         odometry.pose.pose.orientation.x = attitude_quaternion.q1;
00134         odometry.pose.pose.orientation.y = attitude_quaternion.q2;
00135         odometry.pose.pose.orientation.z = attitude_quaternion.q3;
00136         odometry.twist.twist.angular.x = attitude_quaternion.wx;
00137         odometry.twist.twist.angular.y = attitude_quaternion.wy;
00138         odometry.twist.twist.angular.z = attitude_quaternion.wz;
00139         odometry.twist.twist.linear.x = velocity.vx;
00140         odometry.twist.twist.linear.y = velocity.vy;
00141         odometry.twist.twist.linear.z = velocity.vz;
00142         odometry_publisher.publish(odometry);
00143     }
00144 
00145 /******************************************************************
00146 ****************************If using A3****************************
00147 ******************************************************************/
00148 
00149     if(version == DJI::onboardSDK::versionA3_31 || DJI::onboardSDK::versionA3_32) {
00150 
00151         //update gimbal msg
00152         if (msg_flags & A3_HAS_GIMBAL) {
00153                 gimbal.header.frame_id = "/gimbal";
00154                 gimbal.header.stamp= current_time;
00155                 gimbal.ts = bc_data.timeStamp.time;
00156                 gimbal.roll = bc_data.gimbal.roll;
00157                 gimbal.pitch = bc_data.gimbal.pitch;
00158                 gimbal.yaw = bc_data.gimbal.yaw;
00159                 gimbal_publisher.publish(gimbal);
00160         }
00161 
00162          //update rc_channel msg
00163         if (msg_flags & A3_HAS_RC) {
00164                 rc_channels.header.frame_id = "/rc";
00165                 rc_channels.header.stamp = current_time;
00166                 rc_channels.ts = bc_data.timeStamp.time;
00167                 rc_channels.pitch = bc_data.rc.pitch;
00168                 rc_channels.roll = bc_data.rc.roll;
00169                 rc_channels.mode = bc_data.rc.mode;
00170                 rc_channels.gear = bc_data.rc.gear;
00171                 rc_channels.throttle = bc_data.rc.throttle;
00172                 rc_channels.yaw = bc_data.rc.yaw;
00173                 rc_channels_publisher.publish(rc_channels);
00174         }
00175 
00176 
00177         if (msg_flags & A3_HAS_GPS){
00178                 A3_GPS.date = bc_data.gps.date;
00179                 A3_GPS.time = bc_data.gps.time;
00180                 A3_GPS.longitude = bc_data.gps.longitude;
00181                 A3_GPS.latitude = bc_data.gps.latitude;
00182                 A3_GPS.height_above_sea = bc_data.gps.Hmsl;
00183                 A3_GPS.velocity_north = bc_data.gps.velocityNorth;
00184                 A3_GPS.velocity_east= bc_data.gps.velocityEast;
00185                 A3_GPS.velocity_ground = bc_data.gps.velocityGround;
00186                 A3_GPS_info_publisher.publish(A3_GPS);
00187         }
00188         if (msg_flags & A3_HAS_RTK)
00189                 A3_RTK.date = bc_data.rtk.date;
00190                 A3_RTK.time = bc_data.rtk.time;
00191                 A3_RTK.longitude_RTK = bc_data.rtk.longitude;
00192                 A3_RTK.latitude_RTK = bc_data.rtk.latitude;
00193                 A3_RTK.height_above_sea_RTK = bc_data.rtk.Hmsl;
00194                 A3_RTK.velocity_north = bc_data.rtk.velocityNorth;
00195                 A3_RTK.velocity_east = bc_data.rtk.velocityEast;
00196                 A3_RTK.velocity_ground = bc_data.rtk.velocityGround;
00197                 A3_RTK.yaw = bc_data.rtk.yaw;
00198                 A3_RTK.position_flag = bc_data.rtk.posFlag;
00199                 A3_RTK.yaw_flag = bc_data.rtk.yawFlag;
00200                 A3_RTK_info_publisher.publish(A3_RTK);
00201 
00202         //update compass msg
00203         if (msg_flags & A3_HAS_MAG) {
00204                 compass.header.frame_id = "/world";
00205                 compass.header.stamp = current_time;
00206                 compass.ts = bc_data.timeStamp.time;
00207                 compass.x = bc_data.mag.x;
00208                 compass.y = bc_data.mag.y;
00209                 compass.z = bc_data.mag.z;
00210                 compass_publisher.publish(compass);
00211         }
00212 
00213         //update flight_status
00214         if (msg_flags & A3_HAS_STATUS) {
00215                 std_msgs::UInt8 msg;
00216                 flight_status = bc_data.status;
00217                 msg.data = flight_status;
00218                 flight_status_publisher.publish(msg);
00219         }
00220 
00221         //update battery msg
00222         if (msg_flags & A3_HAS_BATTERY) {
00223                 power_status.percentage = bc_data.battery;
00224                 power_status_publisher.publish(power_status);
00225         }
00226 
00227         //update flight control info
00228         if (msg_flags & A3_HAS_DEVICE) {
00229                 flight_control_info.control_mode = bc_data.ctrlInfo.mode;
00230                 flight_control_info.cur_ctrl_dev_in_navi_mode = bc_data.ctrlInfo.deviceStatus;
00231                 flight_control_info.serial_req_status = bc_data.ctrlInfo.flightStatus;
00232                 flight_control_info.virtual_rc_status = bc_data.ctrlInfo.vrcStatus;
00233                 flight_control_info_publisher.publish(flight_control_info);
00234         }
00235 
00236     }
00237 
00238 /******************************************************************
00239 ***************************If using M100***************************
00240 ******************************************************************/
00241 
00242     else {
00243 
00244         if (msg_flags & HAS_GIMBAL) {
00245                 gimbal.header.frame_id = "/gimbal";
00246                 gimbal.header.stamp= current_time;
00247                 gimbal.ts = bc_data.timeStamp.time;
00248                 gimbal.roll = bc_data.gimbal.roll;
00249                 gimbal.pitch = bc_data.gimbal.pitch;
00250                 gimbal.yaw = bc_data.gimbal.yaw;
00251                 gimbal_publisher.publish(gimbal);
00252         }
00253 
00254         //update rc_channel msg
00255         if (msg_flags & HAS_RC) {
00256                 rc_channels.header.frame_id = "/rc";
00257                 rc_channels.header.stamp = current_time;
00258                 rc_channels.ts = bc_data.timeStamp.time;
00259                 rc_channels.pitch = bc_data.rc.pitch;
00260                 rc_channels.roll = bc_data.rc.roll;
00261                 rc_channels.mode = bc_data.rc.mode;
00262                 rc_channels.gear = bc_data.rc.gear;
00263                 rc_channels.throttle = bc_data.rc.throttle;
00264                 rc_channels.yaw = bc_data.rc.yaw;
00265                 rc_channels_publisher.publish(rc_channels);
00266         }
00267 
00268 
00269 
00270         //update compass msg
00271         if (msg_flags & HAS_MAG) {
00272                 compass.header.frame_id = "/world";
00273                 compass.header.stamp = current_time;
00274                 compass.ts = bc_data.timeStamp.time;
00275                 compass.x = bc_data.mag.x;
00276                 compass.y = bc_data.mag.y;
00277                 compass.z = bc_data.mag.z;
00278                 compass_publisher.publish(compass);
00279         }       
00280 
00281         //update flight_status
00282         if (msg_flags & HAS_STATUS) {
00283                 std_msgs::UInt8 msg;
00284                 flight_status = bc_data.status;
00285                 msg.data = flight_status;
00286                 flight_status_publisher.publish(msg);
00287         }
00288 
00289         //update battery msg
00290         if (msg_flags & HAS_BATTERY) {
00291                 power_status.percentage = bc_data.battery;
00292                 power_status_publisher.publish(power_status);
00293         }
00294 
00295         //update flight control info
00296         if (msg_flags & HAS_DEVICE) {
00297                 flight_control_info.control_mode = bc_data.ctrlInfo.mode;
00298                 flight_control_info.cur_ctrl_dev_in_navi_mode = bc_data.ctrlInfo.deviceStatus;
00299                 flight_control_info.serial_req_status = bc_data.ctrlInfo.flightStatus;
00300                 flight_control_info.virtual_rc_status = bc_data.ctrlInfo.vrcStatus;
00301                 flight_control_info_publisher.publish(flight_control_info);
00302         }
00303 
00304     }
00305 
00306 
00307 
00308     //update obtaincontrol msg
00309         std_msgs::UInt8 msg;
00310         activation_result = bc_data.activation;
00311         msg.data = bc_data.activation;
00312         activation_publisher.publish(msg);
00313 
00314 }
00315 
00316 
00317 
00318 int DJISDKNode::init_parameters(ros::NodeHandle& nh_private)
00319 {
00320     std::string drone_version;
00321     std::string serial_name;
00322     int baud_rate;
00323     int app_id;
00324     int app_version;
00325     std::string app_bundle_id; //reserved
00326     std::string enc_key;
00327     int uart_or_usb;
00328     
00329 
00330     nh_private.param("serial_name", serial_name, std::string("/dev/ttyTHS1"));
00331     nh_private.param("baud_rate", baud_rate, 230400);
00332     nh_private.param("app_id", app_id, 1022384);
00333     nh_private.param("app_version", app_version, 1);
00334     nh_private.param("enc_key", enc_key,
00335             std::string("e7bad64696529559318bb35d0a8c6050d3b88e791e1808cfe8f7802150ee6f0d"));
00336 
00337     nh_private.param("uart_or_usb", uart_or_usb, 0);//chosse uart as default
00338     nh_private.param("drone_version", drone_version, std::string("M100"));//chosse M100 as default
00339 
00340     // activation
00341     user_act_data.ID = app_id;
00342 
00343     if((uart_or_usb)&&(drone_version.compare("M100")))
00344     {
00345         printf("M100 does not support USB API.\n");
00346         return -1;
00347     }
00348 
00349     if(!drone_version.compare("M100"))
00350     {
00351         user_act_data.version = versionM100_31;
00352     }
00353     else if (!drone_version.compare("A3_31"))
00354     {
00355         user_act_data.version = versionA3_31;
00356     }
00357     else if (!drone_version.compare("A3_32"))
00358     {
00359       user_act_data.version = versionA3_32;
00360     }
00361     user_act_data.encKey = app_key;
00362     strcpy(user_act_data.encKey, enc_key.c_str());
00363 
00364     printf("=================================================\n");
00365     printf("app id: %d\n", user_act_data.ID);
00366     printf("app version: 0x0%X\n", user_act_data.version);
00367     printf("app key: %s\n", user_act_data.encKey);
00368     printf("=================================================\n");
00369 
00370     if(uart_or_usb) //use usb port for SDK
00371     {
00372         rosAdapter->usbHandshake(serial_name);
00373     }
00374 
00375     rosAdapter->init(serial_name, baud_rate);
00376     rosAdapter->activate(&user_act_data, NULL);
00377     rosAdapter->setBroadcastCallback(&DJISDKNode::broadcast_callback, this);
00378     rosAdapter->setFromMobileCallback(&DJISDKNode::transparent_transmission_callback,this);
00379    
00380     return 0;
00381 }
00382 
00383 
00384 
00385 DJISDKNode::DJISDKNode(ros::NodeHandle& nh, ros::NodeHandle& nh_private) : dji_sdk_mission(nullptr)
00386 {
00387 
00388     init_publishers(nh);
00389     init_services(nh);
00390     init_actions(nh);
00391 
00392 
00393     init_parameters(nh_private);
00394 
00395     int groundstation_enable;
00396     nh_private.param("groundstation_enable", groundstation_enable, 1);
00397     if(groundstation_enable)
00398     {
00399         dji_sdk_mission = new DJISDKMission(nh);
00400     }
00401 
00402 }
00403 
00404 
00405 void DJISDKNode::gps_convert_ned(float &ned_x, float &ned_y,
00406                 double gps_t_lon, double gps_t_lat,
00407                 double gps_r_lon, double gps_r_lat)
00408 {
00409         double d_lon = gps_t_lon - gps_r_lon;
00410         double d_lat = gps_t_lat - gps_r_lat;
00411         ned_x = DEG2RAD(d_lat) * C_EARTH;
00412         ned_y = DEG2RAD(d_lon) * C_EARTH * cos(DEG2RAD(gps_t_lat));
00413 };
00414 
00415 dji_sdk::LocalPosition DJISDKNode::gps_convert_ned(dji_sdk::GlobalPosition loc)
00416 {
00417     dji_sdk::LocalPosition local;
00418     gps_convert_ned(local.x, local.y,
00419         loc.longitude, loc.latitude,
00420         global_position_ref.longitude, global_position_ref.latitude
00421     );
00422     local.z = loc.height;
00423     return local;
00424 }
00425 


dji_sdk
Author(s): Botao Hu
autogenerated on Thu Jun 6 2019 17:55:29