Newer
Older
waypoint_navigation / waypoint_nav / src / velocity_controller.cpp
@koki koki on 29 Aug 2022 2 KB update
#include <ros/ros.h>
#include <std_msgs/Float32.h>
#include <geometry_msgs/Twist.h>
#include <move_base_msgs/MoveBaseAction.h>
#include <actionlib/client/simple_action_client.h>

#include <string>


class VelocityController {
public:
    VelocityController() :
        move_base_action_("move_base", true),
        standard_vel_(1.0),
        current_max_vel_(1.0),
        min_vel_(0.0)
    {
        while((move_base_action_.waitForServer(ros::Duration(1.0)) == false) && (ros::ok() == true)) {
            ROS_INFO("Waiting...");
        }

        ros::NodeHandle nh;
        max_vel_sub_ = nh.subscribe("/max_vel", 1, &VelocityController::maxVelCallback, this);
        cmd_vel_sub_ = nh.subscribe("/cmd_vel_in", 10, &VelocityController::cmdVelCallback, this);
        cmd_vel_pub_ = nh.advertise<geometry_msgs::Twist>("/cmd_vel_out", 10);

        std::string planner = "base_local_planner/TrajectoryPlannerROS";
        std::string param_max = "/move_base/TrajectoryPlannerROS/max_vel_x";
        std::string param_min = "/move_base/TrajectoryPlannerROS/min_vel_x";
        nh.param("/move_base/base_local_planner", planner, planner);
        if (planner == "dwa_local_planner/DWAPlannerROS") {
            param_max = "/move_base/DWAPlannerROS/max_vel_trans";
            param_min = "/move_base/DWAPlannerROS/min_vel_trans";
        }
        nh.param(param_max, standard_vel_, standard_vel_);
        nh.param(param_min, min_vel_, min_vel_);
        ROS_INFO_STREAM("Standard max vel: " << standard_vel_);
    }



    void maxVelCallback(const std_msgs::Float32 &msg)
    {
        current_max_vel_ = standard_vel_ * msg.data;
        current_max_vel_ = std::max(current_max_vel_, min_vel_);
        ROS_INFO_STREAM("Set max vel: " << current_max_vel_);
    }



    void cmdVelCallback(const geometry_msgs::Twist &msg)
    {
        pub_msg_.linear.x = std::min(float(msg.linear.x), current_max_vel_);
        pub_msg_.angular = msg.angular;
        cmd_vel_pub_.publish(pub_msg_);
    }



private:
    actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> move_base_action_;
    ros::Subscriber max_vel_sub_;
    ros::Subscriber cmd_vel_sub_;
    ros::Publisher cmd_vel_pub_;
    float standard_vel_, current_max_vel_, min_vel_;
    geometry_msgs::Twist pub_msg_;
};







int main(int argc, char *argv[]) {
    ros::init(argc, argv, "velocity_controller");
    VelocityController vc;

    ros::spin();
    return 0;
}