turtle_stroll.cpp
Go to the documentation of this file.
00001 #include <boost/bind.hpp>
00002 #include <string>
00003 #include <ros/ros.h>
00004 #include <turtlesim/Pose.h>
00005 //#include <turtlesim/Velocity.h>
00006 #include <geometry_msgs/Twist.h>
00007 #include <turtlesim/Spawn.h>
00008 #include <std_srvs/Empty.h>
00009 #include <gateway_msgs/GatewayInfo.h>
00010 
00011 turtlesim::PoseConstPtr g_pose;
00012 turtlesim::Pose g_goal;
00013 double x_vel = 1.0;
00014 double z_vel = 0.4;
00015 double square_scale = 1.0;
00016 
00017 enum State
00018 {
00019   FORWARD,
00020   STOP_FORWARD,
00021   TURN,
00022   STOP_TURN,
00023 };
00024 
00025 State g_state = FORWARD;
00026 State g_last_state = FORWARD;
00027 bool g_first_goal_set = false;
00028 
00029 #define PI 3.141592
00030 
00031 void poseCallback(const turtlesim::PoseConstPtr& pose)
00032 {
00033   g_pose = pose;
00034 }
00035 
00036 bool hasReachedGoal()
00037 {
00038   return fabsf(g_pose->x - g_goal.x) < 0.1 && fabsf(g_pose->y - g_goal.y) < 0.1 && fabsf(g_pose->theta - g_goal.theta) < 0.01;
00039 }
00040 
00041 bool hasStopped()
00042 {
00043   return g_pose->angular_velocity < 0.0001 && g_pose->linear_velocity < 0.0001;
00044 }
00045 
00046 void printGoal()
00047 {
00048   ROS_INFO("New goal [%f %f, %f]", g_goal.x, g_goal.y, g_goal.theta);
00049 }
00050 
00051 void commandTurtle(ros::Publisher twist_pub, float linear, float angular)
00052 {
00053   //turtlesim::Velocity vel;
00054   geometry_msgs::Twist twist;
00055   twist.linear.x = linear;
00056   twist.angular.z = angular;
00057   twist_pub.publish(twist);
00058 }
00059 
00060 void stopForward(ros::Publisher twist_pub)
00061 {
00062   if (hasStopped())
00063   {
00064     ROS_INFO("Reached goal");
00065     g_state = TURN;
00066     g_goal.x = g_pose->x;
00067     g_goal.y = g_pose->y;
00068     g_goal.theta = fmod(g_pose->theta + PI/2.0, 2*PI);
00069     printGoal();
00070   }
00071   else
00072   {
00073     commandTurtle(twist_pub, 0, 0);
00074   }
00075 }
00076 
00077 void stopTurn(ros::Publisher twist_pub)
00078 {
00079   if (hasStopped())
00080   {
00081     ROS_INFO("Reached goal");
00082     g_state = FORWARD;
00083     g_goal.x = cos(g_pose->theta) * 2 * square_scale + g_pose->x;
00084     g_goal.y = sin(g_pose->theta) * 2 * square_scale + g_pose->y;
00085     g_goal.theta = g_pose->theta;
00086     printGoal();
00087   }
00088   else
00089   {
00090     commandTurtle(twist_pub, 0, 0);
00091   }
00092 }
00093 
00094 
00095 void forward(ros::Publisher twist_pub)
00096 {
00097   if (hasReachedGoal())
00098   {
00099     g_state = STOP_FORWARD;
00100     commandTurtle(twist_pub, 0, 0);
00101   }
00102   else
00103   {
00104     commandTurtle(twist_pub, x_vel, 0.0);
00105   }
00106 }
00107 
00108 void turn(ros::Publisher twist_pub)
00109 {
00110   if (hasReachedGoal())
00111   {
00112     g_state = STOP_TURN;
00113     commandTurtle(twist_pub, 0, 0);
00114   }
00115   else
00116   {
00117     commandTurtle(twist_pub, 0.0, z_vel);
00118   }
00119 }
00120 
00121 void timerCallback(const ros::TimerEvent&, ros::Publisher twist_pub)
00122 {
00123   if (!g_pose)
00124   {
00125     return;
00126   }
00127 
00128   if (!g_first_goal_set)
00129   {
00130     g_first_goal_set = true;
00131     g_state = FORWARD;
00132     g_goal.x = cos(g_pose->theta) * 2 * square_scale + g_pose->x;
00133     g_goal.y = sin(g_pose->theta) * 2 * square_scale + g_pose->y;
00134     g_goal.theta = g_pose->theta;
00135     printGoal();
00136   }
00137 
00138   if (g_state == FORWARD)
00139   {
00140     forward(twist_pub);
00141   }
00142   else if (g_state == STOP_FORWARD)
00143   {
00144     stopForward(twist_pub);
00145   }
00146   else if (g_state == TURN)
00147   {
00148     turn(twist_pub);
00149   }
00150   else if (g_state == STOP_TURN)
00151   {
00152     stopTurn(twist_pub);
00153   }
00154 }
00155 
00156 int main(int argc, char** argv)
00157 {
00158   ros::init(argc, argv, "turtle_stroll");
00159   std::string simulation_namespace;
00160   ros::NodeHandle pnh("~");
00161   if ( !pnh.getParam("simulation_namespace", simulation_namespace) ) {
00162     ROS_WARN_STREAM("TurtleStroll: simulation_namespace parameter not set.");
00163   }
00164   if ( !pnh.getParam("turtle_x_vel", x_vel) ) {
00165     ROS_WARN_STREAM("TurtleStroll: turtle_x_vel parameter not set.");
00166   }
00167   if ( !pnh.getParam("turtle_z_vel", z_vel) ) {
00168     ROS_WARN_STREAM("TurtleStroll: turtle_z_vel parameter not set.");
00169   }
00170   if ( !pnh.getParam("square_scale", square_scale) ) {
00171     ROS_WARN_STREAM("TurtleStroll: square_size parameter not set.");
00172   }
00173 
00174   ros::NodeHandle snh(simulation_namespace);
00175   ros::Subscriber pose_sub = snh.subscribe("pose", 1, poseCallback);
00176   ros::Publisher twist_pub = snh.advertise<geometry_msgs::Twist>("cmd_vel", 1);
00177 
00178   ros::NodeHandle nh;
00179   ros::Timer timer = nh.createTimer(ros::Duration(0.016), boost::bind(timerCallback, _1, twist_pub));
00180 
00181   ros::spin();
00182 }


turtle_concert
Author(s): Daniel Stonier , Jihoon Lee
autogenerated on Fri Feb 12 2016 02:51:42