RosThread.cpp
Go to the documentation of this file.
00001 
00022 #include "RosThread.h"
00023 #include <unistd.h>
00024 #include "cvd/thread.h"
00025 #include "ros/ros.h"
00026 #include "ros/callback_queue.h"
00027 #include "uga_tum_ardrone_gui.h"
00028 #include "stdio.h"
00029 #include "std_msgs/Empty.h"
00030 
00031 
00032 pthread_mutex_t RosThread::send_CS = PTHREAD_MUTEX_INITIALIZER;
00033 RosThread::RosThread()
00034 {
00035         gui = NULL;
00036         navdataCount = velCount = dronePoseCount = joyCount = velCount100ms = 0;
00037         keepRunning = true;
00038         lastJoyControlSent = ControlCommand(0,0,0,0);
00039         lastL1Pressed = lastR1Pressed = false;
00040 }
00041 
00042 RosThread::~RosThread(void)
00043 {
00044 
00045 
00046 }
00047 
00048 void RosThread::startSystem()
00049 {
00050         keepRunning = true;
00051         start();
00052 }
00053 
00054 void RosThread::stopSystem()
00055 {
00056         keepRunning = false;
00057         join();
00058 }
00059 
00060 void RosThread::landCb(std_msgs::EmptyConstPtr)
00061 {
00062         gui->addLogLine("sent: LAND");
00063 }
00064 void RosThread::toggleStateCb(std_msgs::EmptyConstPtr)
00065 {
00066         gui->addLogLine("sent: ToggleState");
00067 }
00068 void RosThread::takeoffCb(std_msgs::EmptyConstPtr)
00069 {
00070         gui->addLogLine("sent: Takeoff");
00071 }
00072 
00073 void RosThread::droneposeCb(const uga_tum_ardrone::filter_stateConstPtr statePtr)
00074 {
00075         dronePoseCount++;
00076 }
00077 void RosThread::velCb(const geometry_msgs::TwistConstPtr vel)
00078 {
00079     velCount++;
00080     velCount100ms++;
00081 }
00082 void RosThread::navdataCb(const ardrone_autonomy::NavdataConstPtr navdataPtr)
00083 {
00084     this->drone_state = navdataPtr->state;
00085 
00086         if(navdataCount%10==0)
00087         {
00088                 char buf[200];
00089                 snprintf(buf,200,"Motors: %f %f %f %f",
00090                                 (float)navdataPtr->motor1,
00091                                 (float)navdataPtr->motor2,
00092                                 (float)navdataPtr->motor3,
00093                                 (float)navdataPtr->motor4);
00094                 gui->setMotorSpeeds(std::string(buf));
00095         }
00096         navdataCount++;
00097 }
00098 
00099 void RosThread::joyCb(const sensor_msgs::JoyConstPtr joy_msg)
00100 {
00101     joyCount++;
00102 
00103     if (joy_msg->axes.size() < 4) {
00104         ROS_WARN_ONCE("Error: Non-compatible Joystick!");
00105         return;
00106     }
00107 
00108     // Avoid crashes if non-ps3 joystick is being used
00109     short unsigned int actiavte_index = (joy_msg->buttons.size() > 11) ? 11 : 1;
00110 
00111         // if not controlling: start controlling if sth. is pressed (!)
00112     bool justStartedControlling = false;
00113         if(gui->currentControlSource != CONTROL_JOY)
00114         {
00115                 if(             joy_msg->axes[0] > 0.1 ||  joy_msg->axes[0] < -0.1 ||
00116                                 joy_msg->axes[1] > 0.1 ||  joy_msg->axes[1] < -0.1 ||
00117                                 joy_msg->axes[2] > 0.1 ||  joy_msg->axes[2] < -0.1 ||
00118                                 joy_msg->axes[3] > 0.1 ||  joy_msg->axes[3] < -0.1 ||
00119                 joy_msg->buttons.at(actiavte_index))
00120                 {
00121                         gui->setControlSource(CONTROL_JOY);
00122                         justStartedControlling = true;
00123                 }
00124         }
00125 
00126         // are we actually controlling with the Joystick?
00127         if(justStartedControlling || gui->currentControlSource == CONTROL_JOY)
00128         {
00129                 ControlCommand c;
00130                 c.yaw = -joy_msg->axes[2];
00131                 c.gaz = joy_msg->axes[3];
00132                 c.roll = -joy_msg->axes[0];
00133                 c.pitch = -joy_msg->axes[1];
00134 
00135                 sendControlToDrone(c);
00136                 lastJoyControlSent = c;
00137 
00138         if(!lastL1Pressed && joy_msg->buttons.at(actiavte_index - 1))
00139                         sendTakeoff();
00140         if(lastL1Pressed && !joy_msg->buttons.at(actiavte_index - 1))
00141                         sendLand();
00142 
00143         if(!lastR1Pressed && joy_msg->buttons.at(actiavte_index))
00144                         sendToggleState();
00145 
00146         }
00147     lastL1Pressed =joy_msg->buttons.at(actiavte_index - 1);
00148     lastR1Pressed = joy_msg->buttons.at(actiavte_index);
00149 }
00150 
00151 
00152 void RosThread::comCb(const std_msgs::StringConstPtr str)
00153 {
00154         if(str->data.substr(0,2) == "u ")
00155         {
00156                 if(str->data.substr(0,4) == "u l ")
00157                         gui->addLogLine(str->data.substr(4,str->data.length()-4));
00158 
00159                 else if(str->data.substr(0,4) == "u c ")
00160                         gui->setAutopilotInfo(str->data.substr(4,str->data.length()-4));
00161 
00162                 else if(str->data.substr(0,4) == "u s ")
00163                         gui->setStateestimationInfo(str->data.substr(4,str->data.length()-4));
00164         }
00165 }
00166 
00167 void RosThread::sendResetMsg() {
00168     pub_reset.publish(emp_msg);
00169 }
00170 
00171 void RosThread::run()
00172 {
00173         std::cout << "Starting ROS Thread" << std::endl;
00174 
00175     vel_pub        = nh_.advertise<geometry_msgs::Twist>(nh_.resolveName("cmd_vel"),1);
00176     vel_sub        = nh_.subscribe(nh_.resolveName("cmd_vel"),50, &RosThread::velCb, this);
00177 
00178     uga_tum_ardrone_pub    = nh_.advertise<std_msgs::String>(nh_.resolveName("uga_tum_ardrone/com"),50);
00179     uga_tum_ardrone_sub    = nh_.subscribe(nh_.resolveName("uga_tum_ardrone/com"),50, &RosThread::comCb, this);
00180 
00181 
00182     dronepose_sub          = nh_.subscribe(nh_.resolveName("ardrone/predictedPose"),50, &RosThread::droneposeCb, this);
00183     navdata_sub    = nh_.subscribe(nh_.resolveName("ardrone/navdata"),50, &RosThread::navdataCb, this);
00184     joy_sub        = nh_.subscribe(nh_.resolveName("joy"),50, &RosThread::joyCb, this);
00185 
00186     takeoff_pub    = nh_.advertise<std_msgs::Empty>(nh_.resolveName("ardrone/takeoff"),1);
00187     land_pub       = nh_.advertise<std_msgs::Empty>(nh_.resolveName("ardrone/land"),1);
00188     toggleState_pub        = nh_.advertise<std_msgs::Empty>(nh_.resolveName("ardrone/reset"),1);
00189 
00190     takeoff_sub    = nh_.subscribe(nh_.resolveName("ardrone/takeoff"),1, &RosThread::takeoffCb, this);
00191     land_sub       = nh_.subscribe(nh_.resolveName("ardrone/land"),1, &RosThread::landCb, this);
00192     toggleState_sub        = nh_.subscribe(nh_.resolveName("ardrone/reset"),1, &RosThread::toggleStateCb, this);
00193 
00194     toggleCam_srv        = nh_.serviceClient<std_srvs::Empty>(nh_.resolveName("ardrone/togglecam"),1);
00195     flattrim_srv         = nh_.serviceClient<std_srvs::Empty>(nh_.resolveName("ardrone/flattrim"),1);
00196 
00197     pub_reset = nh_.advertise<std_msgs::Empty>("ardrone/reset", 1); //send robot input on /cmd_vel topic
00198 
00199         ros::Time last = ros::Time::now();
00200         ros::Time lastHz = ros::Time::now();
00201         while(keepRunning && nh_.ok())
00202         {
00203                 // spin for 100ms
00204                 while((ros::Time::now() - last) < ros::Duration(0.1))
00205                         ros::getGlobalCallbackQueue()->callAvailable(ros::WallDuration(0.1 - (ros::Time::now() - last).toSec()));
00206                 last = ros::Time::now();
00207 
00208                 // if nothing on /cmd_vel, repeat!
00209                 if(velCount100ms == 0)
00210                         switch(gui->currentControlSource)
00211                         {
00212                         case CONTROL_AUTO:
00213                                 sendControlToDrone(ControlCommand(0,0,0,0));
00214                                 break;
00215                         case CONTROL_JOY:
00216                                 sendControlToDrone(lastJoyControlSent);
00217                                 break;
00218                         case CONTROL_KB:
00219                                 sendControlToDrone(gui->calcKBControl());
00220                                 break;
00221                         case CONTROL_NONE:
00222                                 sendControlToDrone(ControlCommand(0,0,0,0));
00223                                 break;
00224                         }
00225                 velCount100ms = 0;
00226 
00227                 // if 1s passed: update Hz values
00228                 if((ros::Time::now() - lastHz) > ros::Duration(1.0))
00229                 {
00230                         gui->setCounts(navdataCount, velCount, dronePoseCount, joyCount);
00231                         navdataCount = velCount = dronePoseCount = joyCount = 0;
00232                         lastHz = ros::Time::now();
00233                 }
00234         }
00235 
00236         gui->closeWindow();
00237         if(nh_.ok()) ros::shutdown();
00238         std::cout << "Exiting ROS Thread (ros::shutdown() has been called)" << std::endl;
00239 }
00240 
00241 
00242 void RosThread::publishCommand(std::string c)
00243 {
00244         std_msgs::String s;
00245         s.data = c.c_str();
00246         pthread_mutex_lock(&send_CS);
00247         uga_tum_ardrone_pub.publish(s);
00248         pthread_mutex_unlock(&send_CS);
00249 }
00250 
00251 void RosThread::sendControlToDrone(ControlCommand cmd)
00252 {
00253         // TODO: check converstion (!)
00254         geometry_msgs::Twist cmdT;
00255         cmdT.angular.z = -cmd.yaw;
00256         cmdT.linear.z = cmd.gaz;
00257         cmdT.linear.x = -cmd.pitch;
00258         cmdT.linear.y = -cmd.roll;
00259 
00260         cmdT.angular.x = cmdT.angular.y = gui->useHovering ? 0 : 1;
00261 
00262 
00263         pthread_mutex_lock(&send_CS);
00264         vel_pub.publish(cmdT);
00265         pthread_mutex_unlock(&send_CS);
00266 }
00267 
00268 void RosThread::sendLand()
00269 {
00270         pthread_mutex_lock(&send_CS);
00271         land_pub.publish(std_msgs::Empty());
00272         pthread_mutex_unlock(&send_CS);
00273 }
00274 void RosThread::sendTakeoff()
00275 {
00276         pthread_mutex_lock(&send_CS);
00277         takeoff_pub.publish(std_msgs::Empty());
00278         pthread_mutex_unlock(&send_CS);
00279 }
00280 void RosThread::sendToggleState()
00281 {
00282         pthread_mutex_lock(&send_CS);
00283         toggleState_pub.publish(std_msgs::Empty());
00284         pthread_mutex_unlock(&send_CS);
00285 }
00286 void RosThread::sendToggleCam()
00287 {
00288         pthread_mutex_lock(&send_CS);
00289         toggleCam_srv.call(toggleCam_srv_srvs);
00290         pthread_mutex_unlock(&send_CS);
00291 }
00292 void RosThread::sendFlattrim()
00293 {
00294         pthread_mutex_lock(&send_CS);
00295 
00296     if (drone_state <= 1) {
00297         sendResetMsg();
00298     }
00299 
00300         flattrim_srv.call(flattrim_srv_srvs);
00301         pthread_mutex_unlock(&send_CS);
00302 }


uga_tum_ardrone
Author(s):
autogenerated on Sat Jun 8 2019 20:30:11