-
参数服务器节点(Parameter Server Node)
负责在启动时一次性声明若干参数,并对外提供查询/修改服务。 -
客户端节点(Parameter Client Node)
演示如何在运行时通过 C++/Python API 读取/设置/列出参数。
示例参数:robot_name(string)、max_speed(double)、enable_debug(bool)。
-
目录结构(C++ 版)
复制
ws
└─src
└─param_server_demo
├─CMakeLists.txt
├─package.xml
├─src
│ ├─param_server.cpp
│ └─param_client.cpp
└─launch
└─demo.launch.py
一、创建功能包
bash
复制
ros2 pkg create --build-type ament_cmake param_server_demo \
--dependencies rclcpp rclpy
二、参数服务器节点(C++) 文件:src/param_server.cpp
cpp
复制
#include <chrono>
#include <memory>
#include "rclcpp/rclcpp.hpp"
class ParameterServer : public rclcpp::Node
{
public:
ParameterServer()
: Node("parameter_server",
rclcpp::NodeOptions()
.allow_undeclared_parameters(true) // 允许动态声明
.automatically_declare_parameters_from_overrides(true))
{
// 1) 声明并设置默认值
this->declare_parameter("robot_name", "turtlebot3");
this->declare_parameter("max_speed", 1.0);
this->declare_parameter("enable_debug", false);
RCLCPP_INFO(this->get_logger(),
"[ParameterServer] ready, parameters declared.");
}
};
int main(int argc, char ** argv)
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<ParameterServer>());
rclcpp::shutdown();
return 0;
}
三、参数客户端节点(C++) 文件:src/param_client.cpp
cpp
复制
#include <chrono>
#include <memory>
#include "rclcpp/rclcpp.hpp"
class ParameterClient : public rclcpp::Node
{
public:
ParameterClient()
: Node("parameter_client")
{
client_ = std::make_shared<rclcpp::AsyncParametersClient>(this, "parameter_server");
// 等待服务器上线
while (!client_->wait_for_service(std::chrono::seconds(1))) {
if (!rclcpp::ok()) return;
RCLCPP_INFO(this->get_logger(), "waiting for parameter server ...");
}
demo();
}
private:
void demo()
{
// 1) 读取
auto params = client_->get_parameters(
{"robot_name", "max_speed", "enable_debug"});
if (rclcpp::spin_until_future_complete(shared_from_this(), params) ==
rclcpp::FutureReturnCode::SUCCESS)
{
RCLCPP_INFO(this->get_logger(),
"robot_name = %s, max_speed = %.2f, enable_debug = %s",
params.get()[0].as_string().c_str(),
params.get()[1].as_double(),
params.get()[2].as_bool() ? "true" : "false");
}
// 2) 修改
client_->set_parameters({
rclcpp::Parameter("max_speed", 3.14),
rclcpp::Parameter("enable_debug", true)
});
// 3) 列出全部
auto list_future = client_->list_parameters({}, 10);
if (rclcpp::spin_until_future_complete(shared_from_this(), list_future) ==
rclcpp::FutureReturnCode::SUCCESS)
{
for (auto & name : list_future.get().names) {
RCLCPP_INFO(this->get_logger(), "param name: %s", name.c_str());
}
}
}
std::shared_ptr<rclcpp::AsyncParametersClient> client_;
};
int main(int argc, char ** argv)
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<ParameterClient>());
rclcpp::shutdown();
return 0;
}
四、Python 版(可选) 文件:param_server_demo/param_server_py.py
Python
复制
import rclpy
from rclpy.node import Node
class ParameterServerPy(Node):
def __init__(self):
super().__init__('parameter_server_py',
allow_undeclared_parameters=True,
automatically_declare_parameters_from_overrides=True)
self.declare_parameter('robot_name', 'turtlebot3_py')
self.declare_parameter('max_speed', 0.5)
self.declare_parameter('enable_debug', False)
self.get_logger().info('[ParameterServerPy] ready.')
def main():
rclpy.init()
rclpy.spin(ParameterServerPy())
rclpy.shutdown()
if __name__ == '__main__':
main()
文件:param_server_demo/param_client_py.py
Python
复制
import rclpy
from rclpy.node import Node
from rcl_interfaces.srv import ListParameters
class ParameterClientPy(Node):
def __init__(self):
super().__init__('parameter_client_py')
self.cli = self.create_client(ListParameters, '/parameter_server_py/list_parameters')
self.declare_parameter('dummy', 0) # 让节点提前初始化
# 用同步接口
from rclpy.parameter_client import SyncParametersClient
self.client = SyncParametersClient(self, 'parameter_server_py')
# 读取
robot_name = self.client.get_parameter('robot_name')
max_speed = self.client.get_parameter('max_speed')
debug = self.client.get_parameter('enable_debug')
self.get_logger().info(f'robot_name={robot_name}, max_speed={max_speed}, debug={debug}')
# 设置
self.client.set_parameters([
rclpy.parameter.Parameter('max_speed', rclpy.Parameter.Type.DOUBLE, 2.71),
rclpy.parameter.Parameter('enable_debug', rclpy.Parameter.Type.BOOL, True)
])
# 列出
names = self.client.list_parameters()
self.get_logger().info(f'All params: {names}')
def main():
rclpy.init()
node = ParameterClientPy()
rclpy.spin_once(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
五、统一启动 launch 文件 文件:launch/demo.launch.py
Python
复制
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
# 参数服务器(C++)
Node(
package='param_server_demo',
executable='param_server',
name='parameter_server',
parameters=[{
'robot_name': 'my_robot',
'max_speed': 2.0,
'enable_debug': False
}]
),
# 客户端(C++)
Node(
package='param_server_demo',
executable='param_client',
name='parameter_client',
output='screen'
),
# Python 版
Node(
package='param_server_demo',
executable='param_server_py.py',
name='parameter_server_py',
parameters=[{'robot_name': 'py_robot'}]
),
Node(
package='param_server_demo',
executable='param_client_py.py',
name='parameter_client_py',
output='screen'
),
])
六、编译 & 运行
bash
复制
cd ~/ws
colcon build --packages-select param_server_demo
source install/setup.bash
# 方式1:launch 一键启动
ros2 launch param_server_demo demo.launch.py
# 方式2:单独启动
# 终端1
ros2 run param_server_demo param_server
# 终端2
ros2 run param_server_demo param_client
七、命令行验证
bash
复制
# 查看参数
ros2 param list /parameter_server
# 读取
ros2 param get /parameter_server max_speed
# 设置
ros2 param set /parameter_server max_speed 9.9
384

被折叠的 条评论
为什么被折叠?



