radar_object_marker.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018, SICK AG
3  * Copyright (C) 2018, Ing.-Buero Dr. Michael Lehning
4  * Copyright (C) 2016, DFKI GmbH
5  * All rights reserved.
6  *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *
20 * All rights reserved.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions are met:
24 *
25 * * Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
27 * * Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * * Neither the name of Osnabrueck University nor the names of its
31 * contributors may be used to endorse or promote products derived from
32 * this software without specific prior written permission.
33 * * Neither the name of SICK AG nor the names of its
34 * contributors may be used to endorse or promote products derived from
35 * this software without specific prior written permission
36 * * Neither the name of Ing.-Buero Dr. Michael Lehning nor the names of its
37 * contributors may be used to endorse or promote products derived from
38 * this software without specific prior written permission
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
44 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
45 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
46 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
47 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
48 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
50 * POSSIBILITY OF SUCH DAMAGE.
51  *
52  */
53 
54 #include <ros/ros.h>
55 
57 #include <sick_scan/RadarScan.h>
58 
59 #include <ros/ros.h>
60 #include <ros/package.h>
61 #include <math.h>
63 #include <sick_scan/RadarScan.h>
66 //#include <boost/serialization/singleton.hpp>
67 
68 float ballRadius = 0.1;
69 float objectArrowScale = 1.0;
71 bool usingPal = false;
72 
75 
76 
77 
78 
79 void normalize( float& angle )
80 {
81  while ( angle < -M_PI ) angle += (2 * M_PI);
82  while ( angle > M_PI ) angle -= (2 * M_PI);
83 }
84 
85 bool isWithinRange( float testAngle, float a, float b )
86 {
87  a -= testAngle;
88  b -= testAngle;
89  normalize( a );
90  normalize( b );
91  if ( a * b >= 0 )
92  return false; // lying on the same side
93  return fabs( a - b ) < M_PI;
94 }
95 
96 
97 
98 /* check for both directions */
99 bool checkForAngleInterval(float orgAngle, float* dstAngle, float mainAngle, float mainAngleTol)
100 {
101  float tmpAngle;
102  bool bRet = isWithinRange(orgAngle, mainAngle - mainAngleTol, mainAngle + mainAngleTol);
103  if (bRet == true)
104  {
105  tmpAngle = mainAngle;
106  normalize(tmpAngle);
107  *dstAngle = tmpAngle;
108  return(bRet);
109  }
110  bRet = isWithinRange(orgAngle, M_PI + mainAngle - mainAngleTol, M_PI + mainAngle + mainAngleTol);
111  if (bRet == true)
112  {
113  tmpAngle = mainAngle + M_PI;
114  normalize(tmpAngle);
115  *dstAngle = tmpAngle;
116  return(bRet);
117 
118  }
119 
120 
121 
122  return(bRet);
123 
124 
125 
126 }
127 
129 {
130  bool bRet = false;
131  double testAngleArrDeg[] = {-161.0, -10.0, -20.0, -30.0, 330.0, 10.0, 20.0, 30.0, -160.0};
132 
133  std::vector<double> testAngleArr;
134 
135  for ( int i =0; i < sizeof(testAngleArrDeg)/sizeof(testAngleArrDeg[0]); i++)
136  {
137  double tmpAngle = testAngleArrDeg[i] / 180.0 * M_PI;
138  testAngleArr.push_back(tmpAngle);
139  }
140 
141 
142  double mainAngle = 20.0/180.0 * M_PI;
143  double mainAngleTol = 30.0/180.0 * M_PI;
144  for (int i = 0; i < testAngleArr.size(); i++)
145  {
146  float angle = testAngleArr[i];
147  float dstAngle;
148  bRet = checkForAngleInterval(angle, &dstAngle, mainAngle, mainAngleTol);
149 
150  printf("Ergebnis: %2d %6.2lf %6.2lf %s\n", i, angle, dstAngle, bRet ? "JA" : "NEIN");
151  }
152  return bRet;
153 }
154 
155 
156 
158  {
159  RadarObjectMarkerCfg *cfgPtr = &boost::serialization::singleton<RadarObjectMarkerCfg>::get_mutable_instance();
160 
161  enum TARGET_MARKER_TYPE {TARGET_MARKER_BALL, TARGET_MARKER_ARROW, TARGET_MARKER_NUM};
162  visualization_msgs::MarkerArray rawTargetArray[TARGET_MARKER_NUM]; // ball and arrow
163  sensor_msgs::PointCloud2 cloud_msg;
164 
165  for (int i = 0; i < TARGET_MARKER_NUM; i++)
166  {
167  rawTargetArray[i].markers.resize(oa->targets.width);
168  }
169 
170  int coordIdx[3] = {0};
171  int vradIdx = -1;
172  int amplitudeIdx = -1;
173 
174  for (int i = 0; i < 3; i++)
175  {
176  coordIdx[i] = -1;
177  }
178 
179 
180  bool useCurrTimeStamp = true;
181  ros::Time currTimeStamp = ros::Time::now(); // timestamp incoming package, will be overwritten by get_datagram
182  for (int i = 0; i < oa->targets.fields.size(); i++)
183  {
184  std::string fieldName = oa->targets.fields[i].name;
185  // x,y,z, vrad, amplitude
186  if (fieldName.compare("x") == 0)
187  {
188  coordIdx[0] = i;
189  }
190  if (fieldName.compare("y") == 0)
191  {
192  coordIdx[1] = i;
193  }
194  if (fieldName.compare("z") == 0)
195  {
196  coordIdx[2] = i;
197  }
198  if (fieldName.compare("vrad") == 0)
199  {
200  vradIdx = i;
201  }
202  if (fieldName.compare("amplitude") == 0)
203  {
204  amplitudeIdx = i;
205  }
206 
207  // printf("%s\n", fieldName.c_str());
208  }
209 
210  int numRawTargets = oa->targets.width;
211 
212  if (numRawTargets > 0)
213  {
214  cloud_msg.header = oa->header;
215 
216  if (useCurrTimeStamp)
217  {
218  cloud_msg.header.stamp = currTimeStamp;
219  }
220 
221  cloud_msg.height = oa->targets.height;
222  cloud_msg.width = oa->targets.width;
223  cloud_msg.row_step = oa->targets.row_step;
224  cloud_msg.point_step = oa->targets.point_step;
225  cloud_msg.data = oa->targets.data;
226  cloud_msg.fields = oa->targets.fields;
227  cloud_msg.is_dense = oa->targets.is_dense;
228  cloud_msg.is_bigendian = oa->targets.is_bigendian;
229  pub_cloud.publish(cloud_msg);
230  }
231  for (size_t i = 0; i < oa->targets.width; i++)
232  {
233  int tmpId = i;
234  float ampl = 0.0;
235  float xs, ys;
236  float pts3d[3];
237  float vrad = 0.0;
238  for (int ii = 0; ii < 3; ii++)
239  {
240  if (coordIdx[ii] != -1)
241  {
242  int tmpIdx = coordIdx[ii];
243  float *valPtr = (float *) (&(oa->targets.data[0]) + i * oa->targets.point_step +
244  oa->targets.fields[tmpIdx].offset);
245  pts3d[ii] = *valPtr;
246  }
247  }
248  if (vradIdx != -1)
249  {
250  int tmpIdx = vradIdx;
251  float *valPtr = (float *) (&(oa->targets.data[0]) + i * oa->targets.point_step +
252  oa->targets.fields[tmpIdx].offset);
253  vrad = *valPtr;
254  }
255  if (amplitudeIdx)
256  {
257  int tmpIdx = amplitudeIdx;
258  float *valPtr = (float *) (&(oa->targets.data[0]) + i * oa->targets.point_step +
259  oa->targets.fields[tmpIdx].offset);
260  ampl = *valPtr;
261 
262  }
263 
264  for (int iLoop = 0; iLoop < TARGET_MARKER_NUM; iLoop++)
265  {
266 
267  rawTargetArray[iLoop].markers[i].header = oa->header;
268 
269  if (useCurrTimeStamp)
270  {
271  rawTargetArray[iLoop].markers[i].header.stamp = currTimeStamp;
272  }
273 
274  rawTargetArray[iLoop].markers[i].ns = "rawtargets";
275  rawTargetArray[iLoop].markers[i].id = tmpId + iLoop * numRawTargets;
276  switch (iLoop)
277  {
278  case TARGET_MARKER_ARROW:
279  {
280  rawTargetArray[iLoop].markers[i].type = visualization_msgs::Marker::ARROW;
281  rawTargetArray[iLoop].markers[i].scale.x = 0.1;
282  rawTargetArray[iLoop].markers[i].scale.y = 0.2;
283 
284  rawTargetArray[iLoop].markers[i].points.resize(2);
285  rawTargetArray[iLoop].markers[i].points[0].x = pts3d[0];
286  rawTargetArray[iLoop].markers[i].points[0].y = pts3d[1];
287  rawTargetArray[iLoop].markers[i].points[0].z = pts3d[2];
288  float lineOfSight = atan2(pts3d[1], pts3d[0]);
289  rawTargetArray[iLoop].markers[i].points[1].x = pts3d[0] + cos(lineOfSight) * vrad * 0.1;
290  rawTargetArray[iLoop].markers[i].points[1].y = pts3d[1] + sin(lineOfSight) * vrad * 0.1;
291  rawTargetArray[iLoop].markers[i].points[1].z = pts3d[2];
292 
293  }
294  break;
295  case TARGET_MARKER_BALL:
296  rawTargetArray[iLoop].markers[i].type = visualization_msgs::Marker::SPHERE;
297  rawTargetArray[iLoop].markers[i].scale.x = ballRadius;
298  rawTargetArray[iLoop].markers[i].scale.y = ballRadius;
299  rawTargetArray[iLoop].markers[i].scale.z = ballRadius;
300 
301 
302  rawTargetArray[iLoop].markers[i].pose.position.x = pts3d[0];
303  rawTargetArray[iLoop].markers[i].pose.position.y = pts3d[1];
304  rawTargetArray[iLoop].markers[i].pose.position.z = pts3d[2];
305  rawTargetArray[iLoop].markers[i].pose.orientation.x = 0.0;
306  rawTargetArray[iLoop].markers[i].pose.orientation.y = 0.0;
307  rawTargetArray[iLoop].markers[i].pose.orientation.z = 0.0;
308  rawTargetArray[iLoop].markers[i].pose.orientation.w = 1.0;
309  break;
310 
311  }
312  rawTargetArray[iLoop].markers[i].action = visualization_msgs::Marker::ADD;
313  if (cfgPtr->isPaletteUsed())
314  {
316  float idxRange = ampl - cfgPtr->getPaletteMinAmpl();
317  double rangeAmpl = cfgPtr->getPaletteMaxAmpl() - cfgPtr->getPaletteMinAmpl();
318  idxRange /= rangeAmpl;
319  if (idxRange < 0.0)
320  {
321  idxRange = 0.0;
322  }
323  if (idxRange > 1.0)
324  {
325  idxRange = 1.0;
326  }
327  unsigned char greyIdx = (unsigned char)(255.999 * idxRange);
328  unsigned char red = pal.getRbgValue(greyIdx, 0U);
329  unsigned char green = pal.getRbgValue(greyIdx, 1U);
330  unsigned char blue = pal.getRbgValue(greyIdx, 2U);
331 
332  float redF, greenF, blueF;
333  redF = red / 255.00;
334  greenF = green / 255.00;
335  blueF = blue / 255.00;
336  rawTargetArray[iLoop].markers[i].color.a = 0.75;
337  rawTargetArray[iLoop].markers[i].color.r = redF;
338  rawTargetArray[iLoop].markers[i].color.g = greenF;
339  rawTargetArray[iLoop].markers[i].color.b = blueF;
340  }
341  else{
342  rawTargetArray[iLoop].markers[i].color.a = 0.75;
343  rawTargetArray[iLoop].markers[i].color.r = GLASBEY_LUT[tmpId * 3] / 255.0;
344  rawTargetArray[iLoop].markers[i].color.g = GLASBEY_LUT[tmpId * 3 + 1] / 255.0;
345  rawTargetArray[iLoop].markers[i].color.b = GLASBEY_LUT[tmpId * 3 + 2] / 255.0;
346  }
347  rawTargetArray[iLoop].markers[i].lifetime = ros::Duration(0.5);
348 
349 
350  }
351  }
352 
353  for (int iLoop = 0; iLoop < TARGET_MARKER_NUM; iLoop++)
354  {
355  pub.publish(rawTargetArray[iLoop]);
356  }
357 
358  /***********************************************************************
359  *
360  *
361  * Drawing marker for objects
362  *
363  ***********************************************************************
364  */
365  visualization_msgs::MarkerArray object_boxes;
366  object_boxes.markers.resize(2 * oa->objects.size());
367 
368  visualization_msgs::MarkerArray object_labels;
369  object_labels.markers.resize(1 * oa->objects.size());
370 
371  float vp_dir = 0.0;
372  float vp_dir_deg = 0.0;
373 
374  double angleMainDirDeg = 20;
375  double angleMainDir = angleMainDirDeg / 180.0 * M_PI;
376  double angleMainDirTolDeg = 20.0;
377  double angleMainDirTol = angleMainDirTolDeg / 180.0 * M_PI;
378 
379  std::vector<float> vehiclePredefinedDir;
380  std::vector<float> vehicleAbsoluteSpeed;
381  std::vector<bool> vehicleIsInPredefinedDir;
382 
383  int objNum = oa->objects.size();
384 
385  vehiclePredefinedDir.resize(objNum);
386  vehicleIsInPredefinedDir.resize(objNum); // flag arraw whether the vehicle drives in tihs dir. or not
387  vehicleAbsoluteSpeed.resize(objNum);
388 
389  for (int iLoop = 0; iLoop < 2; iLoop++)
390  {
391  for (size_t i = 0; i < oa->objects.size(); i++)
392  {
393  int colorId = oa->objects[i].id % 256;
394  float vp[3];
395  vp[0] = oa->objects[i].velocity.twist.linear.x;
396  vp[1] = oa->objects[i].velocity.twist.linear.y;
397  vp[2] = oa->objects[i].velocity.twist.linear.z;
398  float vabs = sqrt(vp[0] * vp[0] + vp[1]*vp[1] + vp[2]*vp[2]);
399  vehicleAbsoluteSpeed[i] = vabs;
400  vp_dir = atan2(vp[1], vp[0]);
401  vp_dir_deg = vp_dir / 3.141592 * 180.0;
402  float dstAngle;
403 
404  bool bRet = checkForAngleInterval(vp_dir, &dstAngle, angleMainDir, angleMainDirTol);
405  vehiclePredefinedDir[i] = dstAngle;
406  vehicleIsInPredefinedDir[i] = bRet;
407 
408  int idx = i + iLoop * oa->objects.size();
409  int tmpId = i; // better: oa->objects[i].id;
410  object_boxes.markers[idx].header = oa->header;
411 
412  if (useCurrTimeStamp)
413  {
414  object_boxes.markers[idx].header.stamp = currTimeStamp;
415  }
416  std::string nameSpaceBoxes = "object_boxes_slow";
417  if (vabs > 5.0)
418  {
419  nameSpaceBoxes = "object_boxes_fast";
420  }
421  object_boxes.markers[idx].ns = nameSpaceBoxes;
422  object_boxes.markers[idx].id = tmpId + iLoop * oa->objects.size(); // i; // oa->objects[i].id;
423  object_boxes.markers[idx].action = visualization_msgs::Marker::ADD;
424  object_boxes.markers[idx].color.a = 0.75;
425  object_boxes.markers[idx].color.r = GLASBEY_LUT[colorId * 3] / 255.0;
426  object_boxes.markers[idx].color.g = GLASBEY_LUT[colorId * 3 + 1] / 255.0;
427  object_boxes.markers[idx].color.b = GLASBEY_LUT[colorId * 3 + 2] / 255.0;
428  object_boxes.markers[idx].lifetime = ros::Duration(1.0);
429 
430  if (iLoop == 0)
431  {
432  object_labels.markers[i].header = oa->header;
433  if (useCurrTimeStamp)
434  {
435  if (iLoop == 0) {
436  object_labels.markers[i].header.stamp = currTimeStamp;
437  }
438  }
439 
440  object_labels.markers[i].id = tmpId + iLoop * oa->objects.size(); // i; // oa->objects[i].id;
441  object_labels.markers[i].action = visualization_msgs::Marker::ADD;
442  object_labels.markers[i].color.a = 0.75;
443  object_labels.markers[i].color.r = GLASBEY_LUT[colorId * 3] / 255.0;
444  object_labels.markers[i].color.g = GLASBEY_LUT[colorId * 3 + 1] / 255.0;
445  object_labels.markers[i].color.b = GLASBEY_LUT[colorId * 3 + 2] / 255.0;
446  object_labels.markers[i].lifetime = ros::Duration(1.0);
447 
449  object_labels.markers[i].pose = oa->objects[i].object_box_center.pose;
450  object_labels.markers[i].scale.z = 1.0;
451 
452  {
453 
454  char szLabel[255];
455  sprintf(szLabel,"%5.1lf [m/s]", vabs );
456 
457  if (vabs > 10.0)
458  {
459  // printf("Dir: %8.3lf [deg]\n", vp_dir_deg);
460  }
461  std::string object_label_ns = "???";
462  if (vabs > 5.0) // 18 km/h
463  {
464  object_label_ns = "object_label_fast";
465  }
466  else
467  {
468  object_label_ns = "object_label_slow";
469 
470  }
471  object_labels.markers[i].text = szLabel;
472  object_labels.markers[i].ns = object_label_ns;
473 
474  if (vehicleIsInPredefinedDir[i] == false)
475  {
476  object_labels.markers[i].scale.z = 0.00;
477  }
478  }
479 
480 
481  }
482 
483  /* object box center is the reference ...
484  * */
485  object_boxes.markers[idx].pose = oa->objects[i].object_box_center.pose; // Position and Orientation
486  object_boxes.markers[idx].scale = oa->objects[i].object_box_size;
487 
488  switch (iLoop)
489  {
490  case 0: // Drawing object cubes
491  object_boxes.markers[idx].type = visualization_msgs::Marker::CUBE;
492  object_boxes.markers[idx].pose.position.z += oa->objects[i].object_box_size.z * 0.5;
493 
494 
495  break;
496  case 1:
497  object_boxes.markers[idx].type = visualization_msgs::Marker::ARROW;
498 
499  break;
500  }
501 
502  switch (iLoop)
503  {
504  case 0:
505  if (object_boxes.markers[idx].scale.x == 0.0)
506  {
507  object_boxes.markers[idx].scale.x = 0.01;
508  }
509  if (object_boxes.markers[idx].scale.y == 0.0)
510  {
511  object_boxes.markers[idx].scale.y = 0.01;
512  }
513  if (object_boxes.markers[idx].scale.z == 0.0)
514  {
515  object_boxes.markers[idx].scale.z = 0.01;
516  }
517 
518  if (vehicleIsInPredefinedDir[i] == false) {
519  object_boxes.markers[idx].scale.x = 0.0;
520  object_boxes.markers[idx].scale.y = 0.0;
521  object_boxes.markers[idx].scale.z = 0.0;
522  object_boxes.markers[idx].lifetime = ros::Duration(0.001);
523  } else{
524 
525 
526  if (vehicleIsInPredefinedDir[i] == true)
527  {
528  float theta = vehiclePredefinedDir[i];
529 
530 
531  // Falls wir eine Zwangsrichtung einpraegen wollen, dann muessen wir es am besten hier tun.
532 
533  // (n_x, n_y, n_z) = (0, 0, 1), so (x, y, z, w) = (0, 0, sin(theta/2), cos(theta/2)).
534  // see https://answers.ros.org/question/9772/quaternions-orientation-representation/
535  float theta2 = 0.5 * theta;
536  object_boxes.markers[idx].pose.orientation.z = sin(theta2);
537  object_boxes.markers[idx].pose.orientation.w = cos(theta2);
538 
539  }
540 
541 
542  }
543  break;
544  case 1:
545  {
546  float xTmp;
547  float yTmp;
548 
549  object_boxes.markers[idx].scale.x = 0.5;
550  object_boxes.markers[idx].scale.y = 0.5;
551  object_boxes.markers[idx].scale.z = 0.5;
552 
553 
554 
555 /* float cosVal = oa->objects[i].object_box_center.pose.orientation.x;
556  float sinVal = oa->objects[i].object_box_center.pose.orientation.y;
557 */
558  xTmp = oa->objects[i].object_box_center.pose.position.x;
559  yTmp = oa->objects[i].object_box_center.pose.position.y;
560 
561  double vehLen = oa->objects[i].object_box_size.x;
562 
563 
564  float quaternion[4] = {0};
565  // rotation around z-axis: [cos(theta/2.0), 0, 0, sin(theta/2.0) ]
566  quaternion[0] = oa->objects[i].object_box_center.pose.orientation.x;
567  quaternion[1] = oa->objects[i].object_box_center.pose.orientation.y;
568  quaternion[2] = oa->objects[i].object_box_center.pose.orientation.z;
569  quaternion[3] = oa->objects[i].object_box_center.pose.orientation.w;
570 
571 
572  // Falls wir eine Zwangsrichtung einpraegen wollen, dann muessen wir es am besten hier tun.
573 
574  // (n_x, n_y, n_z) = (0, 0, 1), so (x, y, z, w) = (0, 0, sin(theta/2), cos(theta/2)).
575  // see https://answers.ros.org/question/9772/quaternions-orientation-representation/
576  float theta2 = atan2(quaternion[2], quaternion[3]);
577  float theta = 2.0f * theta2;
578  if (vehicleIsInPredefinedDir[i] == true)
579  {
580  theta = vehiclePredefinedDir[i];
581  }
582 
583  float cosVal = cos(theta);
584  float sinVal = sin(theta);
585  xTmp += cosVal * vehLen * 0.5;
586  yTmp += sinVal * vehLen * 0.5;
587  object_boxes.markers[idx].pose.position.x = xTmp;
588  object_boxes.markers[idx].pose.position.y = yTmp;
589  object_boxes.markers[idx].pose.position.z = 0.0;
590 
591  // oa->objects[i].object_box_center.pose.orientation;
592  // Arrow orientation is already rotated
593  object_boxes.markers[idx].pose.orientation.x = 0.0;
594  object_boxes.markers[idx].pose.orientation.y = 0.0;
595  object_boxes.markers[idx].pose.orientation.z = 0.0;
596  object_boxes.markers[idx].pose.orientation.w = 0.0;
597 
598  object_boxes.markers[idx].points.resize(2);
599  object_boxes.markers[idx].points[0].x = 0.0;
600  object_boxes.markers[idx].points[0].y = 0.0;
601  object_boxes.markers[idx].points[0].z = 0.0;
602 
603  float absSpeed = 0.0;
604  for (int j = 0; j < 3; j++)
605  {
606  float speedPartial = 0.0;
607  switch(j)
608  {
609  case 0: speedPartial = oa->objects[i].velocity.twist.linear.x; break;
610  case 1: speedPartial = oa->objects[i].velocity.twist.linear.y; break;
611  case 2: speedPartial = oa->objects[i].velocity.twist.linear.z; break;
612  }
613  absSpeed += speedPartial * speedPartial;
614  }
615  absSpeed = sqrt(absSpeed);
616  double lengthOfArrow = objectArrowScale * absSpeed;
617  if (objectArrowScale < 0.0)
618  {
619  lengthOfArrow = -objectArrowScale; // if scale is negative take its absolute value as length of arrow in [m]
620  }
621  // lengthOfArrow = 5.0;
622 
623  if (vehicleIsInPredefinedDir[i] == false) {
624  object_boxes.markers[idx].lifetime = ros::Duration(0.001);
625  lengthOfArrow = 0.0;
626  }
627  object_boxes.markers[idx].points[1].x = 0.0 + lengthOfArrow * cosVal;
628  object_boxes.markers[idx].points[1].y = 0.0 + lengthOfArrow * sinVal;
629  object_boxes.markers[idx].points[1].z = 0.0;
630  // pub.publish(object_boxes);
631 
632  }
633  break;
634  }
635 
636  // printf("Idx: %2d X: %8.3lf Y: %8.3lf\n", idx, object_boxes.markers[idx].pose.position.x, object_boxes.markers[idx].pose.position.y);
637  }
638  }
639  pub.publish(object_boxes);
640  pub.publish(object_labels);
641 
642  }
643 
644 
645  int main(int argc, char **argv)
646  {
647  // checkForAngleIntervalTestbed();
648  ROS_INFO("radar_object_marker, compiled at [%s] [%s]", __DATE__, __TIME__);
649  RadarObjectMarkerCfg *cfgPtr = &boost::serialization::singleton<RadarObjectMarkerCfg>::get_mutable_instance();
650  ros::init(argc, argv, "radar_object_marker");
651  ros::NodeHandle nh;
652  ros::NodeHandle nhPriv("~");
653 
654  std::string heatMap;
655  double minAmpl = 10.0;
656  double maxAmpl = 90.0;
657  bool paramRes = nhPriv.getParam("rawtarget_sphere_radius", ballRadius);
658  paramRes = nhPriv.getParam("rawtarget_palette_name", heatMap);
659  paramRes = nhPriv.getParam("rawtarget_palette_min_ampl", minAmpl);
660  paramRes = nhPriv.getParam("rawtarget_palette_max_ampl", maxAmpl);
661 
662  paramRes = nhPriv.getParam("object_arrow_scale", objectArrowScale);
663 
664  cfgPtr->setPaletteName(heatMap);
665  cfgPtr->setPaletteMinAmpl(minAmpl);
666  cfgPtr->setPaletteMaxAmpl(maxAmpl);
667 
668 
669 
670  std::string path = ros::package::getPath("sick_scan");
671 
672  if (cfgPtr->getPaletteName().length() > 0)
673  {
674  std::string heatMapFileName = path + "/config/" + cfgPtr->getPaletteName();
675  pal.load(heatMapFileName);
676  usingPal = true;
677  cfgPtr->setGnuPlotPalette(pal);
678  cfgPtr->setPaletteUsed(true);
679  }
680  else
681  {
682  cfgPtr->setPaletteUsed(false);
683  }
684 
685  ROS_INFO("Subscribing to radar and pulishing to radar_markers");
686 
687  ros::Subscriber sub = nh.subscribe("radar", 1, callback);
688  pub = nh.advertise<visualization_msgs::MarkerArray>("radar_markers", 1);
689 
690  pub_cloud = nh.advertise<sensor_msgs::PointCloud2>("radar_cloud", 1);
691 
692  ros::spin();
693 
694  return 0;
695  }
std_msgs::Header_::stamp
_stamp_type stamp
Definition: Header.h:45
RadarObjectMarkerCfg
Definition: radar_object_marker.h:271
sensor_msgs::PointCloud2_::row_step
_row_step_type row_step
Definition: PointCloud2.h:74
RadarObjectMarkerCfg::getPaletteName
const std::string & getPaletteName() const
Definition: radar_object_marker.h:293
ros::Publisher
ros::package::getPath
ROSLIB_DECL std::string getPath(const std::string &package_name)
Returns the fully-qualified path to a package, or an empty string if the package is not found.
sensor_msgs::PointCloud2_::width
_width_type width
Definition: PointCloud2.h:62
radar_object_marker.h
angle
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
sensor_msgs::PointCloud2_::point_step
_point_step_type point_step
Definition: PointCloud2.h:71
ros::init
ROSCPP_DECL void init(const M_string &remappings, const std::string &name, uint32_t options=0)
alternate ROS initialization function.
RadarObjectMarkerCfg::getPaletteMinAmpl
double getPaletteMinAmpl() const
Definition: radar_object_marker.h:312
ros::NodeHandle::getParam
bool getParam(const std::string &key, bool &b) const
isWithinRange
bool isWithinRange(float testAngle, float a, float b)
Definition: radar_object_marker.cpp:85
GLASBEY_LUT
static const unsigned char GLASBEY_LUT[]
Definition: radar_object_marker.h:11
GnuPlotPalette
Definition: gnuplotPaletteReader.h:5
red
static ros_std_msgs::ColorRGBA red(void)
Definition: sick_scan_marker.cpp:79
RadarObjectMarkerCfg::setGnuPlotPalette
void setGnuPlotPalette(const GnuPlotPalette &gnuPlotPalette)
Definition: radar_object_marker.h:288
sensor_msgs::PointCloud2_::fields
_fields_type fields
Definition: PointCloud2.h:65
visualization_msgs::Marker_::ADD
@ ADD
Definition: Marker.h:181
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
sensor_msgs::PointCloud2_::height
_height_type height
Definition: PointCloud2.h:59
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
Definition: rossimu.cpp:350
GnuPlotPalette::load
int load(std::string palettName)
Definition: gnuplotPaletteReader.cpp:69
ballRadius
float ballRadius
Definition: radar_object_marker.cpp:68
normalize
void normalize(float &angle)
Definition: radar_object_marker.cpp:79
blue
static ros_std_msgs::ColorRGBA blue(void)
Definition: sick_scan_marker.cpp:89
main
int main(int argc, char **argv)
Definition: radar_object_marker.cpp:645
pal
GnuPlotPalette pal
Definition: radar_object_marker.cpp:70
sensor_msgs::PointCloud2_::data
_data_type data
Definition: PointCloud2.h:77
sick_scan_xd::RadarScan_::ConstPtr
std::shared_ptr< ::sick_scan_xd::RadarScan_< ContainerAllocator > const > ConstPtr
Definition: RadarScan.h:64
std_msgs::Duration
::std_msgs::Duration_< std::allocator< void > > Duration
Definition: Duration.h:48
visualization_msgs::MarkerArray_::markers
_markers_type markers
Definition: MarkerArray.h:39
checkForAngleInterval
bool checkForAngleInterval(float orgAngle, float *dstAngle, float mainAngle, float mainAngleTol)
Definition: radar_object_marker.cpp:99
checkForAngleIntervalTestbed
bool checkForAngleIntervalTestbed()
Definition: radar_object_marker.cpp:128
RadarObjectMarkerCfg::getPaletteMaxAmpl
double getPaletteMaxAmpl() const
Definition: radar_object_marker.h:302
objectArrowScale
float objectArrowScale
Definition: radar_object_marker.cpp:69
green
static ros_std_msgs::ColorRGBA green(void)
Definition: sick_scan_marker.cpp:84
RadarObjectMarkerCfg::setPaletteName
void setPaletteName(const std::string &paletteName)
Definition: radar_object_marker.h:298
sensor_msgs::PointCloud2_::is_bigendian
_is_bigendian_type is_bigendian
Definition: PointCloud2.h:68
RadarObjectMarkerCfg::setPaletteMaxAmpl
void setPaletteMaxAmpl(double paletteMaxAmpl)
Definition: radar_object_marker.h:307
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
ROS_INFO
#define ROS_INFO(...)
Definition: sick_scan_logging.h:117
RadarObjectMarkerCfg::setPaletteMinAmpl
void setPaletteMinAmpl(double paletteMinAmpl)
Definition: radar_object_marker.h:317
visualization_msgs::Marker_::TEXT_VIEW_FACING
@ TEXT_VIEW_FACING
Definition: Marker.h:178
sensor_msgs::PointCloud2_
Definition: PointCloud2.h:25
visualization_msgs::Marker_::ARROW
@ ARROW
Definition: Marker.h:169
RadarObjectMarkerCfg::isPaletteUsed
bool isPaletteUsed() const
Definition: radar_object_marker.h:273
visualization_msgs::MarkerArray_
Definition: MarkerArray.h:24
ros::Time
usingPal
bool usingPal
Definition: radar_object_marker.cpp:71
gnuplotPaletteReader.h
RadarObjectMarkerCfg::getGnuPlotPalette
const GnuPlotPalette & getGnuPlotPalette() const
Definition: radar_object_marker.h:283
sensor_msgs::PointCloud2_::header
_header_type header
Definition: PointCloud2.h:56
ros::spin
ROSCPP_DECL void spin()
Enter simple event loop.
Definition: rossimu.cpp:260
pub_cloud
ros::Publisher pub_cloud
Definition: radar_object_marker.cpp:74
GnuPlotPalette::getRbgValue
unsigned char getRbgValue(unsigned char greyIdx, unsigned int channelIdx)
Definition: gnuplotPaletteReader.cpp:184
visualization_msgs::Marker_::CUBE
@ CUBE
Definition: Marker.h:170
visualization_msgs::Marker_::SPHERE
@ SPHERE
Definition: Marker.h:171
pub
ros::Publisher pub
Definition: radar_object_marker.cpp:73
RadarObjectMarkerCfg::setPaletteUsed
void setPaletteUsed(bool paletteUsed)
Definition: radar_object_marker.h:278
ros::NodeHandle
sensor_msgs::PointCloud2_::is_dense
_is_dense_type is_dense
Definition: PointCloud2.h:80
ros::Subscriber
callback
void callback(const sick_scan_xd::RadarScan::ConstPtr &oa)
Definition: radar_object_marker.cpp:157
ros::Time::now
static Time now()
MarkerArray.h


sick_scan_xd
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Fri Oct 25 2024 02:47:10