Great tutorial from github

23 篇文章 0 订阅

it 's about position control of the turtlesim 
the source code page is from

https://github.com/utari/UTARI_ROSTutorials/wiki/TurtlesimPositionController-Tutorial
Desired Location

This will be a new topic created by ourselves. to simply follow conventions we will use the same beginning of the other topics "/turtle1/", this is sometimes referred to as the namespace.
Chosen topic name: "/turtle1/PositionCommand"
We will have to choose an appropriate msg type. We could use turtlesim/Pose again but as it has unneeded velocity information and to learn about other types we will look through the ROS wiki. Looking through the wiki pages with ros msgs...
http://wiki.ros.org/std_msgs
http://wiki.ros.org/geometry_msgs
We can see the topic type Pose2D under geometry_msgs. This contains X, Y, and Theta information only. The goal of this controller is simply position and not orientation (Theta) but we can use this type for X and Y. A third or higher order controller could be used to have the turtle approach the point from the correct direction.
This msg will also have the c++ header associated with it #include - "geometry_msgs/Pose2D.h".
We will have to add geometry_msgs to our package dependency's for ROS to find this header. In the package root open package.xml and make sure it looks as follows, where CREATOR will likely be your Ubuntu user name.

<package>
  <description brief="TurtlesimPositionController_pkg">

     TurtlesimPositionController_pkg

  </description>
  <author>CREATOR</author>
  <license>BSD</license>
  <review status="unreviewed" notes=""/>
  <url>http://ros.org/wiki/TurtlesimPositionController_pkg</url>
  
  <depend package="turtlesim"/>
  <depend package="rospy"/>
  <depend package="roscpp"/>
  <depend package="geometry_msgs"/>
</package>

It has been noted for an unknown reason that the package and node may build correctly if you skip adding geometry_msgs to the manifest. This is not the case for most msgs and headers.

// i just forget how this xml file work would it really need the geometry_msgs   o?

Adding the Publishers and Subscribers

We can now add the commands to make our node connect to the found ROS topics. These additions are the #includes for the headers, creating the ROS subscribers and publishers, and callbacks for the subscribers. ros::spin will be added for now to check for incoming messages.

 
   
# include "ros/ros.h"# include "geometry_msgs/Pose2D.h" // to get desired position command# include "turtlesim/Pose.h" // to read current position# include "geometry_msgs/Twist.h" // to send velocity command // Function declarations void ComPoseCallback( const geometry_msgs::Pose2D::ConstPtr& msg); void CurPoseCallback( const turtlesim::Pose::ConstPtr& msg); int main( int argc, char **argv){ ros::init(argc, argv, "TurtlesimPositionController_pubsub"); // connect to roscoreros::NodeHandle n; // node object // register sub to get desired position/pose commandsros::Subscriber ComPose_sub = n. subscribe( "/turtle1/PositionCommand", 5, ComPoseCallback); // register sub to get current position/poseros::Subscriber CurPose_sub = n. subscribe( "/turtle1/pose", 5, CurPoseCallback); // register pub to send twist velocity (cmd_vel)ros::Publisher Twist_pub = n. advertise<geometry_msgs::Twist>( "/turtle1/cmd_vel", 100); ros::spin();} // call back to send new desired Pose msgs void ComPoseCallback( const geometry_msgs::Pose2D::ConstPtr& msg){ ROS_INFO( "Received Command msg"); return;} // call back to send new current Pose msgs void CurPoseCallback( const turtlesim::Pose::ConstPtr& msg){ ROS_INFO( "Received Pose msg"); return;}

// this remains undone .

There are many places you could place your processing code, in main, or in your callbacks. For simplicity we will use main as our processing area. Assuming we want the controller to run constantly we will place the code in a while loop, change ros::spin to ros::spinOnce, and use ros::Rate to control the loop frequency.

Getting Data

We now are receiving our input data but throwing it away with every callback. The simplest way to hold onto that data to be processed through main is a global variable holder. We will make variables of our message data types and copy them in the callback.
// 
 
  
# include "ros/ros.h"# include "geometry_msgs/Pose2D.h" // to get desired position command# include "turtlesim/Pose.h" // to read current position# include "geometry_msgs/Twist.h" // to send velocity command // Function declarations void ComPoseCallback( const geometry_msgs::Pose2D::ConstPtr& msg); void CurPoseCallback( const turtlesim::Pose::ConstPtr& msg); // Global variables bool STOP = true; // to hold stop flag, wait till first command giventurtlesim::Pose CurPose; // to hold current posegeometry_msgs::Pose2D DesPose; // variable to hold desired pose int main( int argc, char **argv){ ros::init(argc, argv, "TurtlesimPositionController_pubsub"); // connect to roscoreros::NodeHandle n; // node object // register sub to get desired position/pose commandsros::Subscriber ComPose_sub = n. subscribe( "/turtle1/PositionCommand", 5, ComPoseCallback); // register sub to get current position/poseros::Subscriber CurPose_sub = n. subscribe( "/turtle1/pose", 5, CurPoseCallback); // register pub to send twist velocity (cmd_vel)ros::Publisher Twist_pub = n. advertise<geometry_msgs::Twist>( "/turtle1/cmd_vel", 100);ros::Rate loop_rate( 10); // freq to run loops in (10 Hz) ROS_INFO( "Ready to send position commands"); // let user know we are ready and good while ( ros::ok() && n. ok() ) // while ros and the node are ok{ ros::spinOnce(); if (STOP == false) // and no stop command{ printf( "Processing...\n");} else{ printf( "Waiting...\n");}loop_rate. sleep(); // sleep to maintain loop rate}} // call back to send new desired Pose msgs void ComPoseCallback( const geometry_msgs::Pose2D::ConstPtr& msg){STOP = false; // start loopDesPose. x = msg->x; // copy msg to varible to use elsewhereDesPose. y = msg->y; return;} // call back to send new current Pose msgs void CurPoseCallback( const turtlesim::Pose::ConstPtr& msg){CurPose. x = msg->x;CurPose. y = msg->y;CurPose. theta = msg->theta; // copy msg to varible to use elsewhere return;}

Data Processing

There are many places you could place your processing code, in main, or in your callbacks. For simplicity we will use main as our processing area. Assuming we want the controller to run constantly we will place the code in a while loop, change ros::spin to ros::spinOnce, and use ros::Rate to control the loop frequency.
// that really matters when the ros::spinOnce and ros::Rate to controll the frequency of the loop 

http://docs.ros.org/diamondback/api/erratic_teleop/html/keyboard_8cpp_source.html that ' the robot controll 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值