TwistControllerNode.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2015-2018, Dataspeed Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Dataspeed Inc. nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 #include "TwistControllerNode.h"
36 
37 namespace dbw_mkz_twist_controller {
38 
40 {
41  lpf_fuel_.setParams(60.0, 0.1);
42  accel_pid_.setRange(0.0, 1.0);
43 
44  // Dynamic reconfigure
45  srv_.setCallback(boost::bind(&TwistControllerNode::reconfig, this, _1, _2));
46 
47  // Control rate parameter
48  double control_rate;
49  pn.param("control_rate", control_rate, 50.0);
50  control_period_ = 1.0 / control_rate;
51 
52  // Ackermann steering parameters
53  acker_wheelbase_ = 2.8498; // 112.2 inches
54  acker_track_ = 1.5824; // 62.3 inches
55  steering_ratio_ = 14.8;
56  pn.getParam("ackermann_wheelbase", acker_wheelbase_);
57  pn.getParam("ackermann_track", acker_track_);
58  pn.getParam("steering_ratio", steering_ratio_);
61 
62  // Subscribers
63  sub_twist_ = n.subscribe("cmd_vel", 1, &TwistControllerNode::recvTwist, this);
64  sub_twist2_ = n.subscribe("cmd_vel_with_limits", 1, &TwistControllerNode::recvTwist2, this);
65  sub_twist3_ = n.subscribe("cmd_vel_stamped", 1, &TwistControllerNode::recvTwist3, this);
66  sub_steering_ = n.subscribe("steering_report", 1, &TwistControllerNode::recvSteeringReport, this);
67  sub_imu_ = n.subscribe("imu/data_raw", 1, &TwistControllerNode::recvImu, this);
68  sub_enable_ = n.subscribe("dbw_enabled", 1, &TwistControllerNode::recvEnable, this);
69  sub_fuel_level_ = n.subscribe("fuel_level_report", 1, &TwistControllerNode::recvFuel, this);
70 
71  // Publishers
72  pub_throttle_ = n.advertise<dbw_mkz_msgs::ThrottleCmd>("throttle_cmd", 1);
73  pub_brake_ = n.advertise<dbw_mkz_msgs::BrakeCmd>("brake_cmd", 1);
74  pub_steering_ = n.advertise<dbw_mkz_msgs::SteeringCmd>("steering_cmd", 1);
75 
76  // Debug
77  pub_accel_ = n.advertise<std_msgs::Float64>("filtered_accel", 1);
78  pub_req_accel_ = n.advertise<std_msgs::Float64>("req_accel", 1);
79 
80  // Timers
82 }
83 
85 {
86  if ((event.current_real - cmd_stamp_).toSec() > (10.0 * control_period_)) {
89  return;
90  }
91 
92  double vehicle_mass = cfg_.vehicle_mass + lpf_fuel_.get() / 100.0 * cfg_.fuel_capacity * GAS_DENSITY;
93  double vel_error = cmd_vel_.twist.linear.x - actual_.linear.x;
94  if ((fabs(cmd_vel_.twist.linear.x) < mphToMps(1.0)) || !cfg_.pub_pedals) {
96  }
97 
99  -std::min(fabs(cmd_vel_.decel_limit) > 0.0 ? fabs(cmd_vel_.decel_limit) : 9.8,
100  cfg_.decel_max > 0.0 ? cfg_.decel_max : 9.8),
101  std::min(fabs(cmd_vel_.accel_limit) > 0.0 ? fabs(cmd_vel_.accel_limit) : 9.8,
102  cfg_.accel_max > 0.0 ? cfg_.accel_max : 9.8)
103  );
104  double accel_cmd = speed_pid_.step(vel_error, control_period_);
105 
106  if (cmd_vel_.twist.linear.x <= (double)1e-2) {
107  accel_cmd = std::min(accel_cmd, -530 / vehicle_mass / cfg_.wheel_radius);
108  }
109 
110  std_msgs::Float64 accel_cmd_msg;
111  accel_cmd_msg.data = accel_cmd;
112  pub_req_accel_.publish(accel_cmd_msg);
113 
114  if (sys_enable_) {
115  dbw_mkz_msgs::ThrottleCmd throttle_cmd;
116  dbw_mkz_msgs::BrakeCmd brake_cmd;
117  dbw_mkz_msgs::SteeringCmd steering_cmd;
118 
119  throttle_cmd.enable = true;
120  throttle_cmd.pedal_cmd_type = dbw_mkz_msgs::ThrottleCmd::CMD_PERCENT;
121  if (accel_cmd >= 0) {
122  throttle_cmd.pedal_cmd = accel_pid_.step(accel_cmd - lpf_accel_.get(), control_period_);
123  } else {
125  throttle_cmd.pedal_cmd = 0;
126  }
127 
128  brake_cmd.enable = true;
129  brake_cmd.pedal_cmd_type = dbw_mkz_msgs::BrakeCmd::CMD_TORQUE;
130  if (accel_cmd < -cfg_.brake_deadband) {
131  brake_cmd.pedal_cmd = -accel_cmd * vehicle_mass * cfg_.wheel_radius;
132  } else {
133  brake_cmd.pedal_cmd = 0;
134  }
135 
136  steering_cmd.enable = true;
137  steering_cmd.steering_wheel_angle_cmd = yaw_control_.getSteeringWheelAngle(cmd_vel_.twist.linear.x, cmd_vel_.twist.angular.z, actual_.linear.x)
138  + cfg_.steer_kp * (cmd_vel_.twist.angular.z - actual_.angular.z);
139 
140  if (cfg_.pub_pedals) {
141  pub_throttle_.publish(throttle_cmd);
142  pub_brake_.publish(brake_cmd);
143  }
144 
145  if (cfg_.pub_steering) {
146  pub_steering_.publish(steering_cmd);
147  }
148  } else {
151  }
152 }
153 
154 void TwistControllerNode::reconfig(ControllerConfig& config, uint32_t level)
155 {
156  cfg_ = config;
157  cfg_.vehicle_mass -= cfg_.fuel_capacity * GAS_DENSITY; // Subtract weight of full gas tank
158  cfg_.vehicle_mass += 150.0; // Account for some passengers
159 
160  speed_pid_.setGains(cfg_.speed_kp, 0.0, 0.0);
161  accel_pid_.setGains(cfg_.accel_kp, cfg_.accel_ki, 0.0);
162  yaw_control_.setLateralAccelMax(cfg_.max_lat_accel);
163  lpf_accel_.setParams(cfg_.accel_tau, 0.02);
164 }
165 
166 void TwistControllerNode::recvTwist(const geometry_msgs::Twist::ConstPtr& msg)
167 {
168  cmd_vel_.twist = *msg;
169  cmd_vel_.accel_limit = 0;
170  cmd_vel_.decel_limit = 0;
172 }
173 
174 void TwistControllerNode::recvTwist2(const dbw_mkz_msgs::TwistCmd::ConstPtr& msg)
175 {
176  cmd_vel_ = *msg;
178 }
179 
180 void TwistControllerNode::recvTwist3(const geometry_msgs::TwistStamped::ConstPtr& msg)
181 {
182  cmd_vel_.twist = msg->twist;
183  cmd_vel_.accel_limit = 0;
184  cmd_vel_.decel_limit = 0;
186 }
187 
188 void TwistControllerNode::recvFuel(const dbw_mkz_msgs::FuelLevelReport::ConstPtr& msg)
189 {
190  lpf_fuel_.filt(msg->fuel_level);
191 }
192 
193 void TwistControllerNode::recvSteeringReport(const dbw_mkz_msgs::SteeringReport::ConstPtr& msg)
194 {
195  double raw_accel = 50.0 * (msg->speed - actual_.linear.x);
196  lpf_accel_.filt(raw_accel);
197 
198  std_msgs::Float64 accel_msg;
199  accel_msg.data = lpf_accel_.get();
200  pub_accel_.publish(accel_msg);
201 
202  actual_.linear.x = msg->speed;
203 }
204 
205 void TwistControllerNode::recvImu(const sensor_msgs::Imu::ConstPtr& msg)
206 {
207  actual_.angular.z = msg->angular_velocity.z;
208 }
209 
210 void TwistControllerNode::recvEnable(const std_msgs::Bool::ConstPtr& msg)
211 {
212  sys_enable_ = msg->data;
213 }
214 
215 }
216 
static const double GAS_DENSITY
void publish(const boost::shared_ptr< M > &message) const
void setRange(double min, double max)
Definition: PidControl.h:54
void recvEnable(const std_msgs::Bool::ConstPtr &msg)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void controlCallback(const ros::TimerEvent &event)
double getSteeringWheelAngle(double cmd_vx, double cmd_wz, double speed)
Definition: YawControl.h:50
void recvSteeringReport(const dbw_mkz_msgs::SteeringReport::ConstPtr &msg)
void recvFuel(const dbw_mkz_msgs::FuelLevelReport::ConstPtr &msg)
void recvTwist(const geometry_msgs::Twist::ConstPtr &msg)
double filt(double val)
Definition: LowPass.h:49
bool param(const std::string &param_name, T &param_val, const T &default_val) const
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
TwistControllerNode(ros::NodeHandle &n, ros::NodeHandle &pn)
void reconfig(ControllerConfig &config, uint32_t level)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void setGains(double kp, double ki, double kd)
Definition: PidControl.h:53
dynamic_reconfigure::Server< ControllerConfig > srv_
void recvTwist2(const dbw_mkz_msgs::TwistCmd::ConstPtr &msg)
bool getParam(const std::string &key, std::string &s) const
double step(double error, double sample_time)
Definition: PidControl.h:59
static Time now()
void recvImu(const sensor_msgs::Imu::ConstPtr &msg)
void setParams(double tau, double ts)
Definition: LowPass.h:44
void recvTwist3(const geometry_msgs::TwistStamped::ConstPtr &msg)


dbw_mkz_twist_controller
Author(s): Micho Radovnikovich , Kevin Hallenbeck
autogenerated on Thu Nov 14 2019 03:46:10