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 }