节点
1
2
3
4
5
ros2 run <pkg_name> <exe_name>
ros2 node list
ros2 node info <node_name>
ros2 run <pkg_name> <exe_name> --ros-args --remap __node:=my_turtle #重命名
ros2 run example_parameters_rclcpp parameters_basic --ros-args -p rcl_log_revel:10 #设置参数
功能包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sudo apt install ros-<version>-pkg-name #安装获取
#上面这样操作会直接放进去系统目录,不需要手动source
create Create a new ROS2 package
executables Output a list of package specific executables
list Output a list of available packages
prefix Output the prefix path of a package
xml Output the XML of the package manifest or a specific tag
ros2 pkg create <pkg-name> --build-type {cmake,ament_cmake,maent_python} --dependencies <依赖的名字>
ros2 pkg execultables
ros2 pkg list # 列出所有包的名字
ros2 pkg prefix <pkg-name>
ros2 pkg xml
Colcon
1
2
3
4
5
6
7
8
9
colcon build
source install/setup.bash
ros2 run
colcon build --packages-select YOUR_PKG_NAME #只编译一个包
colcon build --packages-select YOUR_PNG_NAME --cmake-args -DBUILD_TESTING=0 #不编译测试单元
colcon test #运行编译的包的测试
colcon build --symlink-install #允许通过更改src下的部分文件来更改install
colcon build --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
ln -s build/compile_commands.json .
rclcpp & rclpy
1
2
3
4
5
6
7
8
ros2 pkg create example_cpp --build-type ament_cmake --dependencies rclcpp
# 需要学会如何写CMakeLists
colcon build
source install/setup.bash
ros2 run <pkg-name>
# 这里只是简单的做了两个实例。
colcon
1
2
3
# 这里面应该是有很多知识的,不过,这里不说,后期补上
节点发现与多机通信
1
2
3
4
5
6
#linux 上 0-101 215-232可以安全使用
这里有一个域ID和UDP端口计算器的东西,我其实还灭有理解是怎么进行互相转换的
ZeroMQ
PyZMQ
FastDDS
话题与服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 话题与接口
# GUI工具
rqt_graph
ros2 topic -h
ros2 topic list
ros2 topic list -t #-t 表示查看消息类型,默认不显示
ros2 topic echo <topic_name> #打印实时话题内容
ros2 topic info <topic_name> #查看话题信息
ros2 interface show <msg_type> #查看消息类型
ros2 topic pub <topic_name> <msg_type> arg #会一直loop发送arg
Publisher
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "rclcpp/init_options.hpp"
#include "rclcpp/logging.hpp"
#include "rclcpp/publisher.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rclcpp/timer.hpp"
#include "rclcpp/utilities.hpp"
#include <chrono>
#include <memory>
#include "std_msgs/msg/detail/string__struct.hpp"
#include "std_msgs/msg/string.hpp"
class TopicPublisher01: public rclcpp::Node
{
public:
TopicPublisher01(std::string name):Node(name){
RCLCPP_INFO(this->get_logger(),"我是%s",name.c_str());
command_publisher_ = this->create_publisher<std_msgs::msg::String>("command",10);
timer_ = this->create_wall_timer(std::chrono::milliseconds(500),std::bind(&TopicPublisher01::timer_callback,this));
}
private:
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr command_publisher_;
rclcpp::TimerBase::SharedPtr timer_;
void timer_callback(){
std_msgs::msg::String message;
message.data = "forward";
RCLCPP_INFO(this->get_logger(),"Publishing:'%s'",message.data.c_str());
command_publisher_->publish(message);
}
};
int main(int argc,char **argv){
rclcpp::init(argc, argv);
auto node = std::make_shared<TopicPublisher01>("topic_publisher_01");
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
Subscribe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "rclcpp/rclcpp.hpp"
#include <functional>
#include <memory>
#include <rclcpp/utilities.hpp>
#include "std_msgs/msg/string.hpp"
class TopicSubscribe01: public rclcpp::Node{
public:
TopicSubscribe01(std::string name):Node(name){
RCLCPP_INFO(this->get_logger(),"大家好,我是%s",name.c_str());
command_subscribe_ = this->create_subscription<std_msgs::msg::String>("command" , 10, std::bind(&TopicSubscribe01::command_callback,this,std::placeholders::_1));
}
private:
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr command_subscribe_;
void command_callback(const std_msgs::msg::String::SharedPtr msg){
double speed = 0.0f;
if(msg->data=="forward"){
speed = 0.2f;
}
RCLCPP_INFO(this->get_logger(),"get[%s]指令,发送speed%f",msg->data.c_str(),speed);
}
};
int main(int argc , char **argv){
rclcpp::init(argc, argv);
auto node = std::make_shared<TopicSubscribe01>("topic_subscribe_01");
rclcpp::spin(node);
rclcpp::shutdown();
return 0 ;
}
服务通信
1
2
3
4
5
ros2 service list
ros2 service call <service_name> <impl_type> <params> #调用服务
ros2 service type <service_name> #查看接口类型
ros2 service find <impl_type> #通过接口查找服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# serveice_client
#include "rclcpp/logging.hpp"
#include "rclcpp/node.hpp"
#include "rclcpp/rclcpp.hpp"
#include <chrono>
#include <example_interfaces/srv/detail/add_two_ints__struct.hpp>
#include <memory>
#include <rclcpp/client.hpp>
#include <rclcpp/utilities.hpp>
#include "example_interfaces/srv/add_two_ints.hpp"
class ServiceClient01: public rclcpp::Node{
public:
ServiceClient01(std::string name):rclcpp::Node(name){
RCLCPP_INFO(this->get_logger(),"%s节点已经启动",name.c_str());
client_ = this->create_client<example_interfaces::srv::AddTwoInts>("add_");
}
void send_request(int a,int b){
RCLCPP_INFO(this->get_logger(),"计算%d+%d",a,b);
while(!client_->wait_for_service(std::chrono::seconds(1))){
if(!rclcpp::ok()){
RCLCPP_ERROR(this->get_logger(),"等待服务的过程被打断");
return;
}
RCLCPP_INFO(this->get_logger(),"等待服务上线中");
}
auto request = std::make_shared<example_interfaces::srv::AddTwoInts_Request>();
request->a = a;
request->b = b;
client_->async_send_request(request,std::bind(&ServiceClient01::result_callback_,this,std::placeholders::_1));
}
private:
rclcpp::Client<example_interfaces::srv::AddTwoInts>:: SharedPtr client_;
void result_callback_(
rclcpp::Client<example_interfaces::srv::AddTwoInts> ::SharedFuture result_future
){
auto response = result_future.get();
RCLCPP_INFO(this->get_logger(),"计算结果: %ld",response->sum);
}
};
int main(int argc,char **argv){
rclcpp::init(argc, argv);
auto node = std::make_shared<ServiceClient01>("Service_client_01");
node->send_request(5, 6);
rclcpp::spin(node);
rclcpp::shutdown();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#service_server
#include "rclcpp/rclcpp.hpp"
#include <example_interfaces/srv/detail/add_two_ints__struct.hpp>
#include <functional>
#include <memory>
#include <rclcpp/context.hpp>
#include <rclcpp/init_options.hpp>
#include <rclcpp/logging.hpp>
#include <rclcpp/node.hpp>
#include <rclcpp/service.hpp>
#include "example_interfaces/srv/add_two_ints.hpp"
class ServiceServer01: public rclcpp::Node{
public:
ServiceServer01(std::string name):rclcpp::Node(name){
RCLCPP_INFO(this->get_logger(),"%s节点已经启动",name.c_str());
add_ints_server_ =
this->create_service<example_interfaces::srv::AddTwoInts>("add_", std::bind(&ServiceServer01::handle_add_two_ints,this,std::placeholders::_1,std::placeholders::_2 ));
}
private:
rclcpp::Service<example_interfaces::srv::AddTwoInts> :: SharedPtr add_ints_server_;
void handle_add_two_ints(
const std::shared_ptr<example_interfaces::srv::AddTwoInts::Request> request,
std::shared_ptr<example_interfaces::srv::AddTwoInts::Response> response){
RCLCPP_INFO(this->get_logger(),"收到a:%ld b: %ld",request->a,request->b);
response->sum = request->a + request->b;
}
};
int main(int argc,char **argv){
rclcpp::init(argc,argv);
auto node = std::make_shared<ServiceServer01>("service_server_01");
rclcpp::spin(node);
rclcpp::shutdown();
return 0 ;
}
接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
ros2 interface package sensor_msgs #查看某一个接口包下所有的接口
msg #话题接口
srv #服务接口
action #动作接口
#接口数据类型
#基础类
bool
byte
char
float32,float64
int8,uint8
int16,uint16
int32,uint32
int64,uint64
string
#包装类
uint32 id
string image_name
sensor_msgs/Image
底层存在一个转换过程,把上面的接口文件转换为头文件,然后就可以导入了
ros2 pkg create <pkg_name> --build-type ament_cmake --dependencies rosidl_default_generators geometry_msgs
ros2 interface list
ros2 interface show std_msgs/msg/String
留个坑,FastDDS跳过了
参数控制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#开环控制 与 闭环控制
#参数
bool bool[]
int64 int64[]
float64 float64[]
string string[]
byte[]
ros2 param list
ros2 param describe <node_name> <param_name>
ros2 param get <node_name> <param_name>
ros2 param set <node_name> <param_name>
ros2 param dump <node_name>
ros2 param dump <node_name> > ./name.yaml
ros2 param load <node_name> > ./name.yaml
ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>
#日志
RCLCPP_DEBUG(this->get_logger(), "我是DEBUG级别的日志,我被打印出来了!");
RCLCPP_INFO(this->get_logger(), "我是INFO级别的日志,我被打印出来了!");
RCLCPP_WARN(this->get_logger(), "我是WARN级别的日志,我被打印出来了!");
RCLCPP_ERROR(this->get_logger(), "我是ERROR级别的日志,我被打印出来了!");
RCLCPP_FATAL(this->get_logger(), "我是FATAL级别的日志,我被打印出来了!");
this->get_logger().set_level(log_level);
Action
Action = 3 Service + 2 Topic
1
2
3
ros2 action list -t
ros2 action info <action_name>
ros2 action send_goal <action_name> <type> <data> [--feedback]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#rosbag2
ros2 run demo_nodes_cpp talker
rso2 bag record /topic_name
ros2 bag record topic-name1 topic-name2
ros2 bag record -a #记录所有话题
ros2 bag record -o file-name topic-name
ros2 bag info bag-file
ros2 bag play xxx.db3 [-r 10] [-l] #10倍速 单曲循环
ros2 topic echo /topic_name
#gazebo
gazebo /opt/ros/humble/share/gazebo_plugins/worlds/gazebo_ros_diff_drive_demo.world