src/tracker_impl.cc
Go to the documentation of this file.
1 
18 /* system includes */
19 #include <unistd.h>
20 #include <stdio.h>
21 #include <sys/time.h>
22 #include <sstream>
23 #include <vector>
24 #include <algorithm>
25 
26 #include "bird_track_impl.h"
27 #include "tracker_impl.h"
28 #include "transform_coords.h"
29 
30 #define DOUBLE_VECTOR_LENGTH 6
31 
32 #define NOTE_KEY_1 "X"
33 #define NOTE_KEY_2 "Y"
34 #define NOTE_KEY_3 "Z"
35 #define NOTE_KEY_4 "RX"
36 #define NOTE_KEY_5 "RY"
37 #define NOTE_KEY_6 "RZ"
38 
39 extern unsigned int debugLevel;
40 typedef boost::array< ::geometry_msgs::Point_<std::allocator<void> > , 8> BoundingBox;
41 tracker_impl::tracker_impl(trackerID t, BirdTrack_impl* b, std::string trackerName) : myID(t), myBird(b), seqId(0)
42 {
44  threadRunning = false;
45  myTransformer = new transformCoords();
46  generalPublisher = node.advertise<asr_msgs::AsrObject>("fob_objects", 1000);
47 }
48 
50  threadRunning = false;
51 
52  // clearing ros interface
53 }
54 
55 
56 void
58 {
59  tracker_impl* myobj = (tracker_impl*)arg;
60  printf("static WorkerThread method called!\n");
61 
62  myobj->workerThread();
63  printf( "Worker thread exit.\n");
64  return NULL;
65 }
66 
67 
68 
69 #define MAX_SETS 1
70 #define PAUSE_SET 30000
71 #define PAUSE_WRITE 30000
72 
73 double getMedian(double (&vAcc)[MAX_SETS][6], unsigned int index){
74  if (MAX_SETS == 1)
75  return vAcc[0][index];
76 
77  std::vector<double> data;
78  for (unsigned int i=0; i<MAX_SETS; i++)
79  data.push_back(vAcc[i][index]);
80  std::sort(data.begin(), data.end());
81 
82  if (MAX_SETS % 2 == 0)
83  return ((data[MAX_SETS / 2 - 1] + data[MAX_SETS / 2]) / 2);
84  else
85  return data[(MAX_SETS - 1) / 2];
86 }
87 
88 
89 void
91 
92  double v[6];
93  double vAcc[MAX_SETS][6];
94 
95  while(threadRunning)
96  {
98  for (unsigned int i=0; i<MAX_SETS; i++)
99  {
101  myBird->get_posangles(myID, vAcc[i]);
102 
103  if (i+1 < MAX_SETS)
104  usleep(PAUSE_SET);
105  }
106 
107  for (unsigned int i=0; i<6; i++)
108  {
109  v[i] = getMedian(vAcc, i);
110  }
111 
112  //apply calibration
114 
115  //post calibrated data for regular usage
116  if (!this->writeNotification(myID, vAcc[0], v)){
117  printf( "Couldn't write Notification to NotificationManager. Error!\n");
118  exit(-1);
119  }
120 
121  if (debugLevel > 0 )
122  {
123  if (myID == rightTracker)
124  printf("\n");
125  }
126 
127  usleep(PAUSE_WRITE);
128  }
129  threadRunning = false;
130 }
131 
132 void
134  printf( "Starting myBird\n");
135  myBird->start();
136 
138  if(!threadRunning){
139  threadRunning = true;
140  pthread_create(&workerThreadHandle,NULL, &s_workerThread, (void*)this);
141  }
142  else
143  printf( "Thread started, but was already running.\n");
144  printf( "Thread running.\n");
145 }
146 
147 void
149  printf( "Stopping myBird\n");
150  myBird->stop();
151 
153  threadRunning = false;
154 }
155 
156 
157 bool
158 tracker_impl::loadCalibFile(const char *srcFileName)
159 {
160  //original: return myTransformer->loadCalibFile(srcFileName);
161  //original: myTransformer->loadCalibFile: no implemented
162  //this code taken from trackerCalibration
163  bool res;
164  std::string filename;
165  std::stringstream s;
166 
167  int fcountLeft, fcountRight;
168  fulcrum fulcrumarrayLeft[255], fulcrumarrayRight[255];
169  FILE *f;
170  res = ((f=fopen(srcFileName, "r"))!=NULL);
171  std::size_t readSize = 0;
172  if (res)
173  {
174  readSize = fread(&fcountLeft, sizeof(fcountLeft),1,f);
175  readSize = fread(&fcountRight, sizeof(fcountRight),1,f);
176 
177  if (debugLevel > 0) {
178  printf("loadCalibFile %s\n",srcFileName);
179  printf("fcountLeft:%i, fcountRight:%i\n",fcountLeft,fcountRight);
180  }
181  readSize = fread(&fulcrumarrayLeft,sizeof(fulcrumarrayLeft[0]),fcountLeft,f);
182  readSize = fread(&fulcrumarrayRight,sizeof(fulcrumarrayRight[0]),fcountRight,f);
183 
184  if (debugLevel > 1) {
185  printf("fulcrumyArrayLeft(%i):\n",fcountLeft);
186  for(int i=0;i < fcountLeft;i++) {
187  printf("\nentry %i:\n",i);
188  printFulcrum(fulcrumarrayLeft[i]);
189  }
190  printf("fulcrumyArrayRight(%i):\n",fcountRight);
191  for(int i=0;i < fcountRight;i++) {
192  printf("\nentry %i:\n",i);
193  printFulcrum(fulcrumarrayRight[i]);
194  }
195  }
196 //loading from file works. storage in array works
197  s << "Loaded " << (fcountLeft+fcountRight) << " fulcrums\n";
198  fclose(f);
199  }
200  else {
201  printf("error loading calibration data: 2%s:%u\n",__FILE__,__LINE__);
202  return false;
203  }
204 
205  if (myID == rightTracker) {
206  if (debugLevel > 0)
207  printf("loading Calibration into rightTracker\n");
208  res = loadCalibration(fulcrumarrayRight, fcountRight);
209  } else {
210  if (debugLevel > 0)
211  printf("loading Calibration into leftTracker\n");
212  res = loadCalibration(fulcrumarrayLeft, fcountLeft);
213  }
214  if(res)
215  printf("Success! Calibration data loaded\n");
216  else
217  printf("error loading calibration data: %s:%u\n",__FILE__,__LINE__);
218 
219  return res;
220 }
221 
222 
223 void tracker_impl::printFulcrum(fulcrum fulc) {
224  printf("sensorVal: %3.3f, %3.3f, %3.3f\n",fulc.sensorVal[0] ,fulc.sensorVal[1], fulc.sensorVal[2]);
225  printf("sensorAngle: %3.3f, %3.3f, %3.3f\n",fulc.sensorAngle[0] ,fulc.sensorAngle[1], fulc.sensorAngle[2]);
226  printf("worldVal: %3.3f, %3.3f, %3.3f\n",fulc.worldVal[0] ,fulc.worldVal[1], fulc.worldVal[2]);
227  printf("worldAngle: %3.3f, %3.3f, %3.3f\n",fulc.worldAngle[0] ,fulc.worldAngle[1], fulc.worldAngle[2]);
228  }
229 
230 bool
231 tracker_impl::loadCalibration(const fulcrum cal[255], unsigned int length)
232 {
233  double world[6],sensor[6];
235  for (unsigned int i=0; i < length; i++)
236  {
237  for (int j=0;j<3;j++)
238  {
239  sensor[j]=cal[i].sensorVal[j];
240  sensor[j+3]=cal[i].sensorAngle[j];
241  world[j]=cal[i].worldVal[j];
242  world[j+3]=cal[i].worldAngle[j];
243  }
244  myTransformer->addCalibrationData(sensor,world);
245  }
246  return myTransformer->isCalibrated();
247 }
248 
249 void tracker_impl::getPbdObject(std::string name, double *data, asr_msgs::AsrObject &object)
250 {
251 
252  // header
253  object.header.frame_id = "";
254  object.header.seq = seqId;
255  object.header.stamp = ros::Time::now();
256 
257  //Identification of tracker results.
258  object.providedBy = "asr_flock_of_birds";
259 
260 
261  // Object location distribution
262  geometry_msgs::Pose help_pose;
263  help_pose.position.x = data[0] / 1000.0;
264  help_pose.position.y = data[1] / 1000.0;
265  help_pose.position.z = data[2] / 1000.0;
266 
267  tf::Quaternion orientation = tf::createQuaternionFromRPY(data[5] * M_PI/180.0, data[4] * M_PI/180.0, data[3] * M_PI/180.0);
268  help_pose.orientation.x = orientation.x();
269  help_pose.orientation.y = orientation.y();
270  help_pose.orientation.z = orientation.z();
271  help_pose.orientation.w = orientation.w();
272 
273  geometry_msgs::PoseWithCovariance help_pose_with_c;
274  help_pose_with_c.pose = help_pose;
275  if (object.sampledPoses.size() > 0)
276  {
277  object.sampledPoses.pop_back();
278  }
279  object.sampledPoses.push_back(help_pose_with_c);
280 
281  // bounding box collapses to 1 point
282  for (unsigned int i=0; i<8; i++)
283  object.boundingBox[i] = help_pose.position;
284  object.sizeConfidence = 1.0;
285 
286  //Some misc information
287  object.type = "tracker";
288  object.typeConfidence = 1.0;
289 
290  object.identifier = name;
291 
292  object.meshResourcePath = "";
293 
294 }
295 
297 {
298  transform.setOrigin( tf::Vector3(data[0] / 1000.0, data[1] / 1000.0, data[2] / 1000.0) );
299  transform.setRotation( tf::createQuaternionFromRPY(data[5] * M_PI/180.0, data[4] * M_PI/180.0, data[3] * M_PI/180.0));
300 }
301 
302 bool
304 {
305  // input is X Y Z RZ RY RX
306  // output X Y Z RX RY RZ
307 
308  // create ROS msg
309  std::string name = id == leftTracker ? "tracker_left" : "tracker_right";
310 
311  if (debugLevel > 2 )
312  printf( "%s_raw %3.3f %3.3f %3.3f %3.3f° %3.3f° %3.3f° ", name.c_str(),
313  raw[0], raw[1], raw[2], raw[3], raw[4], raw[5]);
314  if (debugLevel > 0 )
315  printf( "%s %3.3f %3.3f %3.3f %3.3f° %3.3f° %3.3f° ", name.c_str(),
316  calibrated[0], calibrated[1], calibrated[2], calibrated[3], calibrated[4], calibrated[5]);
317 
318 
319  // write calibrated data to ROS
320  tf::Transform transform;
321  asr_msgs::AsrObject object;
322 
323  // as AsrObject
324  getPbdObject(name, calibrated, object);
325  generalPublisher.publish(object);
326 
327  // as TF frame
328  getTransform(calibrated, transform);
329  transformPublisher.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "tracker_base", name));
330 
331  // write calibratedraw data to ROS
332  name += "_raw";
333  getPbdObject(name, raw, object);
334  generalPublisher.publish(object);
335 
336  getTransform(raw, transform);
338 
339  this->seqId++;
340  return true;
341 }
342 
343 
344 
345 
346 
347 #if tracker_impl_test
348 int main(int argc, char **argv)
349 {
350  bgcorba::init(argc, argv);
351 
352  // Create a new instance of the implementation
353  tracker_impl *impl = new tracker_impl;
354 
355  int retval = bgcorba::main(impl);
356 
357  delete impl;
358 
359  return retval;
360 }
361 #endif /* tracker_impl_test */
362 
static tf::Quaternion createQuaternionFromRPY(double roll, double pitch, double yaw)
TFSIMD_FORCE_INLINE void setRotation(const Quaternion &q)
filename
void getPbdObject(std::string name, double *data, asr_msgs::AsrObject &object)
#define PAUSE_SET
void publish(const boost::shared_ptr< M > &message) const
f
int main(int argc, char **argv)
XmlRpcServer s
bool threadRunning
flag switching on/off thread
double getMedian(double(&vAcc)[MAX_SETS][6], unsigned int index)
void getTransform(double *data, tf::Transform &transform)
void workerThread()
this method is called by static method s_workerthread
static void * s_workerThread(void *arg)
Thread is bound to this method.
#define PAUSE_WRITE
unsigned int debugLevel
bool loadCalibration(const fulcrum cal[255], unsigned int length)
#define MAX_SETS
tf::TransformBroadcaster transformPublisher
bool loadCalibFile(const char *srcFileName)
tracker_impl(trackerID t, BirdTrack_impl *b, std::string trackerName)
void sendTransform(const StampedTransform &transform)
bool addCalibrationData(double *fobCoords, double *worldCoords)
unsigned int seqId
pthread_t workerThreadHandle
Thread for delivering tracker data to nCenter.
bool writeNotification(trackerID id, double *raw, double *calibrated)
boost::array< ::geometry_msgs::Point_< std::allocator< void > >, 8 > BoundingBox
void transform(double *v)
BirdTrack_impl * myBird
int get_posangles(int whichtracker, double *v)
ros::Publisher generalPublisher
static Time now()
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
bool calibrated
TFSIMD_FORCE_INLINE void setOrigin(const Vector3 &origin)
transformCoords * myTransformer


asr_flock_of_birds
Author(s): Bernhardt Andre, Engelmann Stephan, Giesler Björn, Heller Florian, Jäkel Rainer, Nguyen Trung, Pardowitz Michael, Weckesser Peter, Yi Xie, Zöllner Raoul
autogenerated on Mon Jun 10 2019 12:44:40