机器人原理与实践ROS学习笔记
Posted 与光同程
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器人原理与实践ROS学习笔记相关的知识,希望对你有一定的参考价值。
常用命令
启动ROS: roscore
获取节点信息:
rosnode list 列出所有正在运行的节点
rosnode info xxx 列出节点信息
rosnode ping
rosnode machine
rosnode kill
运行节点
rosrun XXX
创建ROS功能包:roscreate-pkg XXX std_msgs rospy roscpp
编译功能包 :rosmake xxx
查找路径:rospack find xxx
查看依赖关系 :rospack depends XXX
查看功能包内容:rosls
更改包路径 :roscd
显示观察话题:rostopic list
rostopic echo xxx -n x
放码过来
Python 编程
#!/usr/bin/env python
import rospy
from std_msgs.msg import Int32
rospy.init_node('topic_publisher')
pub=rospy.Publisher('PS2',Int32)
rate=rospy.Rate(2)
count=0
while not rospy.is_shutdown():
pub.publish(count)
count+=1
rate.sleep()
#!/usr/bin/env python
import rospy
from std_msgs.msg import Int32
def callback(msg):
print(msg.data)
rospy.init_node('subsribe')
sub=rospy.Subscriber('PS2',Int32,callback)
rospy.spin()
C++编程
ROS的Hello World
消息发布者
#include <ros/ros.h>
#include <std_msgs/String.h>
#include <sstream>
int main(int argc,char ** argv)
{
//启动节点并设置名称
ros::init(argc,argv,"ps2");
//节点句柄
ros::NodeHandle n;
ROS_INFO_STREAM("PS2 NODE INIT");
//设置节点为发布者,并将发布的主题类型告知节点管理器
//参数1:消息名称
//参数2:缓冲区大小
ros::Publisher pub=n.advertise<std_msgs::String>("PS2",1000);
//一秒发送10次
ros::Rate loop_rate(10);
while(ros::ok()){
std_msgs::String msg;
std::stringstream ss;
ss<<"I am PS node";
msg.data=ss.str();
//发布消息
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
消息订阅者
#include <ros/ros.h>
#include <std_msgs/String.h>
void callBack(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("GetPS2 I head that: [%s]",msg->data.c_str());
}
int main(int argc ,char** argv)
{
ros::init(argc,argv,"GetPS2");
ros::NodeHandle n;
ros::Subscriber sub=n.subscribe("PS2",1000,callBack);
ros::spin();
return 0;
}
就像上面说的,ros::spin() 在调用后不会再返回,也就是你的主程序到这儿就不往下执行了,而 ros::spinOnce() 后者在调用后还可以继续执行之后的程序。
其实看函数名也能理解个差不多,一个是一直调用;另一个是只调用一次,如果还想再调用,就需要加上循环了。
这里一定要记住,ros::spin()函数一般不会出现在循环中,因为程序执行到spin()后就不调用其他语句了,也就是说该循环没有任何意义,还有就是spin()函数后面一定不能有其他语句(return 0 除外),有也是白搭,不会执行的。ros::spinOnce()的用法相对来说很灵活,但往往需要考虑调用消息的时机,调用频率,以及消息池的大小,这些都要根据现实情况协调好,不然会造成数据丢包或者延迟的错误。
这里需要特别强调一下,如果大兄弟你的程序写了相关的消息订阅函数,那千万千万千万不要忘了在相应位置加上ros::spin()或者ros::spinOnce()函数,不然你是永远都得不到另一边发出的数据或消息的,博主血的教训,万望紧记。。。
创建msg与srv文件
msg与src勇于定义传输数据的类型与数据值的文件。ROS会根据这些文件内容自动的为我们创建所需的代码。
使用ROS创建自定义消息
在功能包文件夹下创建msg文件夹,然后在msg文件夹中创建.msg文件 输入
int32 A
int32 B
int32 C
编辑CMakeList.txt
显示消息情况
rosmsg show arm/PS2
显示服务情况
rossrv show arm/PS_2
使用srv与msg
#include <ros/ros.h>
#include "arm/PS2.h"
#include <sstream>
int main(int argc,char** argv)
{
ros::init(argc,argv,"sendMsg");
ros::NodeHandle n;
ros::Publisher pub=n.advertise<arm::PS2>("PS2",1000);
ros::Rate loop_rate(10);
while(ros::ok())
{
arm::PS2 msg;
msg.A=1;
msg.B=1;
msg.C=1;
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
#include <ros/ros.h>
#include "arm/PS2.h"
void callBack(const arm::PS2::ConstPtr& msg )
{
ROS_INFO("I Heard :[%d][%d][%d]",msg->A,msg->B,msg->C);
}
int main(int argc ,char** argv)
{
ros::init(argc,argv,"getMsg");
ros::NodeHandle n;
ros::Subscriber sub =n.subscribe("PS2",1,callBack);
ros::spin();
return 0;
}
以上是关于机器人原理与实践ROS学习笔记的主要内容,如果未能解决你的问题,请参考以下文章