ROS2 节点中使用参数

修改service_practice_ws/src/demo_cpp_service/src/patrol_client.cpp

cpp 复制代码
#include <cstdlib>
#include <ctime>
#include <chrono>
#include "rclcpp/rclcpp.hpp"
#include "service_interface/srv/patrol.hpp"
#include "rcl_interfaces/msg/parameter.hpp"
#include "rcl_interfaces/msg/parameter_value.hpp"
#include "rcl_interfaces/msg/parameter_type.hpp"
#include "rcl_interfaces/srv/set_parameters.hpp"

using SetP = rcl_interfaces::srv::SetParameters;
using namespace std::chrono_literals;
using Patrol = service_interface::srv::Patrol;

class PatrolClient : public rclcpp::Node
{
private:
    rclcpp::TimerBase::SharedPtr timer_;
    rclcpp::Client<Patrol>::SharedPtr patrol_client_;

public:
    PatrolClient() : Node("patrol_client")
    {
        patrol_client_ = this->create_client<Patrol>("patrol");
        timer_ = this->create_wall_timer(6s, std::bind(&PatrolClient::timer_callback, this));
    }

    void timer_callback()
    {
        while(!patrol_client_->wait_for_service(std::chrono::seconds(1)))
        {
            if (!rclcpp::ok())
            {
                RCLCPP_ERROR(this->get_logger(), "interrupted when wait for service");
                return;
            }
            RCLCPP_INFO(this->get_logger(), "wait for server..");
        }
        auto request = std::make_shared<Patrol::Request>();
        request->target_x = rand() % 15;
        request->target_y = rand() % 15;
        RCLCPP_INFO(this->get_logger(), "request for patrol (%f, %f)", request->target_x, request->target_y);
        patrol_client_->async_send_request(
            request,
            [&](rclcpp::Client<Patrol>::SharedFuture result_future) -> void
            {
                auto response = result_future.get();
                if(response->result == Patrol::Response::SUCCESS)
                {
                    RCLCPP_INFO(this->get_logger(), "process success");
                }
                else if(response->result == Patrol::Response::FAIL)
                {
                    RCLCPP_INFO(this->get_logger(), "process failed");
                }
            }
        );
    }

    std::shared_ptr<SetP::Response> call_set_parameters(rcl_interfaces::msg::Parameter& parameter)
    {
        auto param_client = this->create_client<SetP>("/turtle_controller/set_parameters");
        while(!param_client->wait_for_service(std::chrono::seconds(1)))
        {
            if(!rclcpp::ok())
            {
                RCLCPP_ERROR(this->get_logger(), "interrupted when wait service");
                return nullptr;
            }
            RCLCPP_INFO(this->get_logger(), "wait service");
        }
        auto request = std::make_shared<SetP::Request>();
        request->parameters.push_back(parameter);

        auto future = param_client->async_send_request(request);
        rclcpp::spin_until_future_complete(this->get_node_base_interface(), future);
        auto response = future.get();
        return response;
    }

    void update_server_param_k(double k)
    {
        auto param = rcl_interfaces::msg::Parameter();
        param.name = "k";
        auto param_value = rcl_interfaces::msg::ParameterValue();
        param_value.type = rcl_interfaces::msg::ParameterType::PARAMETER_DOUBLE;
        param_value.double_value = k;
        param.value = param_value;
        auto response = call_set_parameters(param);
        if(response == nullptr)
        {
            RCLCPP_WARN(this->get_logger(), "update parameter failed");
            return;
        }
        else
        {
            for(auto result : response->results)
            {
                if (result.successful)
                {
                    RCLCPP_INFO(this->get_logger(), "parameter k is updated: %f", k);
                }
                else
                {
                    RCLCPP_WARN(this->get_logger(), "parameter k update failed for : %s", result.reason.c_str());
                }
            }
        }
    }
};

