Ubuntu16.04+ROS 。
发布者订阅者实现,发布者发出目标点,订阅者接受到后控制Turtlebo进行导航。
打开gazebo roslaunch nav_sim myrobot_world.launch
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
通过移动小车,设置目标点,记录左侧显示的位置坐标。x y z 和分别绕xyz轴旋转的角度:roll pitch yaw
#include
#include
#include
#include
using namespace std;
int flag=1;
class Goal{
public:
geometry_msgs::PoseStamped goal;
Goal(){
pub=n.advertise<geometry_msgs::PoseStamped>("/move_base_simple/goal",10);
sub=n.subscribe("/cmd_vel",1,&Goal::callback,this);
goal.header.frame_id = "map";
//改为自己记录目标点的坐标
goal.pose.position.x = pose.x;
goal.pose.position.y = pose.y;
goal.pose.position.z = pose.z;
goal.pose.orientation.x = pose._x;
goal.pose.orientation.y = pose._y;
goal.pose.orientation.z = pose._z;
goal.pose.orientation.w = pose._w;
}
private:
ros::NodeHandle n;
ros::Publisher pub;
ros::Subscriber sub;
void callback(const geometry_msgs::Twist &v);
};
void Goal::callback(const geometry_msgs::Twist &v)
{
if(flag==1&&v.linear.x==0){
ROS_INFO("Sending goal!");
pub.publish(goal);
}
}
int main(int argc,char **argv)
{
ros::init(argc,argv,"send_goal");
Goal g;
ros::spin();
return 0;
}
#include
#include
#include
#include
using namespace std;
int flag=1;
int g1=0,g2=0,g3=0;
class Goal{
public:
geometry_msgs::PoseStamped goal_1;
geometry_msgs::PoseStamped goal_2;
geometry_msgs::PoseStamped goal_3;
Goal(){
pub=n.advertise<geometry_msgs::PoseStamped>("/move_base_simple/goal",10);
sub=n.subscribe("/cmd_vel",1,&Goal::callback,this);
goal_1.header.frame_id = "map";
goal_2.header.frame_id = "map";
goal_3.header.frame_id = "map";
//以下三个目标的改为自己目标点的信息
//Goal one
goal_1.pose.position.x = 0.033449;
goal_1.pose.position.y = 8.273015;
goal_1.pose.position.z = 0.050003;
goal_1.pose.orientation.x = 0;
goal_1.pose.orientation.y = 0;
goal_1.pose.orientation.z = 0;
goal_1.pose.orientation.w = 1.487145;
//Goal two
goal_2.pose.position.x = -0.207746;
goal_2.pose.position.y = 17.607371;
goal_2.pose.position.z = 0.050003;
goal_2.pose.orientation.x = 0;
goal_2.pose.orientation.y = 0;
goal_2.pose.orientation.z = 0;
goal_2.pose.orientation.w = 1.483080;
//Goal three
goal_3.pose.position.x = 2.467109;
goal_3.pose.position.y = 9.938154;
goal_3.pose.position.z = 0.050002;
goal_3.pose.orientation.x = 0;
goal_3.pose.orientation.y = 0;
goal_3.pose.orientation.z = 0;
goal_3.pose.orientation.w = -1.889479;
}
private:
ros::NodeHandle n;
ros::Publisher pub;
ros::Subscriber sub;
void callback(const geometry_msgs::Twist &v);
};
void Goal::callback(const geometry_msgs::Twist &v){
//发送第一个目标点,如果发送成功,v将大于0
if(flag==1&&v.linear.x==0){
ROS_INFO("Sending goal one!");
pub.publish(goal_1);
g1=1;
}
if(v.linear.x>0&&flag==1)
flag=2;
if(flag==2&&v.linear.x==0&&g1){
ROS_INFO("Sending goal two!");
pub.publish(goal_2);
g2=1;
}
if(v.linear.x>0&&flag==2&&g2)
flag=3;
if(flag==3&&v.linear.x==0&&g2){
ROS_INFO("Sending goal three!");
pub.publish(goal_3);
g3=1;
}
}
int main(int argc,char **argv)
{
ros::init(argc,argv,"many_goal");
Goal g;
ros::spin();
return 0;
}
在CMakeLists.txt文件中添加
add_executable(send_goal src/send_goal.cpp)
target_link_libraries(send_goal ${catkin_LIBRARIES})
add_executable(many_goal src/many_goal.cpp)
target_link_libraries(many_goal ${catkin_LIBRARIES})
在move_base.launch文件中启动send_goal.cpp或many_goal.cpp
加入两行:
<!--node pkg="nav_sim" type="send_goal" respawn="false" name="send_goal" output="screen"/-->
<node pkg="nav_sim" type="many_goal" respawn="false" name="many_goal" output="screen"/>
编译成功后:运行
roslaunch nav_sim myrobot_world.launch
roslaunch nav_sim move_base.launch
可以,但需要手动点2D Nav Goal
可以
注:也可以不用Turtlebot,使用nav _sim包的小车或者racecar的minicar。
上周的任务: