TwistControllerNode.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2015-2018, Dataspeed Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Dataspeed Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 
00035 #include "TwistControllerNode.h"
00036 
00037 namespace dbw_mkz_twist_controller {
00038 
00039 TwistControllerNode::TwistControllerNode(ros::NodeHandle &n, ros::NodeHandle &pn) : srv_(pn)
00040 {
00041   lpf_fuel_.setParams(60.0, 0.1);
00042   accel_pid_.setRange(0.0, 1.0);
00043 
00044   // Dynamic reconfigure
00045   srv_.setCallback(boost::bind(&TwistControllerNode::reconfig, this, _1, _2));
00046 
00047   // Control rate parameter
00048   double control_rate;
00049   pn.param("control_rate", control_rate, 50.0);
00050   control_period_ = 1.0 / control_rate;
00051 
00052   // Ackermann steering parameters
00053   acker_wheelbase_ = 2.8498; // 112.2 inches
00054   acker_track_ = 1.5824; // 62.3 inches
00055   steering_ratio_ = 14.8;
00056   pn.getParam("ackermann_wheelbase", acker_wheelbase_);
00057   pn.getParam("ackermann_track", acker_track_);
00058   pn.getParam("steering_ratio", steering_ratio_);
00059   yaw_control_.setWheelBase(acker_wheelbase_);
00060   yaw_control_.setSteeringRatio(steering_ratio_);
00061 
00062   // Subscribers
00063   sub_twist_ = n.subscribe("cmd_vel", 1, &TwistControllerNode::recvTwist, this);
00064   sub_twist2_ = n.subscribe("cmd_vel_with_limits", 1, &TwistControllerNode::recvTwist2, this);
00065   sub_twist3_ = n.subscribe("cmd_vel_stamped", 1, &TwistControllerNode::recvTwist3, this);
00066   sub_steering_ = n.subscribe("steering_report", 1, &TwistControllerNode::recvSteeringReport, this);
00067   sub_imu_ = n.subscribe("imu/data_raw", 1, &TwistControllerNode::recvImu, this);
00068   sub_enable_ = n.subscribe("dbw_enabled", 1, &TwistControllerNode::recvEnable, this);
00069   sub_fuel_level_ = n.subscribe("fuel_level_report", 1, &TwistControllerNode::recvFuel, this);
00070 
00071   // Publishers
00072   pub_throttle_ = n.advertise<dbw_mkz_msgs::ThrottleCmd>("throttle_cmd", 1);
00073   pub_brake_ = n.advertise<dbw_mkz_msgs::BrakeCmd>("brake_cmd", 1);
00074   pub_steering_ = n.advertise<dbw_mkz_msgs::SteeringCmd>("steering_cmd", 1);
00075 
00076   // Debug
00077   pub_accel_ = n.advertise<std_msgs::Float64>("filtered_accel", 1);
00078   pub_req_accel_ = n.advertise<std_msgs::Float64>("req_accel", 1);
00079 
00080   // Timers
00081   control_timer_ = n.createTimer(ros::Duration(control_period_), &TwistControllerNode::controlCallback, this);
00082 }
00083 
00084 void TwistControllerNode::controlCallback(const ros::TimerEvent& event)
00085 {
00086   if ((event.current_real - cmd_stamp_).toSec() > (10.0 * control_period_)) {
00087     speed_pid_.resetIntegrator();
00088     accel_pid_.resetIntegrator();
00089     return;
00090   }
00091 
00092   double vehicle_mass = cfg_.vehicle_mass + lpf_fuel_.get() / 100.0 * cfg_.fuel_capacity * GAS_DENSITY;
00093   double vel_error = cmd_vel_.twist.linear.x - actual_.linear.x;
00094   if ((fabs(cmd_vel_.twist.linear.x) < mphToMps(1.0)) || !cfg_.pub_pedals) {
00095     speed_pid_.resetIntegrator();
00096   }
00097 
00098   speed_pid_.setRange(
00099       -std::min(fabs(cmd_vel_.decel_limit) > 0.0 ? fabs(cmd_vel_.decel_limit) : 9.8,
00100                 cfg_.decel_max > 0.0 ? cfg_.decel_max : 9.8),
00101        std::min(fabs(cmd_vel_.accel_limit) > 0.0 ? fabs(cmd_vel_.accel_limit) : 9.8,
00102                 cfg_.accel_max > 0.0 ? cfg_.accel_max : 9.8)
00103   );
00104   double accel_cmd = speed_pid_.step(vel_error, control_period_);
00105 
00106   if (cmd_vel_.twist.linear.x <= (double)1e-2) {
00107     accel_cmd = std::min(accel_cmd, -530 / vehicle_mass / cfg_.wheel_radius);
00108   } 
00109 
00110   std_msgs::Float64 accel_cmd_msg;
00111   accel_cmd_msg.data = accel_cmd;
00112   pub_req_accel_.publish(accel_cmd_msg);
00113 
00114   if (sys_enable_) {
00115     dbw_mkz_msgs::ThrottleCmd throttle_cmd;
00116     dbw_mkz_msgs::BrakeCmd brake_cmd;
00117     dbw_mkz_msgs::SteeringCmd steering_cmd;
00118 
00119     throttle_cmd.enable = true;
00120     throttle_cmd.pedal_cmd_type = dbw_mkz_msgs::ThrottleCmd::CMD_PERCENT;
00121     if (accel_cmd >= 0) {
00122       throttle_cmd.pedal_cmd = accel_pid_.step(accel_cmd - lpf_accel_.get(), control_period_);
00123     } else {
00124       accel_pid_.resetIntegrator();
00125       throttle_cmd.pedal_cmd = 0;
00126     }
00127 
00128     brake_cmd.enable = true;
00129     brake_cmd.pedal_cmd_type = dbw_mkz_msgs::BrakeCmd::CMD_TORQUE;
00130     if (accel_cmd < -cfg_.brake_deadband) {
00131       brake_cmd.pedal_cmd = -accel_cmd * vehicle_mass * cfg_.wheel_radius;
00132     } else {
00133       brake_cmd.pedal_cmd = 0;
00134     }
00135 
00136     steering_cmd.enable = true;
00137     steering_cmd.steering_wheel_angle_cmd = yaw_control_.getSteeringWheelAngle(cmd_vel_.twist.linear.x, cmd_vel_.twist.angular.z, actual_.linear.x)
00138         + cfg_.steer_kp * (cmd_vel_.twist.angular.z - actual_.angular.z);
00139 
00140     if (cfg_.pub_pedals) {
00141       pub_throttle_.publish(throttle_cmd);
00142       pub_brake_.publish(brake_cmd);
00143     }
00144 
00145     if (cfg_.pub_steering) {
00146       pub_steering_.publish(steering_cmd);
00147     }
00148   } else {
00149     speed_pid_.resetIntegrator();
00150     accel_pid_.resetIntegrator();
00151   }
00152 }
00153 
00154 void TwistControllerNode::reconfig(ControllerConfig& config, uint32_t level)
00155 {
00156   cfg_ = config;
00157   cfg_.vehicle_mass -= cfg_.fuel_capacity * GAS_DENSITY; // Subtract weight of full gas tank
00158   cfg_.vehicle_mass += 150.0; // Account for some passengers
00159 
00160   speed_pid_.setGains(cfg_.speed_kp, 0.0, 0.0);
00161   accel_pid_.setGains(cfg_.accel_kp, cfg_.accel_ki, 0.0);
00162   yaw_control_.setLateralAccelMax(cfg_.max_lat_accel);
00163   lpf_accel_.setParams(cfg_.accel_tau, 0.02);
00164 }
00165 
00166 void TwistControllerNode::recvTwist(const geometry_msgs::Twist::ConstPtr& msg)
00167 {
00168   cmd_vel_.twist = *msg;
00169   cmd_vel_.accel_limit = 0;
00170   cmd_vel_.decel_limit = 0;
00171   cmd_stamp_ = ros::Time::now();
00172 }
00173 
00174 void TwistControllerNode::recvTwist2(const dbw_mkz_msgs::TwistCmd::ConstPtr& msg)
00175 {
00176   cmd_vel_ = *msg;
00177   cmd_stamp_ = ros::Time::now();
00178 }
00179 
00180 void TwistControllerNode::recvTwist3(const geometry_msgs::TwistStamped::ConstPtr& msg)
00181 {
00182   cmd_vel_.twist = msg->twist;
00183   cmd_vel_.accel_limit = 0;
00184   cmd_vel_.decel_limit = 0;
00185   cmd_stamp_ = ros::Time::now();
00186 }
00187 
00188 void TwistControllerNode::recvFuel(const dbw_mkz_msgs::FuelLevelReport::ConstPtr& msg)
00189 {
00190   lpf_fuel_.filt(msg->fuel_level);
00191 }
00192 
00193 void TwistControllerNode::recvSteeringReport(const dbw_mkz_msgs::SteeringReport::ConstPtr& msg)
00194 {
00195   double raw_accel = 50.0 * (msg->speed - actual_.linear.x);
00196   lpf_accel_.filt(raw_accel);
00197 
00198   std_msgs::Float64 accel_msg;
00199   accel_msg.data = lpf_accel_.get();
00200   pub_accel_.publish(accel_msg);
00201 
00202   actual_.linear.x = msg->speed;
00203 }
00204 
00205 void TwistControllerNode::recvImu(const sensor_msgs::Imu::ConstPtr& msg)
00206 {
00207   actual_.angular.z = msg->angular_velocity.z;
00208 }
00209 
00210 void TwistControllerNode::recvEnable(const std_msgs::Bool::ConstPtr& msg)
00211 {
00212   sys_enable_ = msg->data;
00213 }
00214 
00215 }
00216 


dbw_mkz_twist_controller
Author(s): Micho Radovnikovich , Kevin Hallenbeck
autogenerated on Thu Jul 4 2019 20:08:22