2025年2月24日 星期一 甲辰(龙)年 腊月廿四 设为首页 加入收藏
rss
您当前的位置:首页 > 电子 > 机器人与智能物联

对python和C++版本的ROS自定义消息调试

时间:02-03来源:作者:点击数:66

Step1:工程构建

先在CMakeLists.txt中要填有这几项

  • cmake_minimum_required(VERSION 3.0.2)
  • project(simple_ros_test)
  • find_package(catkin REQUIRED COMPONENTS
  • roscpp
  • rospy
  • std_msgs
  • message_generation
  • )
  • add_message_files(
  • FILES
  • Parent.msg
  • Child.msg
  • )
  • generate_messages(
  • DEPENDENCIES
  • std_msgs
  • )
  • catkin_package(
  • # INCLUDE_DIRS include
  • # LIBRARIES simple_ros_test
  • CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
  • # DEPENDS system_lib
  • )
  • include_directories(
  • # include
  • ../../devel/include/
  • ${catkin_INCLUDE_DIRS}
  • )
  • add_executable(rosmsg_test_node src/rosmsg_test_main.cpp)
  • target_link_libraries(rosmsg_test_node
  • ${catkin_LIBRARIES}
  • )

在package.xml中记得添加

  • <build_depend>message_generation</build_depend>
  • <exec_depend>message_runtime</exec_depend>

Step2:自定义消息

比如:Parent.msg中定义

  • Child[] childs

Chlid.msg中定义

  • string Toys
  • string Name
  • uint8 Age

其含义是一个父母有很多孩子,而每个孩子有玩具,名字,年龄等元素。


Step3:Python代码

代码

  • #!/usr/bin/env python
  • import rospy
  • import sys
  • sys.path.insert(0, "/home/wzy/vins_ws/devel/lib/python2.7/dist-packages") # 这一步要加,不然报错ImportError: No module named relative_pose_backend.msg
  • from relative_pose_backend.msg import Parent
  • from relative_pose_backend.msg import Child
  • P = Parent()
  • C1 = Child()
  • C2 = Child()
  • C1.Toys = 1
  • C1.Name = "jerry"
  • C1.Age = 10
  • P.childs.append(C1)
  • C2.Toys = 2
  • C2.Name = "Tom"
  • C2.Age = 8
  • P.childs.append(C2)
  • print(P)
  • # 对循环添加子消息,这里以新增Parent中childs数量为例
  • for i in range(2):
  • Ci = Child() # 这里若要新增对象 要在循环内初始化对象Child(),不能在循环外初始化。和C++中vector push_back()不一样
  • Ci.Name = "name" + str(i)
  • Ci.Toys = "toy_name" + str(i*2)
  • Ci.Age = Ci.Age + 1
  • P.childs.append(Ci)
  • print(P)
  • Ci = Child() # 这里若要新增对象 但在在循环外初始化对象Child(),append函数会依据字典方式,将Name,Toys,Age视作键key,
  • # 所以添加进去的值都被覆盖为循环中最后一次的值
  • for i in range(2):
  • Ci.Name = "name" + str(i)
  • Ci.Toys = "toy_name" + str(i*2)
  • Ci.Age = Ci.Age + 1
  • P.childs.append(Ci)
  • print(P)
  • # 对循环添加子消息,这里以修改Parent中childs属性为例
  • for i in range(len(P.childs)):
  • P.childs[i].Name = "name" + str(i)
  • P.childs[i].Age = P.childs[i].Age + 2
  • print(P)

