网站建设明薇通网络不错,猪价格网,遵义企业网站建设,建设一个大型电影网站费用1、简述
很多项目已经转向ROS2#xff0c;本人作为ROS小白从ROS1开始学起#xff0c;但是不会深入学习ROS1#xff0c;只一带而过。 下面只了解一些ROS1中的概念和基本编程接口。
ROS1中有两种通信模式#xff1a;话题模式和服务模式#xff0c;区别如下
2、话题模式 …1、简述
很多项目已经转向ROS2本人作为ROS小白从ROS1开始学起但是不会深入学习ROS1只一带而过。 下面只了解一些ROS1中的概念和基本编程接口。
ROS1中有两种通信模式话题模式和服务模式区别如下
2、话题模式 2.1 查看话题和消息
1列出所有话题rostopic list
~/workspace/ros$ rostopic list
/rosout
/rosout_agg
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose2查看话题详细信息rostopic info 和下面发布编程相关的话题
~/workspace/ros$ rostopic info /turtle1/cmd_vel
Type: geometry_msgs/TwistSubscribers: * /turtlesim (http://laoer:43127/)和下面订阅编程相关的话题
$ rostopic info /turtle1/pose
Type: turtlesim/PosePublishers: * /turtlesim (http://laoer:43127/)3查看消息详细信息rosmsg show 和下面发布编程相关的消息
~/workspace/ros$ rosmsg show geometry_msgs/Twist
geometry_msgs/Vector3 linearfloat64 xfloat64 yfloat64 z
geometry_msgs/Vector3 angularfloat64 xfloat64 yfloat64 z对应程序中的代码
ros::Publisher turtle_vel_pub n.advertisegeometry_msgs::Twist(/turtle1/cmd_vel, 10);
geometry_msgs::Twist vel_msg;
vel_msg.linear.x 0.5;
vel_msg.angular.z 0.2;
turtle_vel_pub.publish(vel_msg);和下面订阅编程相关的消息
~/workspace/ros$ rosmsg show turtlesim/Pose
float32 x
float32 y
float32 theta
float32 linear_velocity
float32 angular_velocityvoid poseCallback(const turtlesim::Pose::ConstPtr msg)
{ROS_INFO(Turtle pose: x:%0.6f, y:%0.6f, msg-x, msg-y);
}
ros::Subscriber pose_sub n.subscribe(/turtle1/pose, 10, poseCallback);2.2、发布者
1进入ROS1的工程目录
cd ~/workspace/ros/src/2创建功能包
~/workspace/ros/src$ catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim输出信息如下
Created file learning_topic/CMakeLists.txt
Created file learning_topic/package.xml
Created folder learning_topic/include/learning_topic
Created folder learning_topic/src
Successfully created files in /home/laoer/workspace/ros/src/learning_topic. Please adjust the values in package.xml.3编辑源码
cd ~/workspace/ros
vi src/learning_topic/src/velocity_publisher.cpp源码如下
#include ros/ros.h
#include geometry_msgs/Twist.hint main(int argc, char **argv)
{// ROS节点初始化ros::init(argc, argv, velocity_publisher);// 创建节点句柄ros::NodeHandle n;// 创建一个Publisher发布名为/turtle1/cmd_vel的topic消息类型为geometry_msgs::Twist队列长度10ros::Publisher turtle_vel_pub n.advertisegeometry_msgs::Twist(/turtle1/cmd_vel, 10);// 设置循环的频率ros::Rate loop_rate(10);int count 0;while (ros::ok()){// 初始化geometry_msgs::Twist类型的消息geometry_msgs::Twist vel_msg;vel_msg.linear.x 0.5;vel_msg.angular.z 0.2;// 发布消息turtle_vel_pub.publish(vel_msg);ROS_INFO(Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s], vel_msg.linear.x, vel_msg.angular.z);// 按照循环频率延时loop_rate.sleep();}return 0;
}4修改CMakeLists.txt
~/workspace/ros$ vi src/learning_topic/CMakeLists.txt添加需要编译生成的可执行文件规则和连接库 在## Build ##下添加
add_executable(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})5编译
catkin_make编译输出
Base path: /home/laoer/workspace/ros
……
-- processing catkin package: learning_topic
-- add_subdirectory(learning_topic)
……
[100%] Built target velocity_publisher6运行 在终端1中启动节点管理器
roscore在终端2中启动小乌龟节点
rosrun turtlesim turtlesim_node在终端3中先配置环境变量
~/workspace/ros$ source devel/setup.bash再启动发布者
~/workspace/ros$ rosrun learning_topic velocity_publisher 输出信息如下
[ INFO] [1684324440.780789684]: Publsh turtle velocity command[0.50 m/s, 0.20 rad/s]
[ INFO] [1684324440.880933087]: Publsh turtle velocity command[0.50 m/s, 0.20 rad/s]
[ INFO] [1684324440.980945586]: Publsh turtle velocity command[0.50 m/s, 0.20 rad/s]小乌龟将做圆形运动
2.3、订阅者
1进入ROS1的工程目录
cd ~/workspace/ros/src/2创建功能包 已经创建过learning_topic不需要再创建
~/workspace/ros/src$ catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim如果重复创建将会输出如下信息提示文件已存在
catkin_create_pkg: error: File exists: /home/laoer/workspace/ros/src/learning_topic/CMakeLists.txt3编辑源码
cd ~/workspace/ros
vi src/learning_topic/src/pose_subscriber.cpp#include ros/ros.h
#include turtlesim/Pose.h// 接收到订阅的消息后会进入消息回调函数
void poseCallback(const turtlesim::Pose::ConstPtr msg)
{// 将接收到的消息打印出来ROS_INFO(Turtle pose: x:%0.6f, y:%0.6f, msg-x, msg-y);
}int main(int argc, char **argv)
{// 初始化ROS节点ros::init(argc, argv, pose_subscriber);// 创建节点句柄ros::NodeHandle n;// 创建一个Subscriber订阅名为/turtle1/pose的topic注册回调函数poseCallbackros::Subscriber pose_sub n.subscribe(/turtle1/pose, 10, poseCallback);// 循环等待回调函数ros::spin();return 0;
}4修改CMakeLists.txt
~/workspace/ros$ vi src/learning_topic/CMakeLists.txt添加需要编译生成的可执行文件规则和连接库 在## Build ##下添加
add_executable(pose_subscriber src/pose_subscriber.cpp)
target_link_libraries(pose_subscriber ${catkin_LIBRARIES})5编译
catkin_make编译输出
Base path: /home/laoer/workspace/ros
……
[100%] Built target pose_subscriber6运行 在终端1中启动节点管理器
roscore在终端2中启动小乌龟节点
rosrun turtlesim turtlesim_node在终端3中先配置环境变量
~/workspace/ros$ source devel/setup.bash再启动订阅者
~/workspace/ros$ rosrun learning_topic pose_subscriber 输出信息如下
[ INFO] [1684373591.045027979]: Turtle pose: x:7.060666, y:10.029119
[ INFO] [1684373591.061111496]: Turtle pose: x:7.060666, y:10.029119此时位置信息没有变化可以运行2.1中发布者来改变位置信息 在终端4中先配置环境变量
~/workspace/ros$ source devel/setup.bash再启动发布者
~/workspace/ros$ rosrun learning_topic velocity_publisher 在终端3中可以看到位置信息已改变
[ INFO] [1684373649.013267506]: Turtle pose: x:3.651149, y:9.681684
[ INFO] [1684373649.028763094]: Turtle pose: x:3.645919, y:9.6756302.4 节点结构
可以使用rqt_graph来打印当前的节点结构
2.5、话题消息
上面发布者和订阅者的示例中都使用的是已经定义好的信息如
~/workspace/ros$ rosmsg show turtlesim/Pose
float32 x
float32 y
float32 theta
float32 linear_velocity
float32 angular_velocity下面演示如何自定义话题信息 1定义msg文件 进入话题工程目录
~/workspace/ros$ cd src/learning_topic/创建保存消息文件的文件夹
~/workspace/ros/src/learning_topic$ mkdir msg创建消息文件Person.msg
~/workspace/ros/src/learning_topic$ vi Person.msg 内容如下
string name
uint8 age
uint8 sexuint8 unknown 0
uint8 male 1
uint8 female 22在package.xml中添加功能包依赖 在编译自定义消息时需要依赖消息生成的依赖包message_generation 在运行自定义消息时需要依赖运行的依赖包message_runtime 修改package.xml将关于message_generation和message_runtime注释打开即可
build_dependmessage_generation/build_depend
exec_dependmessage_runtime/exec_depend3C代码 订阅者相关代码
~/workspace/ros$ vi src/learning_topic/src/person_subscriber.cpp #include ros/ros.h
#include learning_topic/Person.h// 接收到订阅的消息后会进入消息回调函数
void personInfoCallback(const learning_topic::Person::ConstPtr msg)
{// 将接收到的消息打印出来ROS_INFO(Subcribe Person Info: name:%s age:%d sex:%d, msg-name.c_str(), msg-age, msg-sex);
}int main(int argc, char **argv)
{// 初始化ROS节点ros::init(argc, argv, person_subscriber);// 创建节点句柄ros::NodeHandle n;// 创建一个Subscriber订阅名为/person_info的topic注册回调函数personInfoCallbackros::Subscriber person_info_sub n.subscribe(/person_info, 10, personInfoCallback);// 循环等待回调函数ros::spin();return 0;
}发布者相关代码
~/workspace/ros$ vi src/learning_topic/src/person_publisher.cpp #include ros/ros.h
#include learning_topic/Person.hint main(int argc, char **argv)
{// ROS节点初始化ros::init(argc, argv, person_publisher);// 创建节点句柄ros::NodeHandle n;// 创建一个Publisher发布名为/person_info的topic消息类型为learning_topic::Person队列长度10ros::Publisher person_info_pub n.advertiselearning_topic::Person(/person_info, 10);// 设置循环的频率ros::Rate loop_rate(1);int count 0;while (ros::ok()){// 初始化learning_topic::Person类型的消息learning_topic::Person person_msg;person_msg.name Tom;person_msg.age 18;person_msg.sex learning_topic::Person::male;// 发布消息person_info_pub.publish(person_msg);ROS_INFO(Publish Person Info: name:%s age:%d sex:%d, person_msg.name.c_str(), person_msg.age, person_msg.sex);// 按照循环频率延时loop_rate.sleep();}return 0;
}4在CMakeLists.txt中添加编译选项
find_package(catkin REQUIRED COMPONENTS
……message_generation
)
add_message_files(FILESPerson.msg
)generate_messages(DEPENDENCIESstd_msgs
)
catkin_package(CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime
)add_executable(person_publisher src/person_publisher.cpp)
target_link_libraries(person_publisher ${catkin_LIBRARIES})
add_dependencies(person_publisher ${PROJECT_NAME}_generate_messages_cpp)add_executable(person_subscriber src/person_subscriber.cpp)
target_link_libraries(person_subscriber ${catkin_LIBRARIES})
add_dependencies(person_subscriber ${PROJECT_NAME}_generate_messages_cpp)5编译
~/workspace/ros$ catkin_make……
[ 46%] Generating Javascript code from learning_topic/Person.msg
[ 93%] Built target person_publisher
[100%] Built target person_subscriber6运行 在终端1中启动节点管理器
~/workspace/ros$ roscore在终端2中启动订阅者
~/workspace/ros$ source devel/setup.bash
~/workspace/ros$ rosrun learning_topic person_subscriber 在终端3中启动发布者
~/workspace/ros$ source devel/setup.bash
~/workspace/ros$ rosrun learning_topic person_publisher 终端2打印订阅者收到的信息
[ INFO] [1684377584.196850906]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1684377585.196714423]: Subcribe Person Info: name:Tom age:18 sex:1终端3打印发布者发送的信息
[ INFO] [1684377583.196183979]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1684377584.196358219]: Publish Person Info: name:Tom age:18 sex:17节点图很简单如下
3、服务模式 3.1 查看服务和数据
1列出所有的服务
~/workspace/ros$ rosservice list
/clear
……
/spawn
……2查看服务spawn产卵即在界面中生成一个新的小乌龟
~/workspace/ros$ rosservice info /spawn
Node: /turtlesim
URI: rosrpc://lesen-System-Product-Name:54203
Type: turtlesim/Spawn
Args: x y theta name3调用服务命令 rosservice call 下面的客户端示例的功能和这个命令类似调用服务多产生几个小乌龟
~/workspace/ros$ rosservice call /spawn 3 7 8 haha3.2、客户端
~/workspace/ros$ rosservice call /spawn 3 3 4 hah 1进入ROS1的工程目录
cd ~/workspace/ros/src/2创建功能包
~/workspace/ros/src$ catkin_create_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim3编辑源码
~/workspace/ros/src/learning_service/src$ vi turtle_spawn.cpp #include ros/ros.h
#include turtlesim/Spawn.hint main(int argc, char** argv)
{// 初始化ROS节点ros::init(argc, argv, turtle_spawn);// 创建节点句柄ros::NodeHandle node;// 发现/spawn服务后创建一个服务客户端连接名为/spawn的serviceros::service::waitForService(/spawn);ros::ServiceClient add_turtle node.serviceClientturtlesim::Spawn(/spawn);// 初始化turtlesim::Spawn的请求数据turtlesim::Spawn srv;srv.request.x 2.0;srv.request.y 2.0;srv.request.name turtle2;// 请求服务调用ROS_INFO(Call service to spwan turtle[x:%0.6f, y:%0.6f, name:%s], srv.request.x, srv.request.y, srv.request.name.c_str());add_turtle.call(srv);// 显示服务调用结果ROS_INFO(Spwan turtle successfully [name:%s], srv.response.name.c_str());return 0;
};4修改CMakeLists.txt 添加需要编译生成的可执行文件规则和连接库 在## Build ##下添加
add_executable(turtle_spawn src/turtle_spawn.cpp)
target_link_libraries(turtle_spawn ${catkin_LIBRARIES})5编译
~/workspace/ros$ catkin_make编译输出信息
[ 100%] Built target turtle_spawn6运行 在终端1中启动节点管理器
~/workspace/ros$ roscore在终端2中启动小乌龟 rosrun turtlesim turtlesim_node 在终端3中启动客户端
~/workspace/ros$ source devel/setup.bash
~/workspace/ros$ rosrun learning_service turtle_spawn 输出信息如下
[ INFO] [1684380205.381761081]: Call service to spwan turtle[x:2.000000, y:2.000000, name:turtle2]
[ INFO] [1684380205.401406453]: Spwan turtle successfully [name:turtle2]在小乌龟界面将会出现两个小乌龟
3.3、服务端
1进入ROS1的工程目录
cd ~/workspace/ros/src/2创建功能包 学习服务模式的功能包已经创建这里不需要再运行
~/workspace/ros/src$ catkin_create_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim3编辑源码
~/workspace/ros/src/learning_service/src$ vi turtle_command_server.cpp#include ros/ros.h
#include geometry_msgs/Twist.h
#include std_srvs/Trigger.hros::Publisher turtle_vel_pub;
bool pubCommand false;// service回调函数输入参数req输出参数res
bool commandCallback(std_srvs::Trigger::Request req,std_srvs::Trigger::Response res)
{pubCommand !pubCommand;// 显示请求数据ROS_INFO(Publish turtle velocity command [%s], pubCommandtrue?Yes:No);// 设置反馈数据res.success true;res.message Change turtle command state!return true;
}int main(int argc, char **argv)
{// ROS节点初始化ros::init(argc, argv, turtle_command_server);// 创建节点句柄ros::NodeHandle n;// 创建一个名为/turtle_command的server注册回调函数commandCallbackros::ServiceServer command_service n.advertiseService(/turtle_command, commandCallback);// 创建一个Publisher发布名为/turtle1/cmd_vel的topic消息类型为geometry_msgs::Twist队列长度10turtle_vel_pub n.advertisegeometry_msgs::Twist(/turtle1/cmd_vel, 10);// 循环等待回调函数ROS_INFO(Ready to receive turtle command.);// 设置循环的频率ros::Rate loop_rate(10);while(ros::ok()){// 查看一次回调函数队列ros::spinOnce();// 如果标志为true则发布速度指令if(pubCommand){geometry_msgs::Twist vel_msg;vel_msg.linear.x 0.5;vel_msg.angular.z 0.2;turtle_vel_pub.publish(vel_msg);}//按照循环频率延时loop_rate.sleep();}return 0;
}4修改CMakeLists.txt 添加需要编译生成的可执行文件规则和连接库 在## Build ##下添加
add_executable(turtle_command_server src/turtle_command_server.cpp)
target_link_libraries(turtle_command_server ${catkin_LIBRARIES})5编译
~/workspace/ros$ catkin_make编译输出信息
……
[ 100%] Built target turtle_command_server6运行 在终端1中启动节点管理器
~/workspace/ros$ roscore在终端2中启动小乌龟 rosrun turtlesim turtlesim_node 在终端3中启动服务器
~/workspace/ros$ source devel/setup.bash
~/workspace/ros$ rosrun learning_service turtle_spawn在终端4中使用rosservice call来调用服务
rosservice call /turtle_command终端3中的打印信息
[ INFO] [1684395192.110521550]: Ready to receive turtle command.
[ INFO] [1684395203.911182038]: Publish turtle velocity command [Yes]
[ INFO] [1684395245.311201634]: Publish turtle velocity command [No]流程说明 执行命令后将调用服务turtle_command然后执行对应的回调函数回调函数只控制pubCommand的真假值主循环会根据pubCommand的真假来决定是否发布消息
注小乌龟的运动是最终还是通过发布者Publisher发布名为/turtle1/cmd_vel的主题topic消息类型为控制小乌龟运动的消息geometry_msgs::Twist 节点关系如下
3.4、自定义服务数据
3.4.1 定义服务数据
创建描述服务数据的srv文件 1进入包目录 进入~/workspace/ros/src/learning_service中
cd ~/workspace/ros/src/learning_service2创建保存服务数据文件的目录srv
~/workspace/ros/src/learning_service$ mkdir srv3编辑服务数据文件Person.srv
~/workspace/ros/src/learning_service$ vi srv/Person.srv 内容如下注意“—”不是省略号是数据文件格式的一部分
string name
uint8 age
uint8 sexuint8 unknown 0
uint8 male 1
uint8 female 2---
string result4在package.xml中添加功能包依赖 和话题模式的自定义消息类似 build_dependmessage_generation/build_depend
exec_dependmessage_runtime/exec_depend5在CMakeLists.txt中添加编译选项 和话题模式的自定义消息类似
find_package(catkin REQUIRED COMPONENTS
……message_generation
)
add_service_files(FILESPerson.srv
)generate_messages(DEPENDENCIESstd_msgs
)catkin_package(CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime
)3.4.2 服务端
编辑服务端代码
~/workspace/ros/src/learning_service$ vi src/person_server.cpp#include ros/ros.h
#include learning_service/Person.h// service回调函数输入参数req输出参数res
bool personCallback(learning_service::Person::Request req,learning_service::Person::Response res)
{// 显示请求数据ROS_INFO(Person: name:%s age:%d sex:%d, req.name.c_str(), req.age, req.sex);// 设置反馈数据res.result OK;return true;
}int main(int argc, char **argv)
{// ROS节点初始化ros::init(argc, argv, person_server);// 创建节点句柄ros::NodeHandle n;// 创建一个名为/show_person的server注册回调函数personCallbackros::ServiceServer person_service n.advertiseService(/show_person, personCallback);// 循环等待回调函数ROS_INFO(Ready to show person informtion.);ros::spin();return 0;
}3.4.3 客户端
编辑客户端代码
~/workspace/ros/src/learning_service$ vi src/person_client.cpp#include ros/ros.h
#include learning_service/Person.hint main(int argc, char** argv)
{// 初始化ROS节点ros::init(argc, argv, person_client);// 创建节点句柄ros::NodeHandle node;// 发现/spawn服务后创建一个服务客户端连接名为/spawn的serviceros::service::waitForService(/show_person);ros::ServiceClient person_client node.serviceClientlearning_service::Person(/show_person);// 初始化learning_service::Person的请求数据learning_service::Person srv;srv.request.name Tom;srv.request.age 20;srv.request.sex learning_service::Person::Request::male;// 请求服务调用ROS_INFO(Call service to show person[name:%s, age:%d, sex:%d], srv.request.name.c_str(), srv.request.age, srv.request.sex);person_client.call(srv);// 显示服务调用结果ROS_INFO(Show person result : %s, srv.response.result.c_str());return 0;
};3.4.4 编译
1在CMakeLists.txt中添加服务端、客户端相关的编译规则
add_executable(person_server src/person_server.cpp)
target_link_libraries(person_server ${catkin_LIBRARIES})
add_dependencies(person_server ${PROJECT_NAME}_gencpp)add_executable(person_client src/person_client.cpp)
target_link_libraries(person_client ${catkin_LIBRARIES})
add_dependencies(person_client ${PROJECT_NAME}_gencpp)2编译
~/workspace/ros$ catkin_make编译输出
[ 80%] Built target person_server
[100%] Built target person_client3.4.5 运行
在终端1中启动服务器
~/workspace/ros$ rosrun learning_service person_server在终端2中多次执行客户端命令及打印信息如下
~/workspace/ros$ rosrun learning_service person_client
[ INFO] [1684397359.830399671]: Call service to show person[name:Tom, age:20, sex:1]
[ INFO] [1684397359.831655045]: Show person result : OK
~/workspace/ros$ rosrun learning_service person_client
[ INFO] [1684397360.439275903]: Call service to show person[name:Tom, age:20, sex:1]
[ INFO] [1684397360.440764700]: Show person result : OK终端1收到的信息如下
[ INFO] [1684397334.962962627]: Ready to show person informtion.
[ INFO] [1684397351.231455028]: Person: name:Tom age:20 sex:1
[ INFO] [1684397358.320771056]: Person: name:Tom age:20 sex:1
[ INFO] [1684397359.144605775]: Person: name:Tom age:20 sex:14、参数
ROS 参 数( parameters )机制用于获取任何节点保存在参数服务器中的信息类似全局变量。 方法是使用集中参数服务器( parameter server )维护一个变量集的值,包括整数、浮点数、字符串以及其他数据类型,每一个变量用一个较短的字符串标识 。由于允许节点主动查询其感兴趣的参数的值,它们适用于配置那些不会随时间频繁变更的信息。
4.1 rosparam
操作参数的命令
rosparam set设置参数rosparam get获取参数rosparam load从文件中加载参数rosparam dump将参数写入文件rosparam delete删除参数rosparam list列出所有的参数
示例1列出所有的参数
~/workspace/ros$ rosparam list输出
/rosdistro
/roslaunch/uris/host_lesen_system_product_name__46275
/rosversion
/run_id
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r示例2查看某个参数的值
~/workspace/ros$ rosparam get /turtlesim/background_b输出
2554.2 自定义参数文件
1进入ROS1的工程目录
cd ~/workspace/ros/src/2创建功能包
~/workspace/ros/src$ catkin_create_pkg learning_parameter roscpp rospy std_msgs geometry_msgs turtlesim3进入功能包目录
cd ~/workspace/ros/src/learning_parameter4创建保存参数文件的目录
mkdir config5编辑参数文件
~/workspace/ros/src/learning_parameter$ vi config/turtle_param.yaml background_b: 255
background_g: 86
background_r: 69
rosdistro: melodic
roslaunch:uris: {host_hcx_vpc__43763: http://hcx-vpc:43763/}
rosversion: 1.14.3
run_id: 077058de-a38b-11e9-818b-000c29d22e4d4.3 参数操作示例
1编辑源码
~/workspace/ros/src/learning_parameter$ vi src/parameter_config.cpp 注意古月居的示例源码中background_r需要改为/turtlesim/background_r否则小乌龟不会改变背景色 ros::param::get(/turtlesim/background_r, red);#include string
#include ros/ros.h
#include std_srvs/Empty.hint main(int argc, char **argv)
{int red, green, blue;// ROS节点初始化ros::init(argc, argv, parameter_config);// 创建节点句柄ros::NodeHandle node;// 读取背景颜色参数ros::param::get(/turtlesim/background_r, red);ros::param::get(/turtlesim/background_g, green);ros::param::get(/turtlesim/background_b, blue);ROS_INFO(Get Backgroud Color[%d, %d, %d], red, green, blue);// 设置背景颜色参数ros::param::set(/turtlesim/background_r, 255);ros::param::set(/turtlesim/background_g, 255);ros::param::set(/turtlesim/background_b, 255);ROS_INFO(Set Backgroud Color[255, 255, 255]);// 读取背景颜色参数ros::param::get(/turtlesim/background_r, red);ros::param::get(/turtlesim/background_g, green);ros::param::get(/turtlesim/background_b, blue);ROS_INFO(Re-get Backgroud Color[%d, %d, %d], red, green, blue);// 调用服务刷新背景颜色ros::service::waitForService(/clear);ros::ServiceClient clear_background node.serviceClientstd_srvs::Empty(/clear);std_srvs::Empty srv;clear_background.call(srv);sleep(1);return 0;
}2编译
~/workspace/ros$ catkin_make输出
[ 100%] Built target parameter_config3 运行 在终端1中启动节点管理器
roscore在终端2中启动小乌龟
rosrun turtlesim turtlesim_node在终端3中启动参数测试程序
~/workspace/ros$ source devel/setup.bash
~/workspace/ros$ rosrun learning_parameter parameter_config打印输出
[ INFO] [1684400198.204756094]: Get Backgroud Color[0, 14, -2147483648]
[ INFO] [1684400198.206004077]: Set Backgroud Color[255, 255, 255]
[ INFO] [1684400198.206633529]: Re-get Backgroud Color[255, 255, 255]
[ INFO] [1684400198.206846322]: waitForService: Service [/clear] has not been advertised, waiting...5、坐标
5.1 命令示例
1安装ros-melodic-turtle-tf 以小乌龟的坐标变换为例需要先安装一个软件
$ sudo apt install ros-melodic-turtle-tf2终端1运行节点管理器
$ roscore3终端2运行两个小乌龟自动跟随的demo
$ roslaunch turtle_tf turtle_tf_demo.launch 4终端3运行键盘控制节点
$ rosrun turtlesim turtle_teleop_key5坐标树查看
$ rosrun tf view_frames 输出信息
Listening to /tf for 5.0 seconds
Done Listening
dot - graphviz version 2.40.1 (20161225.0304)Detected dot version 2.40
frames.pdf generated在当前目录下生成文件frames.pdf 6坐标变换
$ rosrun tf tf_echo turtle1 turtle2输出
At time 1684405017.779
- Translation: [0.000, 0.000, 0.000]
- Rotation: in Quaternion [0.000, 0.000, 0.979, 0.205]in RPY (radian) [-0.000, -0.000, 2.728]in RPY (degree) [-0.000, -0.000, 156.306]
At time 1684405018.514
- Translation: [0.000, 0.000, 0.000]
- Rotation: in Quaternion [0.000, 0.000, 0.979, 0.205]in RPY (radian) [-0.000, -0.000, 2.728]in RPY (degree) [-0.000, -0.000, 156.306]
……7rviz可视化工具查看坐标
$ rosrun rviz rviz -d rospack find turtle_tf/rviz/turtle_rviz.rviz5.2 代码示例
1进入ROS1的工程目录
cd ~/workspace/ros/src/2创建功能包
~/workspace/ros/src$ catkin_create_pkg learning_tf roscpp rospy tf turtlesim3编辑源码 tf广播器
~/workspace/ros/src/learning_tf/src$ vi turtle_tf_broadcaster.cpp#include ros/ros.h
#include tf/transform_broadcaster.h
#include turtlesim/Pose.hstd::string turtle_name;void poseCallback(const turtlesim::PoseConstPtr msg)
{// 创建tf的广播器static tf::TransformBroadcaster br;// 初始化tf数据tf::Transform transform;transform.setOrigin( tf::Vector3(msg-x, msg-y, 0.0) );tf::Quaternion q;q.setRPY(0, 0, msg-theta);transform.setRotation(q);// 广播world与海龟坐标系之间的tf数据br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), world, turtle_name));
}int main(int argc, char** argv)
{// 初始化ROS节点ros::init(argc, argv, my_tf_broadcaster);// 输入参数作为海龟的名字if (argc ! 2){ROS_ERROR(need turtle name as argument); return -1;}turtle_name argv[1];// 订阅海龟的位姿话题ros::NodeHandle node;ros::Subscriber sub node.subscribe(turtle_name/pose, 10, poseCallback);// 循环等待回调函数ros::spin();return 0;
};tf监听器
~/workspace/ros/src/learning_tf/src$ cat turtle_tf_listener.cpp#include ros/ros.h
#include tf/transform_listener.h
#include geometry_msgs/Twist.h
#include turtlesim/Spawn.hint main(int argc, char** argv)
{// 初始化ROS节点ros::init(argc, argv, my_tf_listener);// 创建节点句柄ros::NodeHandle node;// 请求产生turtle2ros::service::waitForService(/spawn);ros::ServiceClient add_turtle node.serviceClientturtlesim::Spawn(/spawn);turtlesim::Spawn srv;add_turtle.call(srv);// 创建发布turtle2速度控制指令的发布者ros::Publisher turtle_vel node.advertisegeometry_msgs::Twist(/turtle2/cmd_vel, 10);// 创建tf的监听器tf::TransformListener listener;ros::Rate rate(10.0);while (node.ok()){// 获取turtle1与turtle2坐标系之间的tf数据tf::StampedTransform transform;try{listener.waitForTransform(/turtle2, /turtle1, ros::Time(0), ros::Duration(3.0));listener.lookupTransform(/turtle2, /turtle1, ros::Time(0), transform);}catch (tf::TransformException ex) {ROS_ERROR(%s,ex.what());ros::Duration(1.0).sleep();continue;}// 根据turtle1与turtle2坐标系之间的位置关系发布turtle2的速度控制指令geometry_msgs::Twist vel_msg;vel_msg.angular.z 4.0 * atan2(transform.getOrigin().y(),transform.getOrigin().x());vel_msg.linear.x 0.5 * sqrt(pow(transform.getOrigin().x(), 2) pow(transform.getOrigin().y(), 2));turtle_vel.publish(vel_msg);rate.sleep();}return 0;
};4配置CMakeLists.txt
add_executable(turtle_tf_broadcaster src/turtle_tf_broadcaster.cpp)
target_link_libraries(turtle_tf_broadcaster ${catkin_LIBRARIES})add_executable(turtle_tf_listener src/turtle_tf_listener.cpp)
target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES})5编译
cd ~/workspace/ros
~/workspace/ros$ catkin_make6运行 终端1运行节点管理器
$ roscore终端2运行小乌龟
$ rosrun turtlesim turtlesim_node终端3运行广播1
$ rosrun learning_tf turtle_tf_broadcaster __name:turtle1_tf_broadcaster /turtle1终端4运行广播2
$ rosrun learning_tf turtle_tf_broadcaster __name:turtle2_tf_broadcaster /turtle2终端5运行监听
$ rosrun learning_tf turtle_tf_listener终端6运行键盘控制
$ rosrun turtlesim turtle_teleop_key7效果 效果和命令示例一样
6、launch批量启动节点
6.1 说明
roslaunch可以实现自动启动ROS Master、通过XML文件实现多个节点的配置和启动
6.2 创建launch功能包
1进入ROS1的工程目录
cd ~/workspace/ros/src/2创建功能包
~/workspace/ros/src$ catkin_create_pkg learning_launch6.3 launch文件格式
roslaunch需要加载XML文件来读取各个节点格式如下
launchnode pkglearning_topic typeperson_subscriber nametalker outputscreen /node pkglearning_topic typeperson_publisher namelistener outputscreen /
/launch1launch根元素 2node节点 pkg节点所在的功能包名称 type可执行文件名称 name执行程序运行时的名称 output打印输出 3includelaunch文件嵌套
6.4 执行命令
~/workspace/ros$ roslaunch learning_launch simple.launch 输出
……
NODES
/
listener (learning_topic/person_publisher)
talker (learning_topic/person_subscriber)
ROS_MASTER_URIhttp://localhost:11311
process[talker-1]: started with pid [6649]
process[listener-2]: started with pid [6655]
[ INFO] [1684408582.094373243]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1684408583.094561611]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1684408583.095011334]: Subcribe Person Info: name:Tom age:18 sex:1
[ INFO] [1684408584.094552704]: Publish Person Info: name:Tom age:18 sex:1
[ INFO] [1684408584.094849697]: Subcribe Person Info: name:Tom age:18 sex:17、可视化工具
7.1 rqtrqt系列工具集
7.1 rqt_console日志输出工具 7.2 rqt_graph节点图 7.3 rqt_plot数据绘制 7.4 rqt_image_view图像渲染工具
不知道怎么安装
7.5 rqt_bag 7.6 Rviz三维可视化工具 7.7 Gazebo三维物理仿真平台 7.8 rqt_shell终端
rqt_shell
7.9 rqt_multiplot可视化多个2D图中的数值 7.10 rqt_logger_level配置 ROS 节点的日志级别 7.11 rqt_paramedit编辑参数服务 7.12 rqt_py_trees可视化py_trees行为树
行为树用来让机器人实现复杂任务
7.13 rqt_dep查看ROS包依赖