前言
ros2参数通信测试节点案例。
param_server_node节点
python
import rclpy
from rclpy.node import Node
from rclpy.parameter import Parameter
class ParamServerNode(Node):
def __init__(self):
super().__init__("param_server_node")
# 初始化参数(支持不同类型)
self.declare_parameters(
namespace="",
parameters=[
("int_param", 10), # 整型参数
("float_param", 3.14), # 浮点型参数
("bool_param", True), # 布尔型参数
("string_param", "hello"), # 字符串参数
("list_param", [1, 2, 3]) # 列表参数
]
)
# 创建定时器,1Hz打印参数
self.print_timer = self.create_timer(0.1, self.print_parameters_callback)
self.get_logger().info("参数服务器节点已启动,开始实时打印参数...")
def print_parameters_callback(self):
"""定时器回调函数:获取并打印所有参数"""
# 获取所有参数值
int_param = self.get_parameter("int_param").value
float_param = self.get_parameter("float_param").value
bool_param = self.get_parameter("bool_param").value
string_param = self.get_parameter("string_param").value
list_param = self.get_parameter("list_param").value
# 打印参数(带颜色区分)
self.get_logger().info("\n=== 当前参数值 ===")
self.get_logger().info(f"整型参数: {int_param}")
self.get_logger().info(f"浮点参数: {float_param}")
self.get_logger().info(f"布尔参数: {bool_param}")
self.get_logger().info(f"字符串参数: {string_param}")
self.get_logger().info(f"列表参数: {list_param}\n")
def main(args=None):
rclpy.init(args=args)
node = ParamServerNode()
try:
rclpy.spin(node)
except KeyboardInterrupt:
node.get_logger().info("节点被手动终止")
finally:
node.destroy_node()
rclpy.shutdown()
if __name__ == "__main__":
main()
param_client_node节点
python
import rclpy
from rclpy.node import Node
from rclpy.parameter import Parameter
import random
class ParamClientNode(Node):
def __init__(self):
super().__init__("param_client_node")
# 声明定时器间隔参数(默认5秒)
self.declare_parameter("update_interval", 0.1)
update_interval = self.get_parameter("update_interval").value
# 获取参数服务器节点的名称(固定为param_server_node)
self.target_node_name = "param_server_node"
# 创建参数修改定时器
self.update_timer = self.create_timer(update_interval, self.update_parameters_callback)
# 获取参数客户端(用于修改其他节点参数)
self.param_client = self.create_client(
rclpy.parameter_service.SetParameters,
f"/{self.target_node_name}/set_parameters"
)
self.get_logger().info(f"参数修改节点已启动,修改间隔: {update_interval}秒")
self.get_logger().info(f"目标节点: {self.target_node_name}")
def update_parameters_callback(self):
"""定时器回调:随机修改目标节点的参数"""
# 生成随机参数值
new_int = random.randint(0, 100)
new_float = round(random.uniform(0.0, 10.0), 2)
new_bool = random.choice([True, False])
new_string = f"msg_{random.randint(0, 100)}"
new_list = [random.randint(0, 10) for _ in range(3)]
# 构建参数更新请求
parameters = [
Parameter("int_param", Parameter.Type.INTEGER, new_int),
Parameter("float_param", Parameter.Type.DOUBLE, new_float),
Parameter("bool_param", Parameter.Type.BOOL, new_bool),
Parameter("string_param", Parameter.Type.STRING, new_string),
Parameter("list_param", Parameter.Type.INTEGER_ARRAY, new_list)
]
# 发送参数更新请求
request = rclpy.parameter_service.SetParameters.Request()
request.parameters = [p.to_parameter_msg() for p in parameters]
# 异步调用参数服务
future = self.param_client.call_async(request)
future.add_done_callback(self._on_set_parameters_done)
# 打印修改日志
self.get_logger().info("\n=== 修改参数 ===")
self.get_logger().info(f"整型参数: {new_int}")
self.get_logger().info(f"浮点参数: {new_float}")
self.get_logger().info(f"布尔参数: {new_bool}")
self.get_logger().info(f"字符串参数: {new_string}")
self.get_logger().info(f"列表参数: {new_list}\n")
def _on_set_parameters_done(self, future):
"""参数修改请求回调"""
try:
response = future.result()
if all([resp.successful for resp in response.results]):
self.get_logger().info("参数修改成功!")
else:
self.get_logger().error(f"参数修改失败: {response.results}")
except Exception as e:
self.get_logger().error(f"参数修改异常: {str(e)}")
def main(args=None):
rclpy.init(args=args)
node = ParamClientNode()
try:
rclpy.spin(node)
except KeyboardInterrupt:
node.get_logger().info("节点被手动终止")
finally:
node.destroy_node()
rclpy.shutdown()
if __name__ == "__main__":
main()
效果
运行param_server_node节点
bash
source install/setup.bash
ros2 run data_monitor param_server_node
运行param_client_node节点
bash
source install/setup.bash
ros2 run data_monitor param_client_node
