00001 00013 #include <dji_sdk/dji_sdk_node.h> 00014 #include <algorithm> 00015 00016 bool DJISDKNode::process_waypoint(dji_sdk::Waypoint new_waypoint) 00017 { 00018 double dst_latitude = new_waypoint.latitude; 00019 double dst_longitude = new_waypoint.longitude; 00020 float dst_altitude = new_waypoint.altitude; 00021 00022 double org_latitude = global_position.latitude; 00023 double org_longitude = global_position.longitude; 00024 float org_altitude = global_position.altitude; 00025 00026 double dis_x, dis_y; 00027 float dis_z; 00028 00029 dis_x = dst_latitude - org_latitude; 00030 dis_y = dst_longitude - org_longitude; 00031 dis_z = dst_altitude - org_altitude; 00032 00033 double det_x,det_y; 00034 float det_z; 00035 00036 00037 DJI::onboardSDK::FlightData flight_ctrl_data; 00038 flight_ctrl_data.flag = 0x90; 00039 flight_ctrl_data.z = dst_altitude; 00040 flight_ctrl_data.yaw = new_waypoint.heading; 00041 00042 00043 int latitude_progress = 0; 00044 int longitude_progress = 0; 00045 int altitude_progress = 0; 00046 00047 while (latitude_progress < 100 || longitude_progress < 100 || altitude_progress <100) { 00048 if(waypoint_navigation_action_server->isPreemptRequested()) { 00049 return false; 00050 } 00051 00052 double d_lon = dst_longitude - global_position.longitude; 00053 double d_lat = dst_latitude - global_position.latitude; 00054 00055 flight_ctrl_data.x = ((d_lat) *C_PI/180) * C_EARTH; 00056 flight_ctrl_data.y = ((d_lon) * C_PI/180) * C_EARTH * cos((dst_latitude)*C_PI/180); 00057 rosAdapter->flight->setFlight(&flight_ctrl_data); 00058 00059 det_x = (100 * (dst_latitude - global_position.latitude))/dis_x; 00060 det_y = (100 * (dst_longitude - global_position.longitude))/dis_y; 00061 det_z = (100 * (dst_altitude - global_position.altitude))/dis_z; 00062 00063 latitude_progress = 100 - std::abs((int) det_x); 00064 longitude_progress = 100 - std::abs((int) det_y); 00065 altitude_progress = 100 - std::abs((int) det_z); 00066 00067 //lazy evaluation 00068 //need to find a better way 00069 if (std::abs(dst_latitude - global_position.latitude) < 0.00001) latitude_progress = 100; 00070 if (std::abs(dst_longitude - global_position.longitude) < 0.00001) longitude_progress = 100; 00071 if (std::abs(dst_altitude - global_position.altitude) < 0.12) altitude_progress = 100; 00072 00073 waypoint_navigation_feedback.latitude_progress = latitude_progress; 00074 waypoint_navigation_feedback.longitude_progress = longitude_progress; 00075 waypoint_navigation_feedback.altitude_progress = altitude_progress; 00076 waypoint_navigation_action_server->publishFeedback(waypoint_navigation_feedback); 00077 00078 usleep(20000); 00079 00080 } 00081 ros::Duration(new_waypoint.staytime).sleep(); 00082 return true; 00083 } 00084 00085 00086 bool DJISDKNode::drone_task_action_callback(const dji_sdk::DroneTaskGoalConstPtr& goal) 00087 { 00088 uint8_t request_action = goal->task; 00089 00090 if (request_action == 1) 00091 { 00092 //takeoff 00093 rosAdapter->flight->task(DJI::onboardSDK::Flight::TASK::TASK_TAKEOFF); 00094 } 00095 else if (request_action == 2) 00096 { 00097 //landing 00098 rosAdapter->flight->task(DJI::onboardSDK::Flight::TASK::TASK_LANDING); 00099 } 00100 else if (request_action == 3) 00101 { 00102 //gohome 00103 rosAdapter->flight->task(DJI::onboardSDK::Flight::TASK::TASK_GOHOME); 00104 } 00105 00106 drone_task_feedback.progress = 1; 00107 drone_task_action_server->publishFeedback(drone_task_feedback); 00108 drone_task_action_server->setSucceeded(); 00109 00110 return true; 00111 } 00112 00113 00114 bool DJISDKNode::local_position_navigation_action_callback(const dji_sdk::LocalPositionNavigationGoalConstPtr& goal) 00115 { 00116 /*IMPORTANT*/ 00117 /* 00118 There has been declared a pointer `local_navigation_action` as the function parameter, 00119 However, it is the `local_navigation_action_server` that we should use. 00120 If `local_navigation_action` is used instead, there will be a runtime sengmentation fault. 00121 00122 so interesting 00123 */ 00124 00125 float dst_x = goal->x; 00126 float dst_y = goal->y; 00127 float dst_z = goal->z; 00128 00129 float org_x = local_position.x; 00130 float org_y = local_position.y; 00131 float org_z = local_position.z; 00132 00133 float dis_x = dst_x - org_x; 00134 float dis_y = dst_y - org_y; 00135 float dis_z = dst_z - org_z; 00136 00137 float det_x, det_y, det_z; 00138 00139 DJI::onboardSDK::FlightData flight_ctrl_data; 00140 flight_ctrl_data.flag = 0x90; 00141 flight_ctrl_data.z = dst_z; 00142 flight_ctrl_data.yaw = 0; 00143 00144 int x_progress = 0; 00145 int y_progress = 0; 00146 int z_progress = 0; 00147 while (x_progress < 100 || y_progress < 100 || z_progress <100) { 00148 00149 flight_ctrl_data.x = dst_x - local_position.x; 00150 flight_ctrl_data.y = dst_y - local_position.y; 00151 rosAdapter->flight->setFlight(&flight_ctrl_data); 00152 00153 det_x = (100 * (dst_x - local_position.x)) / dis_x; 00154 det_y = (100 * (dst_y - local_position.y)) / dis_y; 00155 det_z = (100 * (dst_z - local_position.z)) / dis_z; 00156 00157 x_progress = 100 - (int)det_x; 00158 y_progress = 100 - (int)det_y; 00159 z_progress = 100 - (int)det_z; 00160 00161 //lazy evaluation 00162 if (std::abs(dst_x - local_position.x) < 0.1) x_progress = 100; 00163 if (std::abs(dst_y - local_position.y) < 0.1) y_progress = 100; 00164 if (std::abs(dst_z - local_position.z) < 0.1) z_progress = 100; 00165 00166 local_position_navigation_feedback.x_progress = x_progress; 00167 local_position_navigation_feedback.y_progress = y_progress; 00168 local_position_navigation_feedback.z_progress = z_progress; 00169 local_position_navigation_action_server->publishFeedback(local_position_navigation_feedback); 00170 00171 usleep(20000); 00172 } 00173 00174 local_position_navigation_result.result = true; 00175 local_position_navigation_action_server->setSucceeded(local_position_navigation_result); 00176 00177 return true; 00178 } 00179 00180 00181 bool DJISDKNode::global_position_navigation_action_callback(const dji_sdk::GlobalPositionNavigationGoalConstPtr& goal) 00182 { 00183 double dst_latitude = goal->latitude; 00184 double dst_longitude = goal->longitude; 00185 float dst_altitude = goal->altitude; 00186 00187 double org_latitude = global_position.latitude; 00188 double org_longitude = global_position.longitude; 00189 float org_altitude = global_position.altitude; 00190 00191 double dis_x, dis_y; 00192 float dis_z; 00193 00194 dis_x = dst_latitude - org_latitude; 00195 dis_y = dst_longitude - org_longitude; 00196 dis_z = dst_altitude - org_altitude; 00197 00198 double det_x, det_y; 00199 float det_z; 00200 00201 DJI::onboardSDK::FlightData flight_ctrl_data; 00202 flight_ctrl_data.flag = 0x90; 00203 flight_ctrl_data.z = dst_altitude; 00204 flight_ctrl_data.yaw = 0; 00205 00206 00207 int latitude_progress = 0; 00208 int longitude_progress = 0; 00209 int altitude_progress = 0; 00210 00211 while (latitude_progress < 100 || longitude_progress < 100 || altitude_progress < 100) { 00212 00213 double d_lon = dst_longitude - global_position.longitude; 00214 double d_lat = dst_latitude - global_position.latitude; 00215 00216 flight_ctrl_data.x = ((d_lat) *C_PI/180) * C_EARTH; 00217 flight_ctrl_data.y = ((d_lon) * C_PI/180) * C_EARTH * cos((dst_latitude)*C_PI/180); 00218 rosAdapter->flight->setFlight(&flight_ctrl_data); 00219 00220 det_x = (100* (dst_latitude - global_position.latitude))/dis_x; 00221 det_y = (100* (dst_longitude - global_position.longitude))/dis_y; 00222 det_z = (100* (dst_altitude - global_position.altitude))/dis_z; 00223 00224 00225 latitude_progress = 100 - (int)det_x; 00226 longitude_progress = 100 - (int)det_y; 00227 altitude_progress = 100 - (int)det_z; 00228 00229 //lazy evaluation 00230 if (std::abs(dst_latitude - global_position.latitude) < 0.00001) latitude_progress = 100; 00231 if (std::abs(dst_longitude - global_position.longitude) < 0.00001) longitude_progress = 100; 00232 if (std::abs(dst_altitude - global_position.altitude) < 0.12) altitude_progress = 100; 00233 00234 00235 global_position_navigation_feedback.latitude_progress = latitude_progress; 00236 global_position_navigation_feedback.longitude_progress = longitude_progress; 00237 global_position_navigation_feedback.altitude_progress = altitude_progress; 00238 global_position_navigation_action_server->publishFeedback(global_position_navigation_feedback); 00239 00240 usleep(20000); 00241 00242 } 00243 00244 global_position_navigation_result.result = true; 00245 global_position_navigation_action_server->setSucceeded(global_position_navigation_result); 00246 00247 return true; 00248 } 00249 00250 00251 bool DJISDKNode::waypoint_navigation_action_callback(const dji_sdk::WaypointNavigationGoalConstPtr& goal) 00252 { 00253 dji_sdk::WaypointList new_waypoint_list; 00254 new_waypoint_list = goal->waypoint_list; 00255 00256 bool isSucceeded; 00257 for (int i = 0; i < new_waypoint_list.waypoint_list.size(); i++) { 00258 const dji_sdk::Waypoint new_waypoint = new_waypoint_list.waypoint_list[i]; 00259 waypoint_navigation_feedback.index_progress = i; 00260 isSucceeded = process_waypoint(new_waypoint); 00261 if(!isSucceeded) { 00262 waypoint_navigation_result.result = false; 00263 waypoint_navigation_action_server->setPreempted(waypoint_navigation_result); 00264 return false; 00265 } 00266 } 00267 00268 waypoint_navigation_result.result = true; 00269 waypoint_navigation_action_server->setSucceeded(waypoint_navigation_result); 00270 00271 return true; 00272 } 00273