ROS学习
1、ROS终端指令
1.roscore 启动ROS的主节点管理器rosmaster
2.rosrun 用于运行某个功能包中的节点,其一般格式为rosrun [功能包名] [节点名]
3.rostopic 用于查看、发布和订阅ROS话题,使用rostopic list可以查看当前系统中所有的话题,使用rostopic echo <话题> 查看话题内容
4.rqt_graph 图形化显示当前系统活跃的节点以及节点之间的话题通讯关系
5.roslaunch <launch文件夹> <文件.launch> 运行launch文件
6.catkin_make 在工作区执行编译
7.echo -e 显示中文编码
8.chmod +x 文件名.py Python添加为可执行文件
9.add_executable(xx_node src/xx_node.cpp)
target_link_libraries(xx_node
${catkin_LIBRARIES}
) C++添加路径
2、Publish和Subscriber的C++实现
1.cd catkin_ws/src/ (catkin_ws为工作区名称)
2.catkin_create_pkg atr_pkg rospy roscpp std_msgs (<包名> <依赖项>)
3.在VSCode中src->atr_pkg中创建ma_node.cpp(节点的源码文件)
4.在CMakeLists.txt中添加:
add_executable(ma_node src/ma_node.cpp)
target_link_libraries(ma_node
${catkin_LIBRARIES}
)
5.Publish:
#include <ros/ros.h> // 包含ROS库头文件
#include <std_msgs/String.h> // 包含标准字符串消息类型头文件
int main(int argc, char *argv[])
{
ros::init(argc, argv, "chao_node"); // 初始化ROS节点,节点名为"chao_node"
ros::NodeHandle nh; // 创建ROS节点句柄
ros::Publisher pub = nh.advertise<std_msgs::String>("Chat", 10); // 创建一个发布者,发布到名为"Chat"的主题,队列大小为10
ros::Rate loop_rate(10); // 设置循环频率为10Hz
while(ros::ok()) // 当ROS节点正常运行时
{
printf("Hello ROS\n"); // 打印"Hello ROS"到控制台
std_msgs::String msg; // 创建一个标准字符串消息
msg.data = "Hello ROS I am coming!"; // 设置消息内容
pub.publish(msg); // 发布消息
loop_rate.sleep(); // 按照设定的频率休眠,以控制循环速率
}
return 0; // 返回0,表示程序正常结束
}
6.Subscriber:
#include <ros/ros.h> // 包含ROS核心库
#include <std_msgs/String.h> // 包含标准字符串消息类型
// 回调函数,处理来自 "Chat" 主题的消息
void chao_callback(std_msgs::String msg)
{
ROS_INFO( msg.data.c_str()); // 使用ROS_INFO打印消息内容
}
// 回调函数,处理来自 "Chat2" 主题的消息
void yao_callback(std_msgs::String msg)
{
ROS_WARN( msg.data.c_str()); // 使用ROS_WARN打印消息内容
}
int main(int argc, char **argv)
{
setlocale(LC_ALL, ""); // 设置本地化环境,确保ROS消息中的非ASCII字符能正确显示
ros::init(argc, argv, "ma_node"); // 初始化ROS节点,命名为 "ma_node"
ros::NodeHandle nh; // 创建ROS节点句柄
// 创建订阅者,订阅 "Chat" 主题,缓冲区大小为10,回调函数为chao_callback
ros::Subscriber sub = nh.subscribe("Chat", 10, chao_callback);
// 创建订阅者,订阅 "Chat2" 主题,缓冲区大小为10,回调函数为yao_callback
ros::Subscriber sub_2 = nh.subscribe("Chat2", 10, yao_callback);
ros::Rate loop_rate(10); // 设置循环频率为10Hz
// 主循环,当ROS节点正常运行时执行
while (ros::ok())
{
ros::spinOnce(); // 处理所有待处理的回调函数
}
return 0; // 返回0,表示程序正常结束
}
7.rosrun atr_pkg ma_node.cpp 运行节点
8.roslist echo Chat 打印主题信息
9.rqt_graph 图形化显示当前系统活跃的节点以及节点之间的话题通讯关系
3、Launch文件
1.在任意软件包下创建launch文件夹->文件.launch
2.
<launch>
<!-- 启动名为 "yao_node" 的节点,该节点属于 "ssr_pkg" 包,类型为 "yao_node" -->
<node pkg="ssr_pkg" type="yao_node" name="yao_node" />
<!-- 启动名为 "chao_node" 的节点,该节点属于 "ssr_pkg" 包,类型为 "chao_node",并让此节点信息输出在终端 -->
<node pkg="ssr_pkg" type="chao_node" name="chao_node" launch-prefix="gnome-terminal -e"/>
<!-- 启动名为 "ma_node" 的节点,该节点属于 "atr_okg" 包,类型为 "ma_node",并将输出(ROS_WARN不受该属性控制)显示在屏幕上 -->
<node pkg="atr_okg" type="ma_node" name="ma_node" output="screen"/>
</launch>
3.运行launch文件:roslaunch <launch文件夹> <文件.launch>
4、Publish和Subscriber的Python实现
1.在catkin_ws/src/创建Package软件包:catkin_create_pkg ssrpytest_pkg rospy std_msgs (<包名> <依赖项>)
2.在catkin_ws/编译:catkin_make,在ssrpytest_pkg中创建scripts->publish.py
3.Publish:
#!/usr/bin/env python3
#codeing=utf-8
import rospy # 导入 ROS Python 客户端库
from std_msgs.msg import String # 导入标准消息类型 String
if __name__ == '__main__':
rospy.init_node('publish_node') # 初始化 ROS 节点,命名为 'publish_node'
rospy.logwarn('publish node started') # 记录警告信息,表示节点已启动
pub = rospy.Publisher('py_chatter', String, queue_size=10) # 创建一个发布者,发布到名为 'py_chatter' 的主题,消息类型为 String,队列大小为 10
rate = rospy.Rate(10) # 设置循环频率为 10 Hz
while not rospy.is_shutdown(): # 当 ROS 节点未关闭时,循环执行
rospy.loginfo("I am py_chatter") # 记录信息,表示当前节点正在运行
msg = String() # 创建一个 String 类型的消息对象
msg.data = "Hello, I am py_chatter!" # 设置消息内容
pub.publish(msg) # 发布消息
rate.sleep() # 按照设定的频率休眠,以控制循环的执行速度
4.Subscriber:
#!/usr/bin/env python3
#coding=utf-8
import rospy # 导入 ROS Python 客户端库
from std_msgs.msg import String # 导入标准消息类型 String
def callback(msg):
"""
回调函数,当接收到 "py_chatter" 主题的消息时执行
:param msg: 接收到的消息
"""
rospy.loginfo(msg.data) # 记录接收到的消息内容
def callback_copy(msg):
"""
回调函数,当接收到 "py_chatter_copy" 主题的消息时执行
:param msg: 接收到的消息
"""
rospy.logwarn(msg.data) # 记录警告信息,表示接收到的消息内容
if __name__ == '__main__':
rospy.init_node("subscriber") # 初始化 ROS 节点,命名为 "subscriber"
# 创建一个订阅者,订阅名为 "py_chatter" 的主题,消息类型为 String,回调函数为 callback,队列大小为 10
sub = rospy.Subscriber("py_chatter", String, callback, queue_size=10)
# 创建一个订阅者,订阅名为 "py_chatter_copy" 的主题,消息类型为 String,回调函数为 callback_copy,队列大小为 10
sub_copy = rospy.Subscriber("py_chatter_copy", String, callback_copy, queue_size=10)
rospy.spin() # 进入事件循环,等待消息到达
5.初始创建的文件没有执行权,在~/catkin_ws/src/ssrpytest_pkg/scripts执行chmod +x publish.py
6.rosrun ssrpytest_pkg publish.py 运行节点
7.launch运行:
<launch>
<!-- 启动名为 "public" 的节点,该节点属于 "ssrpytest_pkg" 包,类型为 "public.py" -->
<node pkg="ssrpytest_pkg" type="public.py" name="public" />
<!-- 启动名为 "public_copy" 的节点,该节点属于 "ssrpytest_pkg" 包,类型为 "public_copy.py" -->
<node pkg="ssrpytest_pkg" type="public_copy.py" name="public_copy"/ >
<!-- 启动名为 "subcriber" 的节点,该节点属于 "atrpytest_pkg" 包,类型为 "subcriber.py",并在新的 gnome-terminal 中运行 -->
<node pkg="atrpytest_pkg" type="subcriber.py" name="subcriber" launch-prefix="gnome-terminal -e"/>
</launch>
5、机器人运动控制C++实现
1.新建软件包和节点:cd catkin_ws/src/->catkin_create_pkg vel_pkg roscpp rospy geomrtry_msgs(包含了速度类型的软件包)
2.VSCode中创建节点vel_node.cpp
3.
#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
// 主函数,程序入口
int main(int argc, char *argv[])
{
// 初始化ROS节点,节点名为"vel_node"
ros::init(argc, argv, "vel_node");
// 创建ROS节点句柄
ros::NodeHandle n;
// 创建一个发布者,发布消息类型为geometry_msgs::Twist,话题名为"cmd_vel",队列大小为1000
ros::Publisher vel_pub = n.advertise<geometry_msgs::Twist>("cmd_vel", 1000);
// 创建一个geometry_msgs::Twist类型的消息对象
geometry_msgs::Twist vel_msg;
// 设置线性速度和角速度
vel_msg.linear.x = 0.1;
vel_msg.linear.y = 0;
vel_msg.linear.z = 5;
vel_msg.angular.x = 0;
vel_msg.angular.y = 0;
vel_msg.angular.z = 5;
// 设置循环频率为30Hz
ros::Rate r(30);
// 主循环,当ROS节点正常运行时执行
while (ros::ok())
{
// 发布速度消息
vel_pub.publish(vel_msg);
// 按照设定的频率休眠
r.sleep();
}
// 程序正常结束返回0
return 0;
}
4.在CMake里添加路径,Ctrl+Shift+B编译
5.roslaunch wpr_simulation wpb_simple.launch 打开仿真
6.rosrun vel_pkg vel_node 运行节点
6、机器人运动控制Python实现
1.新建软件包和节点:cd catkin_ws/src/->catkin_create_pkg vel_pkg roscpp rospy geomrtry_msgs(包含了速度类型的软件包)
2.VSCode中创建scripts->vel_node.py
3.cd catkin_ws/src/velpy_pkg/scripts->chmod +x vel_node.py 可执行文件
4.
#!/usr/bin/env python3
#coding=utf-8
import rospy
from geometry_msgs.msg import Twist
if __name__ == '__main__':
# 初始化ROS节点,节点名为'velpy_mode'
rospy.init_node('velpy_mode')
# 创建一个发布者,发布消息到'/cmd_vel'话题,消息类型为Twist,队列大小为10
vel_pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
# 创建一个Twist消息对象
vel_msg = Twist()
# 设置线性速度,x方向为0.5,y和z方向为0.0
vel_msg.linear.x = 0.5
vel_msg.linear.y = 0.0
vel_msg.linear.z = 0.0
# 设置角速度,x和y方向为0.0,z方向为0.5
vel_msg.angular.x = 0.0
vel_msg.angular.y = 0.0
vel_msg.angular.z = 0.5
# 设置发布频率为30Hz
rate = rospy.Rate(30)
# 循环发布速度消息,直到节点被关闭
while not rospy.is_shutdown():
vel_pub.publish(vel_msg)
rate.sleep()
5.roslaunch wpr_simulation wpb_simple.launch 打开仿真
6.rosrun vel_pkg vel_node.py 运行节点
7、获取激光雷达数据
1.cd catkin_ws->catkin_creat_pkg lidar_pkg roscpp rospy sensor_msgs
2.C++:
#include "ros/ros.h"
#include "sensor_msgs/LaserScan.h"
// 回调函数,处理激光雷达数据
void lidar_callback(const sensor_msgs::LaserScan msg)
{
float fMidDist = msg.ranges[180];
ROS_INFO("ranges[180] = %f",fMidDist);
}
// 主函数,初始化ROS节点并订阅激光雷达数据
int main(int argc, char **argv)
{
setlocale(LC_ALL, "");
ros::init(argc, argv, "lidar_node");
ros::NodeHandle n;
ros::Subscriber lidar_sub = n.subscribe("scan", 10, &lidar_callback);
ros::spin();
return 0;
}
3.Python:
#!/usr/bin/env python3
import rospy
from sensor_msgs.msg import LaserScan
# 回调函数,处理激光雷达数据
def lidar_callback(msg):
dist = msg.ranges[180]
rospy.loginfo("range= %f",dist)
# 主函数,初始化节点并订阅激光雷达数据
if __name__ == "__main__":
rospy.init_node("lidarpy_node")
lidarpy_sub=rospy.Subscriber("scan", LaserScan, lidar_callback, queue_size=10)
rospy.spin()