Go to the documentation of this file.00001 #include <ros/ros.h>
00002 #include <actionlib/server/simple_action_server.h>
00003 #include <actionlib/client/simple_action_client.h>
00004 #include <std_msgs/Bool.h>
00005 #include <dji_sdk/dji_drone.h>
00006 #include <dji_sdk_web_groundstation/WebWaypointReceiveAction.h>
00007 #include <dji_sdk_web_groundstation/MapNavSrvCmd.h>
00008 #include <dji_sdk/WaypointNavigationAction.h>
00009
00010 using namespace actionlib;
00011
00012 typedef dji_sdk_web_groundstation::WebWaypointReceiveAction Action_t;
00013 typedef dji_sdk_web_groundstation::WebWaypointReceiveGoal Goal_t;
00014 typedef dji_sdk_web_groundstation::WebWaypointReceiveGoalConstPtr GoalConstPtr_t;
00015 typedef dji_sdk_web_groundstation::WebWaypointReceiveFeedback Feedback_t;
00016 typedef dji_sdk_web_groundstation::WebWaypointReceiveResult Result_t;
00017
00018 typedef dji_sdk::WaypointNavigationAction WPAction_t;
00019
00020 SimpleActionServer<Action_t>* asPtr_;
00021
00022 DJIDrone* drone;
00023
00024 uint8_t cmdCode_ = 0;
00025 uint8_t stage_ = 0;
00026 uint64_t tid_ = 0;
00027 uint64_t cmdTid_ = 1;
00028
00029 uint8_t lat_p_;
00030 uint8_t lon_p_;
00031 uint8_t alt_p_;
00032 uint8_t idx_p_;
00033
00034
00035 void wp_feedbackCB(const dji_sdk::WaypointNavigationFeedbackConstPtr& fb) {
00036 lat_p_ = fb->latitude_progress;
00037 lon_p_ = fb->longitude_progress;
00038 alt_p_ = fb->altitude_progress;
00039 idx_p_ = fb->index_progress;
00040 }
00041
00042 void goalCB() {
00043 Feedback_t fb;
00044 Result_t rslt;
00045
00046 cmdCode_ = 0;
00047 Goal_t newGoal = *( asPtr_->acceptNewGoal() );
00048 ROS_INFO_STREAM( "Received goal: \n" << newGoal << "\n" );
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 if(stage_ == 2) {
00060 rslt.result = false;
00061 asPtr_->setAborted(rslt, "Last task is in progress!");
00062 stage_ = 0;
00063 tid_ = 0;
00064 return;
00065 }
00066 if(stage_ == 3) {
00067 rslt.result = false;
00068 asPtr_->setAborted(rslt, "Last task is paused!");
00069 stage_ = 0;
00070 tid_ = 0;
00071 return;
00072 }
00073
00074 tid_ = newGoal.tid;
00075 dji_sdk::WaypointList wpl = newGoal.waypoint_list;
00076 stage_ = 1;
00077
00078 while(ros::ok()) {
00079 if(cmdCode_ == 'c') {
00080
00081 ROS_INFO("Cancel task with tid %llu", tid_);
00082 stage_ = 4;
00083 fb.stage = stage_;
00084 asPtr_->publishFeedback(fb);
00085 } else if(tid_ == cmdTid_){
00086 if(cmdCode_ == 's' && stage_ == 1) {
00087 ROS_INFO("Start task with tid %llu", tid_);
00088 stage_ = 2;
00089 fb.stage = stage_;
00090 asPtr_->publishFeedback(fb);
00091 continue;
00092 }
00093 if(cmdCode_ == 'p' && stage_ == 2) {
00094 ROS_INFO("Pause task with tid %llu", tid_);
00095 stage_ = 3;
00096 fb.stage = stage_;
00097 asPtr_->publishFeedback(fb);
00098 continue;
00099 }
00100 if(cmdCode_ == 'r' && stage_ == 3) {
00101 ROS_INFO("Resume task with tid %llu", tid_);
00102 stage_ = 2;
00103 fb.stage = stage_;
00104 asPtr_->publishFeedback(fb);
00105 continue;
00106 }
00107 } else {
00108 if(cmdCode_ == 'n') {
00109 ROS_INFO("A latest task arrived.");
00110 ROS_INFO("Set task(if any) with tid %llu preemted", newGoal.tid);
00111 stage_ = 4;
00112 fb.stage = stage_;
00113 asPtr_->publishFeedback(fb);
00114 }
00115 }
00116
00117
00118
00119
00120
00121 bool isFinished;
00122 int cnt;
00123 switch(stage_) {
00124 case 0:
00125 rslt.result = false;
00126 asPtr_->setAborted(rslt);
00127 ROS_INFO("The task is aborted for no waypointList received.");
00128 stage_ = 0;
00129 tid_ = 0;
00130 return;
00131 case 1:
00132 case 3:
00133 continue;
00134 case 2:
00135
00136 drone->takeoff();
00137 drone->waypoint_navigation_wait_server();
00138
00139
00140 drone->waypoint_navigation_send_request(wpl,
00141 SimpleActionClient<WPAction_t>::SimpleDoneCallback(),
00142 SimpleActionClient<WPAction_t>::SimpleActiveCallback(),
00143 &wp_feedbackCB
00144 );
00145 ROS_DEBUG("[DEBUG] The goal is sent!");
00146
00147
00148 cnt = 1200;
00149 while(ros::ok() && cnt--) {
00150 fb.latitude_progress = lat_p_;
00151 fb.longitude_progress = lon_p_;
00152 fb.altitude_progress = alt_p_;
00153 fb.index_progress = idx_p_;
00154 asPtr_->publishFeedback(fb);
00155 ROS_DEBUG_COND(cnt==1199, "[DEBUG] cmdCode_: %c", cmdCode_);
00156 if(cmdCode_ == 'c') {
00157
00158 rslt.result = false;
00159 asPtr_->setAborted(rslt);
00160 ROS_INFO("The task is canceled while executing.");
00161 stage_ = 0;
00162 tid_ = 0;
00163
00164 drone->waypoint_navigation_cancel_current_goal();
00165 return;
00166 }
00167 isFinished = drone->waypoint_navigation_wait_for_result();
00168 }
00169 if(isFinished) {
00170 ROS_INFO("Action finished: %s",
00171 drone->waypoint_navigation_get_state().toString().c_str()
00172 );
00173 rslt.result = true;
00174 asPtr_->setSucceeded(rslt);
00175 } else {
00176 ROS_INFO("The task cannot finish before the time out.");
00177 rslt.result = false;
00178 asPtr_->setAborted(rslt);
00179 }
00180 stage_ = 0;
00181 tid_ = 0;
00182 return;
00183 case 4:
00184 ROS_INFO("The task is canceled.");
00185 stage_ = 0;
00186 tid_ = 0;
00187 rslt.result = false;
00188 asPtr_->setPreempted(rslt);
00189 drone->waypoint_navigation_cancel_all_goals();
00190 return;
00191 }
00192 }
00193 }
00194
00195
00196 void preemptCB() {
00197 ROS_INFO("Hey! I got preempt!");
00198 }
00199
00200 void cmdCB(const dji_sdk_web_groundstation::MapNavSrvCmdConstPtr& msg) {
00201 ROS_INFO("Received command \"%c\" of tid %llu", msg->cmdCode, msg->tid);
00202 cmdCode_ = msg->cmdCode;
00203 cmdTid_ = msg->tid;
00204 }
00205
00206
00207 void ctrlCB(const std_msgs::Bool::ConstPtr& msg) {
00208 if(msg->data)
00209 ROS_INFO("Request to obtain control");
00210 else
00211 ROS_INFO("Release control");
00212
00213 drone->sdk_permission_control(msg->data);
00214
00215 }
00216
00217 int main(int argc, char* argv[]) {
00218 ros::init(argc, argv, "map_nav_srv");
00219 ros::NodeHandle nh;
00220 drone = new DJIDrone(nh);
00221
00222
00223 asPtr_ = new SimpleActionServer<Action_t>(
00224 nh,
00225 "dji_sdk_web_groundstation/web_waypoint_receive_action",
00226 false
00227 );
00228
00229
00230 ros::Subscriber sub1 = nh.subscribe("dji_sdk_web_groundstation/map_nav_srv/cmd", 1, cmdCB);
00231 ros::Subscriber sub2 = nh.subscribe("dji_sdk_web_groundstation/map_nav_srv/ctrl", 1, ctrlCB);
00232
00233 asPtr_->registerGoalCallback(&goalCB);
00234 asPtr_->registerPreemptCallback(&preemptCB);
00235 asPtr_->start();
00236
00237
00238 ros::MultiThreadedSpinner spinner(4);
00239 spinner.spin();
00240
00241 return 0;
00242 }