??文章只是个人学习过程中学习笔记,主要参考ROS教程 。
[ROS](01)创建ROS工作空间
[ROS](02)创建&编译ROS软件包Package
1、概述
??msg (消息)文件就是文本文件,用于描述ROS消息的字段。它们用于为不同编程语言编写的消息生成源代码。 ??msg 文件存放在软件包的msg目录下。
2、msg结构和类型
??msg文件就是简单的文本文件,每行都有一个字段类型和字段名称。它的结构为: ????fieldtype + fieldname
2.1 类型
??可以使用的类型为:
- int8, int16, int32, int64 (以及 uint*)
- float32, float64
- string
- time, duration
- 其他msg文件
- variable-length array[] 和 fixed-length array[C]
2.2 举例
std_msgs/Header header
uint8 is_true
uint32 height
uint32 width
string child_frame_id
time stamp
geometry_msgs/PoseWithCovariance pose
geometry_msgs/TwistWithCovariance twist
uint8[] data
3、msg命令rosmsg
rosmsg 显示有关ROS消息类型的信息。
命令 | 功能 |
---|
rosmsg show | 显示消息的描述(详细信息) | rosmsg info | rosmsg show 的别名,功能一样 | rosmsg list | 列出所有消息 | rosmsg md5 | 显示md5加密的消息 | rosmsg package | 列出某个软件包(package)的消息 | rosmsg packages | 列出包含消息的软件包(packages) |
4、msg的用法
4.1 创建msg
??还是在原来创建的软件包 beginner_tutorials 中定义一个新的消息。
roscd beginner_tutorials
mkdir msg
echo "int64 num" > msg/Num.msg
4.2 配置CMakeLists.txt
??1. 为已经存在里面的find_package调用添加message_generation 依赖项(),这样就能生成消息了。(添加 message_generation 依赖项,必须有 std_msgs 。)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
??2. 添加自定义的消息文件。将你msg 文件夹中自定义的*.msg 文件添加在这里。
add_message_files(
FILES
Num.msg
)
??3. 用于生成所有定义的message文件,需要添加本文件需要依赖的packages。其实就是告诉编译器,编译 *.msg 文件时,需要依赖的库或package。
generate_messages(
DEPENDENCIES
std_msgs
)
??4. 导出消息的运行时依赖关系。
catkin_package(
...
CATKIN_DEPENDS message_runtime ...
...)
4.3 配置package.xml
??添加编译依赖与执行依赖。
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
Node :在构建时,其实只需要message_generation ,而在运行时,我们只需要message_runtime 。
4.4 编译package
??已经创建了一些新消息,所以需要重新make一下软件包:
cd
cd catkin_ws
catkin_make
??msg目录中的任何.msg文件都将生成所有支持语言的代码。
- C++消息的头文件将生成在
~/catkin_ws/devel/include/beginner_tutorials/
- python脚本将创建在
~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg
5、msg命令实操
5.1 rosmsg list
??rosmsg list 列出ROS中的所有消息(msg)。
5.2 rosmsg packages
??rosmsg packages [options] 列出包含消息的软件包。
rosmsg packages
rosmsg packages -s
5.3 rosmsg package
??rosmsg package [package-name] 列出某个软件包(package)的消息。
5.4 rosmsg show / rosmsg info
??rosmsg show [message type] 显示消息的详细信息。
5.5 rosmsg md5
??rosmsg md5[message type] 显示md5加密的消息。如果编译的版本不匹配,这也会发出警告。
Node :md5 命令仅供专家用户使用。(??)
6、实操编程 – 话题通信发送自定义消息
??功能:基于话题通信,发布者以一定频率发布自定义消息并打印输出消息,订阅者订阅自定义消息并打印输出消息。 ??实现: ??? 1. 创建发布者(talker )节点,该节点不断广播自定义消息。 ??? 2. 创建订阅者(listener )节点,该节点持续接收自定义消息。 ??? 3. 创建自定义消息(Num.msg ),(见4.1小节 创建msg ) ??? 4. 发布订阅话题chatter
Num.msg
Num.msg
talker
chatter
listener
6.1 编写程序(C++)
??在beginner_tutorials 软件包的src目录下创建发布者和订阅者源文件:
roscd beginner_tutorials
cd src
touch talker.cpp listener.cpp
6.1.1 发布者程序(talker.cpp)
#include "ros/ros.h"
#include "beginner_tutorials/Num.h"
int main(int argc, char **argv)
{
setlocale(LC_ALL,"");
ros::init(argc, argv, "talker");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<beginner_tutorials::Num>("chatter", 1000);
ros::Rate loop_rate(1);
beginner_tutorials::Num msg;
msg.num = 0;
while(ros::ok())
{
ROS_INFO("当前num值为: %d",msg.num);
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
msg.num += 1;
}
return 0;
}
对上边的内容进行一下总结:
- 初始化ROS系统
- 向主节点宣告我们将要在
chatter 话题上发布beginner_tutorials/Num 类型的消息 - 以每秒1次的速率向
chatter 话题循环发布消息
6.1.2 订阅者程序(listener.cpp)
#include "ros/ros.h"
#include "beginner_tutorials/Num.h"
void chatterCallback(const beginner_tutorials::Num::ConstPtr& msg)
{
ROS_INFO("已收到的Num的值: %d",msg->num);
}
int main(int argc, char **argv)
{
setlocale(LC_ALL,"");
ros::init(argc, argv, "listener");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe("chatter",1000, chatterCallback);
ros::spin();
return 0;
}
同样地,我们来总结一下:
- 初始化ROS系统
- 订阅
chatter 话题 - 开始spin自循环,等待消息的到达
- 当消息到达后,调用
chatterCallback() 函数
6.1.3 配置CMakeLists.txt
??只需将这几行添加到CMakeLists.txt文件的底部:
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener ${PROJECT_NAME}_generate_messages_cpp)
6.1.4 编译、运行
??编译后,在终端中执行过程如下所示。
6.2 编写程序(python)
??在beginner_tutorials 软件包的scripts 目录下创建发布者和订阅者源文件:
roscd beginner_tutorials
cd scripts
touch talker.py listener.py
chmod +x talker.py listener.py
6.2.1 发布者程序(talker.py)
import rospy
from beginner_tutorials.msg import Num
def talker():
rospy.init_node("talker",anonymous=True)
pub = rospy.Publisher('chatter', Num, queue_size=1000)
rate = rospy.Rate(1)
msg = Num()
msg.num = 0
while not rospy.is_shutdown():
rospy.loginfo("当前num值为: %d",msg.num)
pub.publish(msg)
rate.sleep()
msg.num += 1
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
6.2.2 订阅者程序(listener.py)
import rospy
from beginner_tutorials.msg import Num
def callback(msg):
rospy.loginfo("已收到的Num的值: %d",msg.num)
def listener():
rospy.init_node("listener",anonymous=True)
pub = rospy.Subscriber('chatter', Num, callback, queue_size=1000)
rospy.spin()
if __name__ == '__main__':
listener()
6.2.3 配置CMakeLists.txt
catkin_install_python(PROGRAMS
scripts/turtle_publisher.py
scripts/talker.py
scripts/listener.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
6.1.4 编译、运行
??编译后,在终端中执行过程如下所示。
|