velocity_limited_marker.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
19 
20 #include <tf/tf.h>
21 
22 
24 {
25 
26 const double DEFAULT_LIFETIME = 1.0;
27 const double DEFAULT_Z_POSITION = 0.25;
28 
29 const double MARKER_SCALE_DIR = 1.0;
30 const double MARKER_RADIUS_DIR = 0.5;
31 const double MARKER_WIDTH_DIR = 0.2;
32 
33 const double MARKER_SCALE_ROT = 1.0;
34 const double MARKER_RADIUS_ROT = 0.6;
35 //const double MARKER_WIDTH_ROT = 0.065;
36 const double MARKER_WIDTH_ROT = 0.15;
37 
38 //const double MAX_VELOCITY = 0.2;
39 const double MAX_VELOCITY = 0.25;
40 const double MIN_VELOCITY = 0.01;
41 const double VELOCITY_COEFF = 1.0 / (MAX_VELOCITY - MIN_VELOCITY);
42 
43 const float MAX_COLOR[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
44 const float MIN_COLOR[4] = { 1.0f, 0.8f, 0.0f, 0.2f };
45 
46 
48 {
49  // a handle for this node, initialize node
50  nh_ = ros::NodeHandle("~");
51 
52  // read parameters from parameter server
53  nh_.param("marker_frame", base_frame_, std::string("/base_link"));
54  nh_.param("marker_topic_name", topic_name_, std::string("velocity_limited_marker"));
55  nh_.param("marker_lifetime", lifetime_, DEFAULT_LIFETIME);
56  nh_.param("z_pos", z_pos_, DEFAULT_Z_POSITION);
57  nh_.param("marker_disabled", disabled_, false);
58 
59  // Create the publisher
60  marker_pub_ = nh_.advertise<visualization_msgs::Marker>(topic_name_, 1);
61 
62  vx_last_ = 0.0;
63  vy_last_ = 0.0;
64  vtheta_last_ = 0.0;
65 
66  // Create the markers
69 }
70 
71 
73 {
74 }
75 
76 
78 {
79  // Message template
80  visualization_msgs::Marker marker;
81  marker.header.frame_id = base_frame_;
82  marker.header.stamp = ros::Time::now();
83  marker.ns = "cob_velocity_limited_marker";
84  marker.id = 0;
85  marker.type = visualization_msgs::Marker::TRIANGLE_LIST;
86  marker.action = visualization_msgs::Marker::ADD;
87  marker.lifetime = ros::Duration(lifetime_);
88  marker.pose.orientation.x = 0;
89  marker.pose.orientation.y = 0;
90  marker.pose.orientation.z = 0;
91  marker.pose.orientation.w = 1;
92  marker.pose.position.x = 0;
93  marker.pose.position.y = 0;
94  marker.pose.position.z = z_pos_;
95  marker.scale.x = MARKER_SCALE_DIR;
96  marker.scale.y = MARKER_SCALE_DIR;
97  marker.scale.z = 1.0;
98  marker.color.r = 1.0;
99  marker.color.g = 0.0;
100  marker.color.b = 0.0;
101  marker.color.a = 0.5; // adjust according to the velocity?
102 
103  // Create the disc like geometry for the markers
104  std::vector<geometry_msgs::Point> circle1, circle2;
105  geometry_msgs::Point v1, v2;
106 
107  static const int STEPS = 36;
108  static const int FIRST = -4;
109  static const int LAST = 4;
110  for( int i = FIRST; i <= LAST; ++i )
111  {
112  float a = float(i) / float(STEPS) * M_PI * 2.0;
113  float cosa = cos(a);
114  float sina = sin(a);
115 
116  v1.x = MARKER_RADIUS_DIR * cosa;
117  v1.y = MARKER_RADIUS_DIR * sina;
118  v2.x = (MARKER_RADIUS_DIR + MARKER_WIDTH_DIR) * cosa;
119  v2.y = (MARKER_RADIUS_DIR + MARKER_WIDTH_DIR) * sina;
120 
121  circle1.push_back(v1);
122  circle2.push_back(v2);
123  }
124 
125  marker.points.clear();
126  for( std::size_t i = 0; i < (circle1.size() - 1); ++i )
127  {
128  std::size_t i1 = i;
129  std::size_t i2 = (i + 1) % circle1.size();
130 
131  marker.points.push_back(circle1[i1]);
132  marker.points.push_back(circle2[i1]);
133  marker.points.push_back(circle1[i2]);
134 
135  marker.points.push_back(circle1[i2]);
136  marker.points.push_back(circle2[i2]);
137  marker.points.push_back(circle2[i1]);
138  }
139 
140  // Particular messages for each axis
141  x_pos_marker_ = marker;
142  x_pos_marker_.id = 0;
143  x_pos_marker_.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, 0, 0);
144 
145  x_neg_marker_ = marker;
146  x_neg_marker_.id = 1;
147  x_neg_marker_.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, 0, M_PI);
148 
149  y_pos_marker_ = marker;
150  y_pos_marker_.id = 2;
151  y_pos_marker_.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, 0, 0.5 * M_PI);
152 
153  y_neg_marker_ = marker;
154  y_neg_marker_.id = 3;
155  y_neg_marker_.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, 0, -0.5 * M_PI);
156 }
157 
158 
160 {
161  // Message template
162  visualization_msgs::Marker marker;
163  marker.header.frame_id = base_frame_;
164  marker.header.stamp = ros::Time::now();
165  marker.ns = "cob_velocity_limited_marker";
166  marker.id = 0;
167  marker.type = visualization_msgs::Marker::TRIANGLE_LIST;
168  marker.action = visualization_msgs::Marker::ADD;
169  marker.lifetime = ros::Duration(lifetime_);
170  marker.pose.orientation.x = 0;
171  marker.pose.orientation.y = 0;
172  marker.pose.orientation.z = 0;
173  marker.pose.orientation.w = 1;
174  marker.pose.position.x = 0;
175  marker.pose.position.y = 0;
176  marker.pose.position.z = z_pos_;
177  marker.scale.x = MARKER_SCALE_ROT;
178  marker.scale.y = MARKER_SCALE_ROT;
179  marker.scale.z = 1.0;
180  marker.color.r = 1.0;
181  marker.color.g = 0.0;
182  marker.color.b = 0.0;
183  marker.color.a = 0.5; // adjust according to the velocity?
184 
185  // Create the disc like geometry for the markers
186  std::vector<geometry_msgs::Point> circle1, circle2, circle3;
187  geometry_msgs::Point v1, v2, v3;
188 
189  static const int STEPS = 48;
190  static const int FIRST = 0;
191  static const int LAST = 23;
192  for( int i = FIRST; i <= LAST; ++i )
193  {
194  float a = float(2*i) / float(STEPS) * M_PI * 2.0;
195  float cosa = cos(a);
196  float sina = sin(a);
197 
198  v1.x = MARKER_RADIUS_ROT * cosa;
199  v1.y = MARKER_RADIUS_ROT * sina;
200  v2.x = (MARKER_RADIUS_ROT + MARKER_WIDTH_ROT) * cosa;
201  v2.y = (MARKER_RADIUS_ROT + MARKER_WIDTH_ROT) * sina;
202 
203  circle1.push_back(v1);
204  circle2.push_back(v2);
205 
206  a = float(2*i+1) / float(STEPS) * M_PI * 2.0;
207  cosa = cos(a);
208  sina = sin(a);
209 
210  v3.x = (MARKER_RADIUS_ROT + 0.5 * MARKER_WIDTH_ROT) * cosa;
211  v3.y = (MARKER_RADIUS_ROT + 0.5 * MARKER_WIDTH_ROT) * sina;
212 
213  circle3.push_back(v3);
214  }
215 
216  marker.points.clear();
217  for( std::size_t i = 0; i < circle1.size(); ++i )
218  {
219  marker.points.push_back(circle1[i]);
220  marker.points.push_back(circle2[i]);
221  marker.points.push_back(circle3[i]);
222  }
223 
224  // Particular messages for each axis
225  theta_pos_marker_ = marker;
226  theta_pos_marker_.id = 4;
228 
229  theta_neg_marker_ = marker;
230  theta_neg_marker_.id = 5;
231  theta_neg_marker_.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(M_PI, 0, 0);
232 }
233 
234 
235 void VelocityLimitedMarker::interpolateColor(double velocity, std_msgs::ColorRGBA& color)
236 {
237  if( velocity < MIN_VELOCITY )
238  {
239  color.r = color.g = color.b = color.a = 0.0f;
240  return;
241  }
242 
243  float alpha = float((velocity - MIN_VELOCITY) * VELOCITY_COEFF);
244  alpha = (alpha > 1.0f) ? 1.0f : alpha;
245 
246  color.r = (1.0f - alpha) * MIN_COLOR[0] + alpha * MAX_COLOR[0];
247  color.g = (1.0f - alpha) * MIN_COLOR[1] + alpha * MAX_COLOR[1];
248  color.b = (1.0f - alpha) * MIN_COLOR[2] + alpha * MAX_COLOR[2];
249  color.a = (1.0f - alpha) * MIN_COLOR[3] + alpha * MAX_COLOR[3];
250 }
251 
252 
253 void VelocityLimitedMarker::publishMarkers( double vel_x_desired,
254  double vel_x_actual,
255  double vel_y_desired,
256  double vel_y_actual,
257  double vel_theta_desired,
258  double vel_theta_actual)
259 {
260  if( disabled_ )
261  {
262  return;
263  }
264 
265  // Publish the markers
266  double epsilon = 0.05;
267 
268  // acceleration
269  double ax,ay,atheta;
270  ax = vel_x_actual - vx_last_;
271  ay = vel_y_actual - vy_last_;
272  atheta = vel_theta_actual - vtheta_last_;
273  vx_last_ = vel_x_actual;
274  vy_last_ = vel_y_actual;
275  vtheta_last_ = vel_theta_actual;
276 
277  // for x-axis
278  double x_vel_diff = fabs(vel_x_desired - vel_x_actual);
279  if( x_vel_diff >= epsilon )
280  {
281 // double alpha = x_vel_diff * VELOCITY_COEFF;
282  if (vel_x_desired >= 0.0 && ax <= 0.0)
283  {
284  x_pos_marker_.header.stamp = ros::Time::now();
285  interpolateColor(x_vel_diff, x_pos_marker_.color);
286 // x_pos_marker_.color.a = (alpha > 1.0) ? 1.0 : alpha;
288  }
289  else if (vel_x_desired <= 0.0 && ax >= 0.0)
290  {
291  x_neg_marker_.header.stamp = ros::Time::now();
292  interpolateColor(x_vel_diff, x_neg_marker_.color);
293 // x_neg_marker_.color.a = (alpha > 1.0) ? 1.0 : alpha;
295  }
296  }
297 
298  // for y-axis
299  double y_vel_diff = fabs(vel_y_desired - vel_y_actual);
300  if( y_vel_diff >= epsilon )
301  {
302 // double alpha = y_vel_diff * VELOCITY_COEFF;
303  if (vel_y_desired >= 0.0 && ay <= 0.0)
304  {
305  y_pos_marker_.header.stamp = ros::Time::now();
306  interpolateColor(y_vel_diff, y_pos_marker_.color);
307 // y_pos_marker_.color.a = (alpha > 1.0) ? 1.0 : alpha;
309  }
310  else if (vel_y_desired <= 0.0 && ay >= 0.0)
311  {
312  y_neg_marker_.header.stamp = ros::Time::now();
313  interpolateColor(y_vel_diff, y_neg_marker_.color);
314 // y_neg_marker_.color.a = (alpha > 1.0) ? 1.0 : alpha;
316  }
317  }
318 
319  // for theta-axis
320  double theta_vel_diff = fabs(vel_theta_desired - vel_theta_actual);
321  if( theta_vel_diff >= epsilon )
322  {
323 // double alpha = theta_vel_diff * VELOCITY_COEFF;
324  if (vel_theta_desired >= 0.0 && atheta <= 0.0)
325  {
326  theta_pos_marker_.header.stamp = ros::Time::now();
327  interpolateColor(theta_vel_diff, theta_pos_marker_.color);
328 // theta_pos_marker_.color.a = (alpha > 1.0) ? 1.0 : alpha;
330  }
331  else if (vel_theta_desired <= 0.0 && atheta >= 0.0)
332  {
333  theta_neg_marker_.header.stamp = ros::Time::now();
334  interpolateColor(theta_vel_diff, theta_neg_marker_.color);
335 // theta_neg_marker_.color.a = (alpha > 1.0) ? 1.0 : alpha;
337  }
338  }
339 }
340 
341 
342 }
343 
void interpolateColor(double velocity, std_msgs::ColorRGBA &color)
Calculates the color for the marker.
void publish(const boost::shared_ptr< M > &message) const
f
void createRotationalMarkers()
Creates all rotational markers, the method is called from the constructor.
void publishMarkers(double vel_x_desired, double vel_x_actual, double vel_y_desired, double vel_y_actual, double vel_theta_desired, double vel_theta_actual)
Creates all the markers, the method is called from the constructor.
bool param(const std::string &param_name, T &param_val, const T &default_val) const
double epsilon
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void createDirectionalMarkers()
Creates all directional markers, the method is called from the constructor.
static geometry_msgs::Quaternion createQuaternionMsgFromRollPitchYaw(double roll, double pitch, double yaw)
static Time now()
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)


cob_collision_velocity_filter
Author(s): Matthias Gruhler, Michal Spanel
autogenerated on Thu Apr 8 2021 02:39:36