鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    4.5.3修改其他节点参数,[INFO] [1763206927.409951296] [turtle_controller]: 参数更新失败,原因:parameter 'k' cannot be set because it was not declared

    已定时 已固定 已锁定 已移动
    动手学ROS2
    ros2 修改其他节点参数
    3
    4
    2.5k
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • D
      ddl
      最后由 编辑

      //patrol_client.cpp
      #include "rclcpp/rclcpp.hpp"
      #include "chapt4_interfaces/srv/patrol.hpp"
      #include <chrono>
      #include <ctime>
      #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;//可以使用10s,100ms表示时间
      using Patrol = chapt4_interfaces::srv::Patrol;

      class PatrolClientNode: public rclcpp::Node //定义类,继承自rclcpp::Node
      {
      public:
      PatrolClientNode():Node("turtle_controller")
      {
      srand(time(NULL));//初始化随机数种子

          patrol_client_ = this->create_client<Patrol>("patrol");
          //创建客户端
          timer_ = this->create_wall_timer(10s,[&]()->void{
          //1检测服务端是否上线
          while (!this->patrol_client_->wait_for_service(1s))
          {
              if(!rclcpp::ok()){
                  RCLCPP_ERROR(this->get_logger(),"等待服务上线过程中,rclcpp挂了,我退下了");
                  return;
              }
              RCLCPP_ERROR(this->get_logger(),"等待服务上线中");
          }
          //2构造请求的对象
          auto request = std::make_shared<Patrol::Request>();
          request->target_x = rand() % 12;
          request->target_y = rand() % 12;//取余防止超过12
          RCLCPP_INFO(this->get_logger(),"准备好目标点%f,%f",
          request->target_x,request->target_y);
          //3发送请求,调动函数,异步发送请求
          this->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(),"请求巡逻目标点成功");
              }
              if(response->result==Patrol::Response::FAIL){
                  RCLCPP_INFO(this->get_logger(),"请求巡逻目标点失败"); 
              }
              });    
          });
          
      }
      
      //创建客户端发送请求,返回结果
      SetP::Response::SharedPtr call_set_parameter(const rcl_interfaces::msg::Parameter &param)
      {
          auto param_client_ = this->create_client<SetP>("/turtle_controller/set_parameters");
          //更改客户端名(智能指针),服务类型名,服务名称
          //创建客户端
          //1检测服务端是否上线
          while (!this->patrol_client_->wait_for_service(1s))
          {
              if(!rclcpp::ok()){
                  RCLCPP_ERROR(this->get_logger(),"等待服务上线过程中,rclcpp挂了,我退下了");
                  return nullptr;
              }
              RCLCPP_ERROR(this->get_logger(),"等待服务上线中");
          }
          //2构造请求的对象
          auto request = std::make_shared<SetP::Request>();
          request->parameters.push_back(param);
          //3发送请求,调动函数,异步发送请求
          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)
      {
          //1创建参数对象
          auto param = rcl_interfaces::msg::Parameter();
          param.name = "k";
          //2创建参数值
          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 = this->call_set_parameter(param);
          if(response==NULL){
              RCLCPP_INFO(this->get_logger(),"参数更新失败");
              return;
              
          }
          for (auto result:response->results)
          //返回值是result[]数组,遍历数组
          {
              if (result.successful==false)
              {
                  RCLCPP_INFO(this->get_logger(),"参数更新失败,原因:%s",result.reason.c_str());
              }else{
                  RCLCPP_INFO(this->get_logger(),"参数更新成功");
              }
              
          }
          
      }
      

      private://私有成员变量 声明定时器和客户端
      rclcpp::TimerBase::SharedPtr timer_;
      rclcpp::Client<Patrol>::SharedPtr patrol_client_;
      };

      int main(int argc,char* argv[])//俩命令行参数
      {
      rclcpp::init(argc,argv);
      auto node = std::make_shared<PatrolClientNode>();//创建节点turtle-circle,创建TCN类的共享指针
      node->update_server_param_k(4.0);
      rclcpp::spin(node);//启动节点循环
      rclcpp::shutdown();//关闭环境
      return 0;
      }
      //turtle_control.cpp
      #include "rclcpp/rclcpp.hpp"
      #include "geometry_msgs/msg/twist.hpp"
      #include "turtlesim/msg/pose.hpp"
      #include "chapt4_interfaces/srv/patrol.hpp"
      #include "rcl_interfaces/msg/set_parameters_result.hpp"
      #include "rclcpp/parameter_client.hpp"
      #include "rclcpp/parameter.hpp"

      using Patrol = chapt4_interfaces::srv::Patrol;
      using SetParametersResult = rcl_interfaces::msg::SetParametersResult;

      class TurtleController: public rclcpp::Node //定义类,继承自rclcpp::Node
      {
      private:
      OnSetParametersCallbackHandle::SharedPtr parameter_callback_handle_;
      rclcpp::Service<Patrol>::SharedPtr patrol_server_;
      rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr publisher_; //发布者的智能指针
      rclcpp::Subscriptionturtlesim::msg::Pose::SharedPtr subscriber_; //订阅者的智能共享指针
      double target_x_{1.0};
      double target_y_{1.0};
      double k_{1.0};//比例系数
      double max_speed_{3.0};

      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_);
      this->set_parameter(rclcpp::Parameter("k",2.0));

          parameter_callback_handle_ = this->add_on_set_parameters_callback([&](const 
          std::vector<rclcpp::Parameter> & parameters)->
              rcl_interfaces::msg::SetParametersResult{
              rcl_interfaces::msg::SetParametersResult result;
              result.successful = true;
              for (const auto & parameter : parameters) {
                  RCLCPP_INFO(this->get_logger(),"更新参数的值%s=%f",parameter.get_name().
                  c_str(),parameter.as_double());
                  if(parameter.get_name()=="k")
                  {
                      k_ = parameter.as_double();
                  }
                  if(parameter.get_name()=="max_speed")
                  {
                      max_speed_ = parameter.as_double();
                  }
              }
              return result;
              });
          patrol_server_ = this->create_service<Patrol>("patrol",[&](const 
          Patrol::Request::SharedPtr request,Patrol::Response::SharedPtr response) -> void{
              if(
                  (0 < request->target_x && request->target_x < 12.0f)&&
                  (0 < request->target_y && request->target_y < 12.0f)
              ){
                  this->target_x_ = request->target_x;
                  this->target_y_ = request->target_y;
                  response->result = Patrol::Response::SUCCESS;
              }else{
                  response->result = Patrol::Response::FAIL;
              }
              //额外调用添加的回调函数,做到第一时间更新参数
          });
          publisher_ = this->create_publisher<geometry_msgs::msg::Twist>(
              "/turtle1/cmd_vel", 10);
          subscriber_ = this->create_subscription<turtlesim::msg::Pose>(
              "/turtle1/pose", 10,
              std::bind(&TurtleController::on_pose_received_, this, std::placeholders::_1)); 
          
      }
      

      private:
      void on_pose_received_(const turtlesim::msg::Pose::SharedPtr pose){
      //1.获取当前位置
      auto current_x = pose->x;
      auto current_y = pose->y;
      RCLCPP_INFO(get_logger(),"当前:x=%f,y=%f",current_x,current_y);

          //2.计算当前海龟位置跟目标位置之间的距离差和角度差
          auto distance = std::sqrt(
              (target_x_-current_x)*(target_x_-current_x)+
              (target_y_-current_y)*(target_y_-current_y)      
          );
          auto angle = std::atan2( (target_y_-current_y), (target_x_-current_x)) - pose->theta;
      
          //3.控制策略
          auto msg = geometry_msgs::msg::Twist();
          if(distance>0.1){
              if(fabs(angle)>0.2){
                  msg.angular.z = fabs(angle);
              }else{
                  msg.linear.x = k_*distance;
              }
          }
      
          //4.限制线速度最大值
          if(msg.linear.x > max_speed_){
              msg.linear.x = max_speed_;
          }
          publisher_->publish(msg);
      }
      

      };

      int main(int argc,char* argv[])//俩命令行参数
      {
      rclcpp::init(argc,argv);
      auto node = std::make_shared<TurtleController>();//创建节点turtle-circle,创建TCN类的共享指针
      rclcpp::spin(node);//启动节点循环
      rclcpp::shutdown();//关闭环境
      return 0;
      }

      星 1 条回复 最后回复 回复 引用 0
      • 4
        49736207
        最后由 编辑

        请问这个问题解决了吗?

        D 1 条回复 最后回复 回复 引用 0
        • D
          ddl @49736207
          最后由 编辑

          @49736207 没有解决

          1 条回复 最后回复 回复 引用 0
          • 星
            星心 @ddl
            最后由 编辑

            @ddl 在 4.5.3修改其他节点参数,[INFO] [1763206927.409951296] [turtle_controller]: 参数更新失败,原因:parameter 'k' cannot be set because it was not declared 中说:

            PatrolClientNode():Node("turtle_controller")

            客户端节点命名重复,导致的参数未声明

            1 条回复 最后回复 回复 引用 0
            • 第一个帖子
              最后一个帖子
            皖ICP备16016415号-7
            Powered by NodeBB | 鱼香ROS