48 }
else if (value > max) {
56 static T
overflowSaturation(
double input, T limit_min, T limit_max,
double scale_factor,
const std::string& input_name,
const std::string& units)
58 if (input < (limit_min * scale_factor)) {
59 ROS_WARN(
"%s [%f %s] out of range -- saturating to %f %s", input_name.c_str(), input, units.c_str(), limit_min * scale_factor, units.c_str());
61 }
else if (input > (limit_max * scale_factor)) {
62 ROS_WARN(
"%s [%f %s] out of range -- saturating to %f %s", input_name.c_str(), input, units.c_str(), limit_max * scale_factor, units.c_str());
65 return input / scale_factor;
69 static inline bool validInputs(
const dataspeed_ulc_msgs::UlcCmd& cmd)
72 if (std::isnan(cmd.linear_velocity)) {
73 ROS_WARN(
"NaN input detected on speed input");
76 if (std::isnan(cmd.yaw_command)) {
77 ROS_WARN(
"NaN input detected on yaw command input");
80 if (std::isnan(cmd.linear_accel)) {
81 ROS_WARN(
"NaN input detected on linear accel input");
84 if (std::isnan(cmd.linear_decel)) {
85 ROS_WARN(
"NaN input detected on linear decel input");
88 if (std::isnan(cmd.lateral_accel)) {
89 ROS_WARN(
"NaN input detected on lateral accel input");
92 if (std::isnan(cmd.angular_accel)) {
93 ROS_WARN(
"NaN input detected on angular accel input");
128 bool diff = (msg->linear_accel !=
ulc_cmd_.linear_accel)
129 || (msg->linear_decel !=
ulc_cmd_.linear_decel)
130 || (msg->lateral_accel !=
ulc_cmd_.lateral_accel)
131 || (msg->angular_accel !=
ulc_cmd_.angular_accel);
146 ulc_cmd_.linear_velocity = msg.linear.x;
147 ulc_cmd_.yaw_command = msg.angular.z;
148 ulc_cmd_.steering_mode = dataspeed_ulc_msgs::UlcCmd::YAW_RATE_MODE;
177 if (!msg->is_rtr && !msg->is_error && !msg->is_extended) {
182 dataspeed_ulc_msgs::UlcReport report;
183 report.header.stamp = msg->header.stamp;
185 report.accel_ref = (float)ptr->
accel_ref * 0.05f;
186 report.speed_meas = (
float)ptr->
speed_meas * 0.02f;
187 report.accel_meas = (float)ptr->
accel_meas * 0.05f;
195 report.override_latched = ptr->
override;
220 msg.is_extended =
false;
223 memset(ptr, 0x00,
sizeof(*ptr));
237 if (
ulc_cmd_.steering_mode == dataspeed_ulc_msgs::UlcCmd::YAW_RATE_MODE) {
239 }
else if (
ulc_cmd_.steering_mode == dataspeed_ulc_msgs::UlcCmd::CURVATURE_MODE) {
257 msg.is_extended =
false;
260 memset(ptr, 0x00,
sizeof(*ptr));
ros::Subscriber sub_twist_stamped_
void recvEnable(const std_msgs::BoolConstPtr &msg)
#define ROS_WARN_THROTTLE(rate,...)
void publish(const boost::shared_ptr< M > &message) const
void recvTwistCmd(const geometry_msgs::Twist &msg)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void sendCmdMsg(bool cfg)
void recvCan(const can_msgs::FrameConstPtr &msg)
dataspeed_ulc_msgs::UlcCmd ulc_cmd_
uint16_t steering_enabled
TransportHints & tcpNoDelay(bool nodelay=true)
void recvTwist(const geometry_msgs::TwistConstPtr &msg)
UlcNode(ros::NodeHandle &n, ros::NodeHandle &pn)
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
void recvTwistStamped(const geometry_msgs::TwistStampedConstPtr &msg)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
uint8_t steering_preempted
ros::Subscriber sub_enable_
uint8_t max_steering_angle
bool getParam(const std::string &key, std::string &s) const
ros::Publisher pub_report_
static T overflowSaturation(double input, T limit_min, T limit_max, double scale_factor, const std::string &input_name, const std::string &units)
ros::Subscriber sub_twist_
static void getParamWithSaturation(ros::NodeHandle &nh, const std::string &key, T &value, T min, T max)
void recvUlcCmd(const dataspeed_ulc_msgs::UlcCmdConstPtr &msg)
static bool validInputs(const dataspeed_ulc_msgs::UlcCmd &cmd)
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
void configTimerCb(const ros::TimerEvent &event)