显示结果

  • childs:
  • -
  • childs:
  • -
  • Toys: "Toys1"
  • Name: "jerry"
  • Age: 10
  • -
  • Toys: "Toys2"
  • Name: "Tom"
  • Age: 8
  • childs:
  • -
  • Toys: "Toys1"
  • Name: "jerry"
  • Age: 10
  • -
  • Toys: "Toys2"
  • Name: "Tom"
  • Age: 8
  • -
  • Toys: "toy_name0"
  • Name: "name0"
  • Age: 1
  • -
  • Toys: "toy_name2"
  • Name: "name1"
  • Age: 1
  • childs:
  • -
  • Toys: "Toys1"
  • Name: "jerry"
  • Age: 10
  • -
  • Toys: "Toys2"
  • Name: "Tom"
  • Age: 8
  • -
  • Toys: "toy_name0"
  • Name: "name0"
  • Age: 1
  • -
  • Toys: "toy_name2"
  • Name: "name1"
  • Age: 1
  • -
  • Toys: "toy_name2"
  • Name: "name1"
  • Age: 2
  • -
  • Toys: "toy_name2"
  • Name: "name1"
  • Age: 2
  • childs:
  • -
  • Toys: "Toys1"
  • Name: "name0"
  • Age: 12
  • -
  • Toys: "Toys2"
  • Name: "name1"
  • Age: 10
  • -
  • Toys: "toy_name0"
  • Name: "name2"
  • Age: 3
  • -
  • Toys: "toy_name2"
  • Name: "name3"
  • Age: 3
  • -
  • Toys: "toy_name2"
  • Name: "name5"
  • Age: 6
  • -
  • Toys: "toy_name2"
  • Name: "name5"
  • Age: 6

Step4:C++代码简要

代码

  • #include "simple_ros_test/Parent.h"
  • #include "ros/ros.h"
  • #include "iostream"
  • int main(int argc, char **argv) {
  • // Launch our ros node
  • ros::init(argc, argv, "rosmsg_test_node");
  • ros::NodeHandle nh;
  • // ros::NodeHandle nh("~");
  • ros::Rate rate(10);
  • simple_ros_test::Parent parent;
  • simple_ros_test::Child child_0;
  • simple_ros_test::Child child_1;
  • child_0.Age = 8;
  • child_0.Name = "Jerry";
  • child_0.Toys = "hhh";
  • child_1.Age = 10;
  • child_1.Name = "Tom";
  • child_1.Toys = "kkk";
  • parent.childs.emplace_back(child_0);
  • parent.childs.emplace_back(child_1);
  • //在循环中添加,循环外定义,可以。这一点与python不同
  • simple_ros_test::Child child_i;
  • for (int i = 0; i < 2; ++i) {
  • child_i.Toys = "toy" + std::to_string(i);
  • child_i.Name = "name" + std::to_string(i);
  • child_i.Age = i;
  • parent.childs.emplace_back(child_i);
  • }
  • //在循环中添加,循环内定义,也可以
  • for (int i = 0; i < 2; ++i) {
  • simple_ros_test::Child child_j;
  • child_j.Toys = "toy" + std::to_string(i*2);
  • child_j.Name = "name" + std::to_string(i*2);
  • child_j.Age = i*2;
  • parent.childs.emplace_back(child_j);
  • }
  • //打印结果
  • for (int i = 0; i < parent.childs.size(); ++i) {
  • std::cout << "parent child = " << std::to_string(parent.childs[i].Age) << "\t" << parent.childs[i].Name << "\t" << parent.childs[i].Toys << std::endl;
  • }
  • return 0;
  • }

显示结果

  • parent child = 8 Jerry hhh
  • parent child = 10 Tom kkk
  • parent child = 0 name0 toy0
  • parent child = 1 name1 toy1
  • parent child = 0 name0 toy0
  • parent child = 2 name2 toy2

Step5:注意事项

5.1 若报错没有可执行文件

把新建的python文件赋权限chmod a+x *.py,对C++文件生成的节点,重新source devel/setup.bash

5.2 如果显示找不到自定义消息

请查看如下目录有没有消息文件生成

python需要查看$HOME/vins_ws/devel/lib/python2.7/dist-packages/relative_pose_backend/msg/有类似目录结构

  • .
  • ├── __init__.py
  • └── msg
  • ├── _Child.py
  • ├── __init__.py
  • └── _Parent.py

C++需要查看$HOME/vins_ws/devel/include/relative_pose_backend/有如下目录结构

  • .
  • ├── Child.h
  • ├── Parent.h
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门