如果写了消息订阅函数,那一定要写ros::spin() 或者ros::spinOnce(),不然是得不到另一边发出的消息或者信息
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
int main(int argc, char **argv)
{
//ROS节点初始化,节点名称是talker
ros::init(argc, argv, "talker");
//创建节点的句柄
ros::NodeHandle n;
//创建一个Publisher ,发布名为chatter的topic,消息类型是std_msgs::String,1000是消息发布队列的大小
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
//设置循环的频率
ros::Rate loop_rate(10);
//进入节点的主循环,在节点未发生异常情况的时候一直在循环中运行
int count = 0;
while (ros::ok())
{
//初始化std_msgs::String类型的消息
std_msgs::String msg;
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();
//发布消息,ROS_INFO类似与print,用来打印信息
ROS_INFO("%s", msg.data.c_str());
/**
* 向 Topic: chatter 发送消息, 发送频率为10Hz(1秒发10次);消息池最大容量1000。
*/
chatter_pub.publish(msg);
//循环等待回调函数,用来处理节点订阅话题的所有回调函数
ros::spinOnce();
//按照循环频率延时,publisher一个周期工作完成后,可以让节点休息一段时间,调用休眠函数让节点进入休眠状态,设置休眠的时间,休息后在开始下一个周期的工作
loop_rate.sleep();
++count;
}
return 0;
}
接受端:
#include "ros/ros.h"
#include "std_msgs/String.h"
//接受到消息后,会进入消息回调函数
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
//将接受到的消息打印出来
ROS_INFO("I heard: [%s]", msg->data.c_str());
}
int main(int argc, char **argv)
{
//初始化节点listener
ros::init(argc, argv, "listener");
//初始化节点句柄
ros::NodeHandle n;
//创建一个Subscriber,订阅chatter的话题,注册回调函数
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
/**
* ros::spin() 将会进入循环, 一直调用回调函数chatterCallback(),每次调用1000个数据。
* 当用户输入Ctrl+C或者ROS主进程关闭时退出,
*/
ros::spin();
return 0;
}
接受端:
#include "ros/ros.h"
#include "std_msgs/String.h"
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
/*...TODO...*/
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("chatter", 2, chatterCallback);
ros::Rate loop_rate(5);
while (ros::ok())
{
/*...TODO...*/
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
用python写ros代码
1.关于rospy.spin()调用多次callback ,程序若无rospy.spin(),也无上面黄色部分,则订阅一次发布消息会调用多次callback。
2.当接收到订阅消息时,ballback在r.sleep()时间空隙的时候调用,所以callback的执行时间不能超过r.sleep()提供的间隙时间,例如在callback里设置sleep(1),则会消耗完r.sleep(),然后运行print 'after sleep 1s',此时flg=0,因此跳出while循环,结束程序。直接用sleep()代替rospy.Rate和r.sleep(),也是可以的。
3.最好使用:
while not rospy.is_shutdown(): #True:
if self.flg==1: #encoder_list[0]='e':
#!/usr/bin/env python
import rospy
from bzrobot_msgs.msg import bzr_WheelLinearVels
#from threading import Thread
from time import sleep
class RS232MotorComm():
def callback(self, data):
print '****************************************start callback'
self.flg=0
sleep(0.05)
rospy.loginfo("speed %f %f",data.leftWheelLinearVel, data.rightWheelLinearVel)
self.flg=1
def motor_listener(self):
self.flg=1
rospy.init_node('rs232_motor_comm', anonymous=True)
rospy.Subscriber("control_wheel_linear_vel", bzr_WheelLinearVels, self.callback)
#sleep(1)
r = rospy.Rate(10) # 10hz
while self.flg==1:#not rospy.is_shutdown():#True:
print'where'
r.sleep() #time must enough for callback,or it will out while loop
print'after sleep 1s'
if __name__ == '__main__':
motor_controller = RS232MotorComm()
print'the1'
motor_controller.motor_listener()
#rospy.spin()
print'end'