00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00034 #ifndef _PUBLISH_MIT_LOGS_
00035 #define _PUBLISH_MIT_LOGS_
00036
00037 #include "publish_mit_logs.h"
00038 #include "rosbag/bag.h"
00039
00040 void signal_handler(int sig)
00041 {
00042 printf("%d %d %d\n",sig,SIGSEGV,SIGINT);
00043
00044 if(sig==SIGSEGV)
00045 {
00046
00047 signal(SIGSEGV, SIG_DFL);
00048
00049 ROS_WARN("System segfaulted");
00050
00051 ros::shutdown();
00052
00053 exit(0);
00054 }
00055 else if(sig==SIGINT)
00056 {
00057 ROS_WARN("Ctrl-c pressed");
00058
00059 ros::shutdown();
00060
00061 exit(0);
00062 }
00063 }
00064
00065
00066 void copy_pixels_to_image_msg_data(unsigned char *in, sensor_msgs::Image *image, int size) {
00067
00070
00074
00075
00076
00078
00079
00080 for(int i=0; i<240*376*3; i+=3)
00081
00082
00083 {
00084
00085
00086
00087
00088
00089
00090 image->data[i] = in[i+2];
00091 image->data[i+1] = in[i+1];
00092 image->data[i+2] = in[i];
00093
00094
00095 }
00096
00097 }
00098
00099 void set_fixed_fields_image_msg(sensor_msgs::Image* msg, int height, int width, char* encoding, int is_bigendian, char* frame_id)
00100 {
00101 msg->height = height;
00102 msg->width = width;
00103 msg->encoding = sensor_msgs::image_encodings::RGB8;
00104 msg->is_bigendian = 0;
00105 msg->step = width*3;
00106 msg->data.resize(width*height*3);
00107 msg->header.frame_id = frame_id;
00108 }
00109
00114
00115 int main(int argc, char **argv)
00116 {
00118 ros::init(argc, argv, "point_cloud_publisher");
00119
00120 ros::NodeHandle n;
00121 ros::Publisher cloud_pub = n.advertise<sensor_msgs::PointCloud2>("/cloud", 1);
00122 ros::Publisher filtered_cloud_pub = n.advertise<sensor_msgs::PointCloud2>("/filtered_cloud", 1);
00123 ros::Publisher pose_pub = n.advertise<geometry_msgs::PoseStamped >("/vehicle_pose", 1);
00124
00125 rosbag::Bag bag("test.bag", rosbag::bagmode::Write);
00126
00127
00128 image_transport::ImageTransport it(n);
00129 image_transport::Publisher pub_image_rfc = it.advertise("/cam_roof_fc", 1);
00130 image_transport::Publisher pub_image_rfl = it.advertise("/cam_roof_fl", 1);
00131 image_transport::Publisher pub_image_rfr = it.advertise("/cam_roof_fr", 1);
00132 image_transport::Publisher pub_image_rrc = it.advertise("/cam_roof_rc", 1);
00133 image_transport::Publisher pub_image_rfc_6mm = it.advertise("/cam_roof_fc_6mm", 1);
00134
00135 geometry_msgs::PoseStamped pose_msg;
00136
00137 sensor_msgs::Image image_rfc;
00138 set_fixed_fields_image_msg(&image_rfc, 240, 376,(char*)"RGB8", 0, (char*) "/tf_cam_roof_fc");
00139 sensor_msgs::Image image_rfl;
00140 set_fixed_fields_image_msg(&image_rfl, 240, 376,(char*)"RGB8", 0, (char*) "/tf_cam_roof_fl");
00141 sensor_msgs::Image image_rfr;
00142 set_fixed_fields_image_msg(&image_rfr, 240, 376,(char*)"RGB8", 0, (char*) "/tf_cam_roof_fr");
00143 sensor_msgs::Image image_rrc;
00144 set_fixed_fields_image_msg(&image_rrc, 240, 376,(char*)"RGB8", 0, (char*) "/tf_cam_roof_rc");
00145 sensor_msgs::Image image_rfc_6mm;
00146 set_fixed_fields_image_msg(&image_rrc, 240, 376,(char*)"RGB8", 0, (char*) "/tf_cam_roof_fc_6mm");
00147
00148 tf::TransformBroadcaster tf_br;
00149 tf::Transform tr;
00150
00151
00152 tf::TransformBroadcaster tf_br1;
00153 tf::Transform tr1;
00154 tr1.setOrigin( tf::Vector3(2.0, 0.10, 1.87));
00155 tf::Quaternion q1;
00156 q1.setRPY( M_PI/180.*-92.732548686299864, M_PI/180.* 1.5247112920413703, M_PI/180.* -88.947474213001513);
00157 tr1.setRotation(q1);
00158
00159
00160 tf::TransformBroadcaster tf_br2;
00161 tf::Transform tr2;
00162 tr2.setOrigin( tf::Vector3(1.70, 0.66, 1.83));
00163 tf::Quaternion q2;
00164 q2.setRPY( M_PI/180.*-104.85977729830938, M_PI/180.* 1.7669342713597069, M_PI/180.* -24.369926193961831);
00165 tr2.setRotation(q2);
00166
00167 tf::TransformBroadcaster tf_br3;
00168 tf::Transform tr3;
00169 tr3.setOrigin( tf::Vector3(1.60, -0.66, 1.83));
00170 tf::Quaternion q3;
00171 q3.setRPY( M_PI/180.*-104.67989704943309, M_PI/180.* -1.6346433362446215, M_PI/180.* -154.50843893511401);
00172 tr3.setRotation(q3);
00173
00174 tf::TransformBroadcaster tf_br4;
00175 tf::Transform tr4;
00176 tr4.setOrigin( tf::Vector3(-0.72, 0.58, 1.87));
00177 tf::Quaternion q4;
00178 q4.setRPY( M_PI/180.*-87.556890981409339, M_PI/180.* 0.20153392228877995, M_PI/180.* 90.018251146632338);
00179 tr4.setRotation(q4);
00180
00181 tf::TransformBroadcaster tf_br5;
00182 tf::Transform tr5;
00183 tr5.setOrigin( tf::Vector3(2.0, 0.10, 1.87));
00184 tf::Quaternion q5;
00185 q5.setRPY( M_PI/180.*-92.994985165680859, M_PI/180.* 1.8089691922136495, M_PI/180.* -89.480172060729586);
00186 tr5.setRotation(q5);
00187
00188 visualization_msgs::Marker car_marker;
00189 ros::Publisher car_marker_pub = n.advertise<visualization_msgs::Marker>("/car_resource", 1);
00190 car_marker.id = 1;
00191 car_marker.header.stamp = ros::Time::now();
00192 car_marker.type = visualization_msgs::Marker::MESH_RESOURCE;
00193 car_marker.action = visualization_msgs::Marker::ADD;
00194 car_marker.ns = "ns";
00195 car_marker.mesh_resource = "package://wrapper_collada/models/audi_q7_blender.dae";
00196 car_marker.mesh_use_embedded_materials = 1;
00197 car_marker.header.frame_id = "/world";
00198 car_marker.scale.x = 1;
00199 car_marker.scale.y = 1;
00200 car_marker.scale.z = 1;
00201 car_marker.color.r = 0.8;
00202 car_marker.color.g = 0.4;
00203 car_marker.color.b = 0.0;
00204 car_marker.color.a = 0.9;
00205
00206 ros::Rate r(0.1);
00207
00208
00209 pcl::PointCloud<pcl::PointXYZ> cloud;
00210 sensor_msgs::PointCloud2::Ptr cloud_msg(new sensor_msgs::PointCloud2 ());
00211 sensor_msgs::PointCloud2::Ptr cloud_msg_filtered(new sensor_msgs::PointCloud2 ());
00212 cloud.header.frame_id = "/world";
00213 cloud.height = 1;
00214 cloud.is_dense=0;
00215
00216 if(argc < 4)
00217 {
00218 fprintf(stderr,
00219 "usage: example4-velodyne <logfile> <start_time> <end time>\n"
00220 "\n"
00221 "start_time and end_time are given in seconds from the\n"
00222 "start of the log file\n");
00223 return 1;
00224 }
00225
00226 lcm_eventlog_t *log = lcm_eventlog_create(argv[1], "r");
00227 if(!log)
00228 {
00229 fprintf(stderr, "error opening log file\n");
00230 return 1;
00231 }
00232
00233 double start_time = strtod(argv[2], NULL);
00234 double end_time = strtod(argv[3], NULL);
00235
00236 Config *config = config_parse_default();
00237 if(!config) {
00238 fprintf(stderr, "couldn't find config file\n");
00239 return 1;
00240 }
00241
00242
00243 velodyne_calib_t *vcalib = velodyne_calib_create();
00244
00245
00246
00247
00248 lcm_eventlog_event_t *event = lcm_eventlog_read_next_event(log);
00249 int64_t first_timestamp = event->timestamp;
00250 lcmtypes_pose_t last_pose;
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 cloud.points.erase(cloud.points.begin(), cloud.points.end());
00266
00267
00268 printf("start_time=%f\n",start_time);
00269 printf("end_time=%f\n",end_time);
00270 ros::Time time_start = ros::Time::now();
00271
00272
00273 int64_t start_utime = first_timestamp + (int64_t)(start_time*1000000);
00274 int64_t end_utime = first_timestamp + (int64_t)(end_time *1000000);
00275
00276 double start_velodyne_acquisition=-1;
00277
00278 memset(&last_pose, 0, sizeof(last_pose));
00279
00280 while(n.ok())
00281 {
00282
00283 lcm_eventlog_free_event(event);
00284
00285
00286
00287 event = lcm_eventlog_read_next_event(log);
00288
00289 if(!event)
00290 break;
00291 else
00292 {
00293 printf("Event %s at time %3.2f\n",event->channel,((double)(event->timestamp-first_timestamp))/1000000.);
00294
00295
00296
00297 }
00298
00299
00300
00301 if(!strcmp(event->channel, "POSE")) {
00302 if(last_pose.utime)
00303 lcmtypes_pose_t_decode_cleanup(&last_pose);
00304
00305 lcmtypes_pose_t_decode(event->data, 0, event->datalen, &last_pose);
00306 }
00307
00308
00309 if(event->timestamp < start_utime) {
00310 continue;
00311 }
00312
00313
00314 if(event->timestamp >= end_utime) {
00315 break;
00316 }
00317
00318 ros::Time event_time = time_start + ros::Duration(((double)(event->timestamp-first_timestamp))/1000000.);
00319
00320 printf("ROS Event %s at time %3.2f\n",event->channel,event_time.toSec());
00321
00322 if(!strcmp(event->channel, "POSE"))
00323 {
00324 geometry_msgs::TransformStamped msg;
00325 std::vector< geometry_msgs::TransformStamped > vec_msg;
00326 tf::tfMessage tfmsg;
00327
00328 printf("Processing Event %s at time %3.2f\n",event->channel,((double)(event->timestamp-first_timestamp))/1000000.);
00329 pose_msg.header.frame_id = "/world";
00330 pose_msg.header.stamp = ros::Time::now();
00331 pose_msg.pose.position.x = last_pose.pos[0];
00332 pose_msg.pose.position.y = last_pose.pos[1];
00333 pose_msg.pose.position.z = last_pose.pos[2];
00334
00335 pose_msg.pose.orientation.x = last_pose.orientation[1];
00336 pose_msg.pose.orientation.y = last_pose.orientation[2];
00337 pose_msg.pose.orientation.z = last_pose.orientation[3];
00338 pose_msg.pose.orientation.w = last_pose.orientation[0];
00339
00340 tr.setOrigin( tf::Vector3(pose_msg.pose.position.x,
00341 pose_msg.pose.position.y,
00342 pose_msg.pose.position.z));
00343 tr.setRotation( tf::Quaternion( pose_msg.pose.orientation.x,
00344 pose_msg.pose.orientation.y,
00345 pose_msg.pose.orientation.z,
00346 pose_msg.pose.orientation.w
00347 ));
00348
00349 pose_pub.publish(pose_msg);
00350
00351
00352 car_marker.pose.position.x = pose_msg.pose.position.x;
00353 car_marker.pose.position.y = pose_msg.pose.position.y;
00354 car_marker.pose.position.z = pose_msg.pose.position.z;
00355 car_marker.pose.orientation.x = pose_msg.pose.orientation.x;
00356 car_marker.pose.orientation.y = pose_msg.pose.orientation.y;
00357 car_marker.pose.orientation.z = pose_msg.pose.orientation.z;
00358 car_marker.pose.orientation.w = pose_msg.pose.orientation.w;
00359 car_marker.header.stamp = event_time;
00360 car_marker_pub.publish(car_marker);
00361
00362 bag.write("/car_resource", event_time,car_marker);
00363
00364 tf_br.sendTransform(tf::StampedTransform(tr, ros::Time::now(), "/world","/tf_vehicle"));
00365 tf::transformStampedTFToMsg(tf::StampedTransform(tr, ros::Time::now(), "/world","/tf_vehicle"),msg);
00366 vec_msg.erase(vec_msg.begin(),vec_msg.end());
00367 vec_msg.push_back(msg);
00368
00369
00370
00371
00372 tf_br1.sendTransform(tf::StampedTransform(tr1, ros::Time::now(), "/tf_vehicle","/tf_cam_roof_fc"));
00373 tf::transformStampedTFToMsg(tf::StampedTransform(tr1, ros::Time::now(), "/tf_vehicle","/tf_cam_roof_fc"),msg);
00374
00375
00376 tfmsg.transforms.push_back(msg);
00377
00378
00379
00380
00381
00382 tf_br2.sendTransform(tf::StampedTransform(tr2, ros::Time::now(), "/tf_vehicle","/tf_cam_roof_fl"));
00383 tf::transformStampedTFToMsg(tf::StampedTransform(tr2, ros::Time::now(), "/tf_vehicle","/tf_cam_roof_fl"),msg);
00384
00385
00386 tfmsg.transforms.push_back(msg);
00387
00388
00389
00390
00391
00392 tf_br3.sendTransform(tf::StampedTransform(tr3, ros::Time::now(), "/tf_vehicle","/tf_cam_roof_fr"));
00393 tf::transformStampedTFToMsg(tf::StampedTransform(tr3, ros::Time::now(), "/tf_vehicle","/tf_cam_roof_fr"),msg);
00394
00395
00396 tfmsg.transforms.push_back(msg);
00397
00398
00399
00400
00401
00402 tf_br4.sendTransform(tf::StampedTransform(tr4, ros::Time::now(), "/tf_vehicle","/tf_cam_roof_rc"));
00403 tf::transformStampedTFToMsg(tf::StampedTransform(tr4, ros::Time::now(), "/tf_vehicle","/tf_cam_roof_rc"),msg);
00404
00405
00406 tfmsg.transforms.push_back(msg);
00407
00408
00409
00410
00411
00412 tf_br5.sendTransform(tf::StampedTransform(tr5, ros::Time::now(), "/tf_vehicle","/tf_cam_roof_fc_6mm"));
00413 tf::transformStampedTFToMsg(tf::StampedTransform(tr5, ros::Time::now(), "/tf_vehicle","/tf_cam_roof_fc_6mm"),msg);
00414
00415
00416 tfmsg.transforms.push_back(msg);
00417
00418
00419 bag.write("/tf", event_time,tfmsg);
00420
00421 }
00422
00423
00424 if(!strcmp(event->channel, "VELODYNE"))
00425 {
00426
00427
00428 if(start_velodyne_acquisition ==-1)
00429 {
00430 start_velodyne_acquisition = (double)(first_timestamp + event->timestamp)/1000000.;
00431
00432 }
00433
00434 if (((double)(first_timestamp+event->timestamp)/1000000. - start_velodyne_acquisition)>1)
00435 {
00436
00437 printf("Processing Event %s at time %3.2f\n",event->channel,((double)(event->timestamp-first_timestamp))/1000000.);
00438
00439
00440 ROS_ERROR("Cloud timestamp not set, problem during migration lar3 to lar4");
00441 pcl::toROSMsg(cloud, *cloud_msg);
00442
00443
00444
00445 ROS_ERROR("Voxel grid REMOVED, not working in ros::hydro, please remake, problem during migration lar3 to lar4");
00446
00447
00448
00449
00450
00451
00452
00453
00454 filtered_cloud_pub.publish(cloud_msg_filtered);
00455 bag.write("/filtered_cloud", event_time, cloud_msg_filtered);
00456
00457 cloud.points.erase(cloud.points.begin(), cloud.points.end());
00458
00459 start_velodyne_acquisition = (double)(first_timestamp + event->timestamp)/1000000.;
00460 }
00461
00462
00463 lcmtypes_velodyne_t vel;
00464 lcmtypes_velodyne_t_decode(event->data, 0, event->datalen,
00465 &vel);
00466
00467
00468
00469
00470
00471
00472 double velodyne_to_local[16];
00473 config_util_sensor_to_local_with_pose (config, "VELODYNE",
00474 velodyne_to_local, &last_pose);
00475
00476
00477 velodyne_decoder_t vdecoder;
00478 velodyne_decoder_init(vcalib, &vdecoder, vel.data, vel.datalen);
00479
00480
00481
00482 velodyne_sample_t vsample;
00483
00484 while (!velodyne_decoder_next(vcalib, &vdecoder, &vsample))
00485 {
00486 if (vsample.range < 3 || vsample.range>50)
00487 {
00488 continue;
00489 }
00490
00491 double sensor_xyz[4] = {vsample.xyz[0], vsample.xyz[1], vsample.xyz[2], 1 };
00492 double local_xyz[4];
00493
00494 matrix_vector_multiply_4x4_4d(velodyne_to_local, sensor_xyz, local_xyz);
00495
00496 pcl::PointXYZ Pt;
00497 Pt.x = local_xyz[0];
00498 Pt.y = local_xyz[1];
00499 Pt.z = local_xyz[2];
00500
00501
00502
00503
00504 cloud.push_back(Pt);
00505 }
00506
00507 cloud.width = cloud.size();
00508
00509
00510
00511 lcmtypes_velodyne_t_decode_cleanup(&vel);
00512 }
00513
00514 if(!strcmp(event->channel, "CAM_THUMB_RFC"))
00515 {
00516
00517 printf("Processing Event %s at time %3.2f\n",event->channel,((double)(event->timestamp-first_timestamp))/1000000.);
00518
00519 ROS_INFO("EVENT CAM_THUMB_RFC");
00520 lcmtypes_image_t img;
00521 lcmtypes_image_t_decode(event->data, 0, event->datalen, &img);
00522
00523
00524 char fname[80];
00525 sprintf(fname, "cam.jpg");
00526 FILE *fp = fopen(fname, "wb");
00527 int status = fwrite(img.image, img.size, 1, fp);
00528 if(status != 1) {
00529 perror("fwrite");
00530 return 1;
00531 }
00532 fclose(fp);
00533
00534
00535
00536 cv_bridge::CvImage out_msg;
00537 out_msg.header.stamp = ros::Time::now();
00538 out_msg.header.frame_id = "/tf_cam_roof_fc";
00539 out_msg.encoding = sensor_msgs::image_encodings::TYPE_8UC3;
00540 out_msg.image = cv::imread(fname,1);
00541 out_msg.toImageMsg(image_rfc);
00542
00543 pub_image_rfc.publish(image_rfc);
00544 bag.write("/cam_roof_fc", event_time, image_rfc);
00545
00546
00547 lcmtypes_image_t_decode_cleanup(&img);
00548 }
00549
00550 if(!strcmp(event->channel, "CAM_THUMB_RFL"))
00551 {
00552 printf("Processing Event %s at time %3.2f\n",event->channel,((double)(event->timestamp-first_timestamp))/1000000.);
00553 lcmtypes_image_t img;
00554 lcmtypes_image_t_decode(event->data, 0, event->datalen, &img);
00555
00556
00557 char fname[80];
00558 sprintf(fname, "cam.jpg");
00559 FILE *fp = fopen(fname, "wb");
00560 int status = fwrite(img.image, img.size, 1, fp);
00561 if(status != 1) {
00562 perror("fwrite");
00563 return 1;
00564 }
00565 fclose(fp);
00566
00567
00568 cv_bridge::CvImage out_msg;
00569 out_msg.header.stamp = ros::Time::now();
00570 out_msg.header.frame_id = "/tf_cam_roof_fl";
00571 out_msg.encoding = sensor_msgs::image_encodings::TYPE_8UC3;
00572 out_msg.image = cv::imread(fname,1);
00573
00574 out_msg.toImageMsg(image_rfl);
00575
00576 pub_image_rfl.publish(image_rfl);
00577 bag.write("/cam_roof_fl", event_time, image_rfl);
00578
00579
00580 lcmtypes_image_t_decode_cleanup(&img);
00581 }
00582
00583 if(!strcmp(event->channel, "CAM_THUMB_RFR"))
00584 {
00585 printf("Processing Event %s at time %3.2f\n",event->channel,((double)(event->timestamp-first_timestamp))/1000000.);
00586 lcmtypes_image_t img;
00587 lcmtypes_image_t_decode(event->data, 0, event->datalen, &img);
00588
00589
00590 char fname[80];
00591 sprintf(fname, "cam.jpg");
00592 FILE *fp = fopen(fname, "wb");
00593 int status = fwrite(img.image, img.size, 1, fp);
00594 if(status != 1) {
00595 perror("fwrite");
00596 return 1;
00597 }
00598 fclose(fp);
00599
00600
00601
00602 cv_bridge::CvImage out_msg;
00603 out_msg.header.stamp = ros::Time::now();
00604 out_msg.header.frame_id = "/tf_cam_roof_fr";
00605 out_msg.encoding = sensor_msgs::image_encodings::TYPE_8UC3;
00606 out_msg.image = cv::imread(fname,1);
00607 out_msg.toImageMsg(image_rfr);
00608
00609 pub_image_rfr.publish(image_rfr);
00610 bag.write("/cam_roof_fr", event_time, image_rfr);
00611
00612
00613 lcmtypes_image_t_decode_cleanup(&img);
00614
00615 }
00616
00617 if(!strcmp(event->channel, "CAM_THUMB_RRC"))
00618 {
00619 printf("Processing Event %s at time %3.2f\n",event->channel,((double)(event->timestamp-first_timestamp))/1000000.);
00620 lcmtypes_image_t img;
00621 lcmtypes_image_t_decode(event->data, 0, event->datalen, &img);
00622
00623
00624 char fname[80];
00625 sprintf(fname, "cam.jpg");
00626 FILE *fp = fopen(fname, "wb");
00627 int status = fwrite(img.image, img.size, 1, fp);
00628 if(status != 1) {
00629 perror("fwrite");
00630 return 1;
00631 }
00632 fclose(fp);
00633
00634
00635
00636 cv_bridge::CvImage out_msg;
00637 out_msg.header.stamp = ros::Time::now();
00638 out_msg.header.frame_id = "/tf_cam_roof_rc";
00639 out_msg.encoding = sensor_msgs::image_encodings::TYPE_8UC3;
00640 out_msg.image = cv::imread(fname,1);
00641 out_msg.toImageMsg(image_rrc);
00642
00643 pub_image_rrc.publish(image_rrc);
00644 bag.write("/cam_roof_rc", event_time, image_rrc);
00645
00646
00647 lcmtypes_image_t_decode_cleanup(&img);
00648 }
00649
00650 if(!strcmp(event->channel, "CAM_THUMB_RFC_6mm"))
00651 {
00652 printf("Processing Event %s at time %3.2f\n",event->channel,((double)(event->timestamp-first_timestamp))/1000000.);
00653 lcmtypes_image_t img;
00654 lcmtypes_image_t_decode(event->data, 0, event->datalen, &img);
00655
00656
00657 char fname[80];
00658 sprintf(fname, "cam.jpg");
00659 FILE *fp = fopen(fname, "wb");
00660 int status = fwrite(img.image, img.size, 1, fp);
00661 if(status != 1) {
00662 perror("fwrite");
00663 return 1;
00664 }
00665 fclose(fp);
00666
00667
00668
00669 cv_bridge::CvImage out_msg;
00670 out_msg.header.stamp = ros::Time::now();
00671 out_msg.header.frame_id = "/tf_cam_roof_fc_6mm";
00672 out_msg.encoding = sensor_msgs::image_encodings::TYPE_8UC3;
00673 out_msg.image = cv::imread(fname,1);
00674 out_msg.toImageMsg(image_rfc_6mm);
00675
00676 pub_image_rfc_6mm.publish(image_rfc_6mm);
00677 bag.write("/cam_roof_fc_6mm", event_time, image_rfc_6mm);
00678
00679
00680 lcmtypes_image_t_decode_cleanup(&img);
00681 }
00682
00683
00684
00685 ros::spinOnce();
00686 }
00687
00688
00689
00690
00691 bag.close();
00692
00693 lcm_eventlog_free_event(event);
00694 lcm_eventlog_destroy(log);
00695 return 0;
00696 }
00697
00698 #endif
00699