int main(int argc, char *argv[])
{
    rclcpp::init(argc, argv);
    auto node = std::make_shared<PatrolClient>();
    node->update_server_param_k(1.5);
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

修改service_practice_ws/src/demo_cpp_service/src/turtle_control.cpp

cpp 复制代码
#include "rclcpp/rclcpp.hpp"
#include "service_interface/srv/patrol.hpp"
#include "turtlesim/msg/pose.hpp"
#include "geometry_msgs/msg/twist.hpp"
#include "rcl_interfaces/msg/set_parameters_result.hpp"
using service_interface::srv::Patrol;
using SetParametersResult = rcl_interfaces::msg::SetParametersResult;

class TurtleController : public rclcpp::Node
{
public:
    TurtleController() : Node("turtle_controller")
    {
        this->declare_parameter("k", 1.0);
        this->declare_parameter("max_speed", 1.0);
        this->get_parameter("k", k_);
        this->get_parameter("max_speed", max_speed_);
        velocity_publisher_ = this->create_publisher<geometry_msgs::msg::Twist>("/turtle1/cmd_vel", 10);
        pose_subscription_ = this->create_subscription<turtlesim::msg::Pose>("/turtle1/pose", 10,
            std::bind(&TurtleController::on_pose_received_, this, std::placeholders::_1));
        //添加服务
        patrol_server_ = this->create_service<Patrol>(
            "patrol",
        [&](const std::shared_ptr<Patrol::Request> request,
        std::shared_ptr<Patrol::Response> response) -> void{
            if((0 < request->target_y && request->target_x < 12.0f)
            && (0 < request->target_y && request->target_y < 12.0f)){
                target_x_ = request->target_x;
                target_y_ = request->target_y;
                response->result = Patrol::Response::SUCCESS;
            }
            else
            {
                response->result = Patrol::Response::FAIL;
            }
        }
        );
        //添加参数设置回调
        parameters_callback_handle_ = this->add_on_set_parameters_callback(
            [&](const std::vector<rclcpp::Parameter>& parameters)->SetParametersResult
            {
                for(auto parameter : parameters)
                {
                    RCLCPP_INFO(this->get_logger(), "set parameter %s to %f", parameter.get_name().c_str(), parameter.as_double());
                    if (parameter.get_name() == "k")
                    {
                        k_ = parameter.as_double();
                    }
                    else if(parameter.get_name() == "max_speed")
                    {
                        max_speed_ = parameter.as_double();
                    }
                }
                auto result = SetParametersResult();
                result.successful = true;
                return result;
            }
        );
        velocity_publisher_ = this->create_publisher<geometry_msgs::msg::Twist>("/turtle1/cmd_vel", 10);
    }

    void on_pose_received_(const turtlesim::msg::Pose::SharedPtr pose)
    {
        auto message = geometry_msgs::msg::Twist();
        double current_x = pose->x;
        double current_y = pose->y;
        // RCLCPP_INFO(this->get_logger(), "current location: (x=%f, y=%f)", current_x, current_y);

        double distance = std::sqrt((target_x_ - current_x)*(target_x_-current_x)+(target_y_-current_y)*(target_y_-current_y));
        double angle = std::atan2(target_y_-current_y, target_x_-current_x)-pose->theta;

        if(distance>0.1)
        {
            if (fabs(angle)>0.2)    
            {
                message.angular.z = fabs(angle);
            }
            else
            {
                message.linear.x = k_*distance;
            }
            
        }


        if (message.linear.x > max_speed_)
        {
            message.linear.x = max_speed_;
        }
        velocity_publisher_->publish(message);
        
    }

private:
    rclcpp::Service<Patrol>::SharedPtr patrol_server_;
    rclcpp::Subscription<turtlesim::msg::Pose>::SharedPtr pose_subscription_;
    rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr velocity_publisher_;
    OnSetParametersCallbackHandle::SharedPtr parameters_callback_handle_;
    double target_x_{0.0};
    double target_y_{0.0};
    double k_{1.0};
    double max_speed_{7.0};
    
};

int main(int argc, char *argv[])
{
    rclcpp::init(argc, argv);
    auto node = std::make_shared<TurtleController>();
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

构建运行查看结果,可以发现在/turtle_controller下面有kmax_speed服务

bash 复制代码
colcon build
ros2 run turtlesim turtlesim_node
ros2 run demo_cpp_service patrol_client
ros2 run demo_cpp_service turtle_control

ros2 param list
----------------------------输出-----------------------------
/patrol_client:
  qos_overrides./parameter_events.publisher.depth
  qos_overrides./parameter_events.publisher.durability
  qos_overrides./parameter_events.publisher.history
  qos_overrides./parameter_events.publisher.reliability
  use_sim_time
/rqt_gui_py_node_1968386:
  use_sim_time
/turtle_controller:
  k
  max_speed
  qos_overrides./parameter_events.publisher.depth
  qos_overrides./parameter_events.publisher.durability
  qos_overrides./parameter_events.publisher.history
  qos_overrides./parameter_events.publisher.reliability
  use_sim_time
/turtlesim:
  background_b
  background_g
  background_r
  qos_overrides./parameter_events.publisher.depth
  qos_overrides./parameter_events.publisher.durability
  qos_overrides./parameter_events.publisher.history
  qos_overrides./parameter_events.publisher.reliability
  use_sim_time
相关推荐
草莓熊Lotso2 小时前
Qt 显示与输入类控件进阶:数字、进度、输入框实战攻略
java·大数据·开发语言·c++·人工智能·qt
山峰哥2 小时前
SQL调优实战:从索引到执行计划的深度优化指南
大数据·开发语言·数据库·sql·编辑器·深度优先
HellowAmy2 小时前
我的C++规范 - 指针指向
开发语言·c++·代码规范
渡我白衣2 小时前
从线性到非线性——神经网络的原理、训练与可解释性探索
开发语言·javascript·人工智能·深度学习·神经网络·机器学习·数字电路
蒸蒸yyyyzwd2 小时前
go语言学习
开发语言·学习·golang
froginwe112 小时前
R 数据框
开发语言
CSDN_RTKLIB2 小时前
多线程锁基础
c++
坐怀不乱杯魂2 小时前
Linux网络 - Socket编程(IPv4&IPv6)
linux·服务器·网络·c++·udp·tcp
Yupureki2 小时前
《算法竞赛从入门到国奖》算法基础:搜索-BFS初识
c语言·数据结构·c++·算法·visual studio·宽度优先