Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00049 #include <algorithm>
00050 #include <geometry_msgs/Twist.h>
00051 #include <math.h>
00052 #include <ros/ros.h>
00053 #include <rovio_shared/man_drv.h>
00054 #include <rovio_shared/rovio_http.h>
00055 #include <rovio_ctrl/rovio_move.h>
00056 #include <sstream>
00057 #include <string>
00058 
00059 using namespace std;
00060 
00061 move_controller::move_controller()
00062 {
00063   string user;
00064   string pass;
00065 
00066   
00067   if (!node.getParam(USER, user))
00068   {
00069     ROS_ERROR("Parameter %s not found.", USER);
00070     exit(-1);
00071   }
00072   if (!node.getParam(PASS, pass))
00073   {
00074     ROS_ERROR("Parameter %s not found.", PASS);
00075     exit(-1);
00076   }
00077   if (!node.getParam(HOST, host))
00078   {
00079     ROS_ERROR("Parameter %s not found.", HOST);
00080     exit(-1);
00081   }
00082 
00083   
00084   rovio = new rovio_http(user, pass);
00085 
00086   
00087   man_drv = node.subscribe<rovio_shared::man_drv>("man_drv", 10, &move_controller::man_drv_callback, this);
00088   cmd_vel = node.subscribe<geometry_msgs::Twist>("cmd_vel", 10, &move_controller::cmd_vel_callback, this);
00089 
00090   drive = 0;
00091   speed = 0;
00092   rotate = 0;
00093 
00094   ROS_INFO("Rovio Move Controller Initialized");
00095 }
00096 
00097 move_controller::~move_controller()
00098 {
00099   
00100   delete rovio;
00101 }
00102 
00103 void move_controller::update()
00104 {
00105   
00106   if (drive > 0)
00107   {
00108     
00109     stringstream ss;
00110     ss << "http://" << host.c_str() << "/rev.cgi?Cmd=nav&action=18&drive=" << drive << "&speed=" << speed;
00111     rovio_response *buf = rovio->send(ss.str().c_str());
00112     rovio_response_clean(buf);
00113   }
00114   
00115   if (rotate > 0)
00116   {
00117     
00118     stringstream ss;
00119     ss << "http://" << host.c_str() << "/rev.cgi?Cmd=nav&action=18&drive=6&speed=" << rotate;
00120     rovio_response *buf = rovio->send(ss.str().c_str());
00121     rovio_response_clean(buf);
00122   }
00123   else if (rotate < 0)
00124   {
00125     
00126     stringstream ss;
00127     ss << "http://" << host.c_str() << "/rev.cgi?Cmd=nav&action=18&drive=5&speed=" << -rotate;
00128     rovio_response *buf = rovio->send(ss.str().c_str());
00129     rovio_response_clean(buf);
00130   }
00131 }
00132 
00133 void move_controller::man_drv_callback(const rovio_shared::man_drv::ConstPtr &msg)
00134 {
00135   
00136   if (msg->drive < rovio_shared::man_drv::MIN_DRIVE_VAL || msg->drive > rovio_shared::man_drv::MAX_DRIVE_VAL)
00137   {
00138     ROS_ERROR(
00139         "Manual Drive 'drive' value of %i out of range [%i,%i].", msg->drive, rovio_shared::man_drv::MIN_DRIVE_VAL, rovio_shared::man_drv::MAX_DRIVE_VAL);
00140     return;
00141   }
00142   if (msg->speed < rovio_shared::man_drv::MIN_SPEED_VAL || msg->speed > rovio_shared::man_drv::MAX_SPEED_VAL)
00143   {
00144     ROS_ERROR(
00145         "Manual Drive 'speed' value of %i out of range [%i,%i].", msg->speed, rovio_shared::man_drv::MIN_SPEED_VAL, rovio_shared::man_drv::MAX_SPEED_VAL);
00146     return;
00147   }
00148 
00149   
00150   drive = msg->drive;
00151   speed = msg->speed;
00152 }
00153 
00154 void move_controller::cmd_vel_callback(const geometry_msgs::Twist::ConstPtr &msg)
00155 {
00156   
00157   if (msg->linear.x == 0 && msg->linear.y > 0)
00158   {
00159     
00160     drive = 3;
00161   }
00162   else if (msg->linear.x == 0 && msg->linear.y < 0)
00163   {
00164     
00165     drive = 4;
00166   }
00167   else
00168   {
00169     
00170     double angle = atan2(msg->linear.x, msg->linear.y);
00171     
00172     if (msg->linear.x > 0 && angle <= 5 * M_PI / 8 && angle >= 3 * M_PI / 8)
00173     {
00174       
00175       drive = 1;
00176     }
00177     else if (msg->linear.x > 0 && msg->linear.y > 0 && angle < 3 * M_PI / 8 && angle >= M_PI / 8)
00178     {
00179       
00180       drive = 8;
00181     }
00182     else if (msg->linear.y > 0 && (angle >= -1 * M_PI / 8 || angle >= 3 * M_PI / 8))
00183     {
00184       
00185       drive = 4;
00186     }
00187     else if (msg->linear.x < 0 && msg->linear.y > 0 && angle < -1 * M_PI / 8 && angle >= -3 * M_PI / 8)
00188     {
00189       
00190       drive = 10;
00191     }
00192     else if (msg->linear.x < 0 && angle <= -3 * M_PI / 8 && angle >= -5 * M_PI / 8)
00193     {
00194       
00195       drive = 2;
00196     }
00197     else if (msg->linear.x < 0 && msg->linear.y < 0 && angle <= -5 * M_PI / 8 && angle >= -7 * M_PI / 8)
00198     {
00199       
00200       drive = 9;
00201     }
00202     else if (msg->linear.y < 0 && (angle < -7 * M_PI / 8 || angle >= 7 * M_PI / 8))
00203     {
00204       
00205       drive = 3;
00206     }
00207     else if (msg->linear.x > 0 && msg->linear.y < 0 && angle < 7 * M_PI / 8 && angle >= 5 * M_PI / 8)
00208     {
00209       
00210       drive = 7;
00211     }
00212     else
00213     {
00214       
00215       drive = 0;
00216     }
00217   }
00218 
00219   
00220   rotate = -msg->angular.z * 10.0;
00221 
00222   
00223   speed = min(10, (int)(sqrt(pow(msg->linear.x, 2.0) + pow(msg->linear.y, 2.0)) * 10));
00224 }
00225 
00226 int main(int argc, char **argv)
00227 {
00228   
00229   ros::init(argc, argv, "rovio_move");
00230 
00231   
00232   move_controller controller;
00233 
00234   
00235   ros::Rate loop_rate(5);
00236   
00237   while (ros::ok())
00238   {
00239     ros::spinOnce();
00240     
00241     controller.update();
00242     loop_rate.sleep();
00243   }
00244 }