ros基础知识总结
ros基础总结
·
目录
ros基础总结
1.
创建工作空间并初始化
创建功能包
优先查找环境变量中的最前面的工作空间
2.
话题编程 和自定义msg并配置
服务编程 和自定义srv并配置
动作编程 和自定义action并配置
分布式通信
3.
launch文件
tf坐标转换 和两个小乌龟跟随
rqt工具 rqt_console rqt_graph rqt_plot rqt_reconfigure
rviz 数据可视化 插件机制 机器人模型 坐标 运动规划 导航 点云 图像 slam
gazebo 三维物理仿真环境
4.
创建模型并控制
将模型添加到gazebo中
创建Gazebo仿真环境
5.
图像标定
ros和opencv之间的转换
视觉移动物体识别 二维码识别
科大讯飞语音识别 合成和智能语音助手(交互)
6.
SLAM建图
导航过程中同步SLAM构建地图
moveit
ros常用命令
catkin_create_pkg 创建包
roscd
rosls
rospack find
rosnode list 列出所有正在运行的节点
rosnode info package 显示某个节点信息
rosrun package 运行某个包
rostopic list 列出当前所有topic
rostopic info 显示某个topic的属性信息
rostopic type 显示某个topic的类型
rostopic echo 显示某个topic的内容
rostopic pub -r 10 [topic] [msg_type] --[args] 向某个topic发布内容
rosservice list 输出可用服务的信息
rosservice info 显示某个service的属性信息
rosservice call 调用带参数的服务
rosservice type 输出服务类型
rosservice find 依据类型寻找服务find services by service type
rosservice uri 输出服务的ROSRPC uri
rosmsg list 列出所有msg
rosmsg show 显示某个msg内容
rossrv show 显示某个srv内容
rosparam set param_key param_name 设置参数
rosparam get param_key 获取参数
rosparam load file_name 从文件读取参数
rosparam dump file_name 向文件中写入参数
rosparam delete param_key 删除参数
rosparam list 列出参数名
创建工作空间
创建工作空间
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws
编译工作空间
catkin_make
设置环境变量
source devel/setup.bash
检查环境变量
echo $ROS_PACKAGE_PATH
创建功能包
catkin_create_pkg learning rospy roscpp std_msgs
编译功能包
cd ~/catkin_ws
catkin_make
source ~/catkin_ws/devel/setup.bash
编译制定功能包
catkin_make -DCATKIN_WHITELIST_PACKAGES="包名"
话题编程
话题编程流程
- 创建发布者
- 创建订阅者
- 添加编译选项
- 运行可执行文件
如何实现一个发布者
1.初始化ROS节点
2.向ROS Master注册节点信息,包括发布的话题名和话题中的消息类型
3.按一定频率循环发布消息
/**
* 该例程将发布chatter话题,消息类型String
* talker.cpp
*/
#include <sstream>
#include "ros/ros.h"
#include "std_msgs/String.h"
int main(int argc, char **argv)
{
// ROS节点初始化
ros::init(argc, argv, "talker");
// 创建节点句柄
ros::NodeHandle n;
// 创建一个Publisher,发布名为chatter的topic,消息类型为std_msgs::String
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("%s", msg.data.c_str());
chatter_pub.publish(msg);
// 循环等待回调函数
ros::spinOnce();
// 按照循环频率延时
loop_rate.sleep();
++count;
}
return 0;
}
如何实现一个订阅者
- 初始化一个ROS节点
- 订阅需要的话题
- 循环等待话题消息,接收到消息后进入回调函数
- 在回调函数中完成消息处理
/**
* 该例程将订阅chatter话题,消息类型String
* listener.cpp
*/
#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)
{
// 初始化ROS节点
ros::init(argc, argv, "listener");
// 创建节点句柄
ros::NodeHandle n;
// 创建一个Subscriber,订阅名为chatter的topic,注册回调函数chatterCallback
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
// 循环等待回调函数
ros::spin();
return 0;
}
如何编译代码
- 设置需要编译的代码和生成的可执行文件
- 设置链接库
- 设置依赖
在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(talker ${PROJECT_NAME}_generate_messages_cpp)
运行代码
1.启动roscore
2.设置环境变量
source ~/catkin_ws/devel/setup.bash
3.运行发布者
rosrun learning talker
4.运行订阅者
rosrun learning listener
自定义msg话题消息
话题person.msg数据定义
string name
uint8 sex
uint8 age
uint8 unknown=0
uint8 male=1
uint8 female=2
1.定义msg文件
2.在package.xml中添加功能包依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
3.在CMakeLists.txt中添加编译选项
find_package( …… message_generation)
catkin_package(CATKIN_DEPENDS geometry_msgs roscpp
rospy std_msgs message_runtime)
add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)
注:部分ros版本中的exec_depend需要改成run_depend
服务编程
服务编程流程
- 创建服务器
- 创建客户端
- 添加编译选项
- 运行可执行程序
AddTwoInts.srv 数据格式
int64 a
int64 b
---
int64 sum
1.定义srv文件
2.在package.xml中添加功能包依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
3.在CMakeLists.xml中添加编译选项
find_package( …… message_generation)
catkin_package(CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs message_runtime)
add_service_files(FILES AddTwoInts.srv)
generate_messages(DEPENDENCIES std_msgs)
如何实现一个服务器
- 初始化ROS节点
- 创建Server实例
- 循环等待服务请求,进入回调函数
- 在回调函数中完成服务功能的处理,并反馈应答数据
/**
* AddTwoInts Server
*/
#include "ros/ros.h"
#include "learning_communication/AddTwoInts.h"
// service回调函数,输入参数req,输出参数res
bool add(learning_communication::AddTwoInts::Request &req,
learning_communication::AddTwoInts::Response &res)
{
// 将输入参数中的请求数据相加,结果放到应答变量中
res.sum = req.a + req.b;
ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
ROS_INFO("sending back response: [%ld]", (long int)res.sum);
return true;
}
int main(int argc, char **argv)
{
// ROS节点初始化
ros::init(argc, argv, "add_two_ints_server");
// 创建节点句柄
ros::NodeHandle n;
// 创建一个名为add_two_ints的server,注册回调函数add()
ros::ServiceServer service = n.advertiseService("add_two_ints", add);
// 循环等待回调函数
ROS_INFO("Ready to add two ints.");
ros::spin();
return 0;
}
如何实现一个客户端
- 初始化ROS节点
- 创建一个Client实例
- 发布服务请求数据
- 等待Server处理之后的应答结果
/**
* AddTwoInts Client
*/
#include <cstdlib>
#include "ros/ros.h"
#include "learning_communication/AddTwoInts.h"
int main(int argc, char **argv)
{
// ROS节点初始化
ros::init(argc, argv, "add_two_ints_client");
// 从终端命令行获取两个加数
if (argc != 3)
{
ROS_INFO("usage: add_two_ints_client X Y");
return 1;
}
// 创建节点句柄
ros::NodeHandle n;
// 创建一个client,请求add_two_int service,service消息类型是learning_communication::AddTwoInts
ros::ServiceClient client = n.serviceClient<learning_communication::AddTwoInts>("add_two_ints");
// 创建learning_communication::AddTwoInts类型的service消息
learning_communication::AddTwoInts srv;
srv.request.a = atoll(argv[1]);
srv.request.b = atoll(argv[2]);
// 发布service请求,等待加法运算的应答结果
if (client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
return 0;
}
编译代码
- 设置需要编译的代码和生成的可执行文件
- 设置链接库
- 设置依赖
add_executable(server src/server.cpp)
target_link_libraries(server ${catkin_LIBRARIES})
add_dependencies(server ${PROJECT_NAME}_gencpp)
add_executable(client src/client.cpp)
target_link_libraries(client ${catkin_LIBRARIES})
add_dependencies(client ${PROJECT_NAME}_gencpp)
运行可执行文件
1.启动roscore
2.设置环境变量
source ~/catkin_ws/devel/setup.bash
3.运行服务端
rosrun learning server
4.运行客户端
rosrun learning client 3 5
动作编程
自定义动作消息
DoDishes.action文件格式信息
# 定义目标信息
uint32 dishwasher_id # Specify which dishwasher we want to use
---
# 定义结果信息
uint32 total_dishes_cleaned
---
# 定义周期反馈的信息
float32 percent_complete
1.定义action文件
2.在package.xml中添加功能包依赖
<build_depend>actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<exec_depend>actionlib</exec_depend>
<exec_depend>actionlib_msgs</exec_depend>
3.在CMakeLists.txt中添加编译选项
find_package(catkin REQUIRED actionlib_msgs actionlib)
add_action_files(DIRECTORY action FILES DoDishes.action)
generate_messages(DEPENDENCIES std_msgs actionlib_msgs)
实现一个动作服务器
- 初始化ROS节点
- 创建动作服务器实例
- 启动服务器,等待动作请求
- 在回调函数中完成动作服务功能的处理,并反馈进度信息
- 动作完成,发送结束信息
#include <ros/ros.h>
#include <actionlib/server/simple_action_server.h>
#include "learning_communication/DoDishesAction.h"
typedef actionlib::SimpleActionServer<learning_communication::DoDishesAction> Server;
// 收到action的goal后调用该回调函数
void execute(const learning_communication::DoDishesGoalConstPtr& goal, Server* as)
{
ros::Rate r(1);
learning_communication::DoDishesFeedback feedback;
ROS_INFO("Dishwasher %d is working.", goal->dishwasher_id);
// 假设洗盘子的进度,并且按照1hz的频率发布进度feedback
for(int i=1; i<=10; i++)
{
feedback.percent_complete = i * 10;
as->publishFeedback(feedback);
r.sleep();
}
// 当action完成后,向客户端返回结果
ROS_INFO("Dishwasher %d finish working.", goal->dishwasher_id);
as->setSucceeded();
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "do_dishes_server");
ros::NodeHandle n;
// 定义一个服务器
Server server(n, "do_dishes", boost::bind(&execute, _1, &server), false);
// 服务器开始运行
server.start();
ros::spin();
return 0;
}
实现一个动作客户端
- 初始化ROS节点
- 创建动作客户端实例
- 连接动作服务端
- 发送动作目标
- 根据不同的服务端反馈处理回调函数
#include <actionlib/client/simple_action_client.h>
#include "learning_communication/DoDishesAction.h"
typedef actionlib::SimpleActionClient<learning_communication::DoDishesAction> Client;
// 当action完成后会调用该回调函数一次
void doneCb(const actionlib::SimpleClientGoalState& state,
const learning_communication::DoDishesResultConstPtr& result)
{
ROS_INFO("Yay! The dishes are now clean");
ros::shutdown();
}
// 当action激活后会调用该回调函数一次
void activeCb()
{
ROS_INFO("Goal just went active");
}
// 收到feedback后调用该回调函数
void feedbackCb(const learning_communication::DoDishesFeedbackConstPtr& feedback)
{
ROS_INFO(" percent_complete : %f ", feedback->percent_complete);
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "do_dishes_client");
// 定义一个客户端
Client client("do_dishes", true);
// 等待服务器端
ROS_INFO("Waiting for action server to start.");
client.waitForServer();
ROS_INFO("Action server started, sending goal.");
// 创建一个action的goal
learning_communication::DoDishesGoal goal;
goal.dishwasher_id = 1;
// 发送action的goal给服务器端,并且设置回调函数
client.sendGoal(goal, &doneCb, &activeCb, &feedbackCb);
ros::spin();
return 0;
}
编译代码
- 设置需要编译的代码和生成的可执行文件
- 设置链接库
- 设置依赖
add_executable(DoDishes_client src/DoDishes_client.cpp)
target_link_libraries( DoDishes_client ${catkin_LIBRARIES})
add_dependencies(DoDishes_client ${${PROJECT_NAME}_EXPORTED_TARGETS})
add_executable(DoDishes_server src/DoDishes_server.cpp)
target_link_libraries( DoDishes_server ${catkin_LIBRARIES})
add_dependencies(DoDishes_server ${${PROJECT_NAME}_EXPORTED_TARGETS})
运行可执行文件
1.启动roscore
2.设置环境变量
source ~/catkin_ws/devel/setup.bash
3.运行服务端
rosrun learning_communication DoDishes_server
4.运行客户端
rosrun learning_communication DoDishes_client
ros分布式通信
首先需要确定ROS多机系统中的所有计算机处于同一网络,然后分别在计算机hcx-pc、raspi2上使用ifconfig
命令查看计算机的局域网IP地址。
分别在两台计算机系统的/etc/hosts
文件中加入对方的IP地址和对应的计算机名:
# @hcx-pc,/etc/hosts
192.168.31.14 raspi2
# @raspi2,/etc/hosts
192.168.31.198 hcx-pc
设置完毕后,分别在两台计算机上使用ping
命令测试网络是否连通。
# @hcx-pc
ping raspi2
# @raspi2
ping hcx-pc
如果双向网络都畅通,就说明底层网络的通信已经没有问题,接下来设置ROS相关的环境变量。
设置ROS_MASTER_URI
因为系统中只能存在一个Master,所以从机raspi2需要知道Master的位置。ROS Master的位置可以使用环境变量ROS_MASTER_URI进行定义,在从机raspi2上使用如下命令设置ROS_MASTER_URI:
export ROS_MASTER_URI=http://hcx-pc:11311
但是以上设置只能在输入的终端中生效,为了让所有打开的终端都能识别,最好使用如下命令将环境变量的设置加入终端额配置文件中。
echo ''export ROS_MASTER_URI=http://hcx-pc:11311'' >> ~/.bashrc
更多推荐
所有评论(0)