map_nav_srv.cpp
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_; //latitude_progress
00030 uint8_t lon_p_; //longitude_progress
00031 uint8_t alt_p_; //altitude_progress
00032 uint8_t idx_p_; //index_progress
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; //eliminate effect of last task
00047     Goal_t newGoal = *( asPtr_->acceptNewGoal() );
00048     ROS_INFO_STREAM( "Received goal: \n" << newGoal << "\n" );
00049 
00050     //********** stage code **********
00051     //*  0: waiting for waypointList
00052     //*  1: waiting for start
00053     //*  2: in progress
00054     //*  3: paused
00055     //*  4: canceled
00056     //********************************
00057 
00058     //check last task stage
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') { //"c" for cancel
00080             //cmdCode_ = 0; //eliminate effect of next task
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) { //"s" for start
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) { //"p" for pause
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) { //"r" for resume
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') { //"n" for newer waypointLine arrived
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         /*ROS_INFO_ONCE("Stage: %d", stage_);
00118         ROS_INFO_ONCE("CmdCode: %d", cmdCode_);
00119         ROS_INFO_ONCE("tid: %llu", tid_);*/
00120 
00121         bool isFinished; //flag for task result
00122         int cnt; //feedback count
00123         switch(stage_) {
00124             case 0: //"0" for waiting for waypointList
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: //"1" for waiting for start
00132             case 3: //"3" for paused
00133                 continue;
00134             case 2: //"2" for in progress
00135                 //wpClientPtr_->waitForServer();
00136                 drone->takeoff();
00137                 drone->waypoint_navigation_wait_server();
00138                 
00139                 //wpClientPtr_->sendGoal(wpGoal, 
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                 //wait 1200*0.25s=300s until the task finishes
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                         //cmdCode_ = 0; //eliminate effect of next task
00158                         rslt.result = false;
00159                         asPtr_->setAborted(rslt);
00160                         ROS_INFO("The task is canceled while executing.");
00161                         stage_ = 0;
00162                         tid_ = 0;
00163                         //wpClientPtr_->cancelGoal();
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: //"4" for canceled
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 //TODO: preemptCB
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 //TRUE for request control and FALSE for release control
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     //web_waypoint_receive action server
00223     asPtr_ = new SimpleActionServer<Action_t>(
00224         nh, 
00225         "dji_sdk_web_groundstation/web_waypoint_receive_action", 
00226         false
00227     );
00228 
00229     //command subscribers
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     //use multi thread to handle the subscribers.
00238     ros::MultiThreadedSpinner spinner(4);
00239     spinner.spin();
00240 
00241     return 0;
00242 }


dji_sdk_web_groundstation
Author(s):
autogenerated on Thu Jun 6 2019 17:55:48