00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <uwsim/ROSInterface.h>
00014 #include <uwsim/UWSimUtils.h>
00015 #include <osg/LineWidth>
00016 #include <osg/Material>
00017 #include <osgOcean/ShaderManager>
00018 #include <uwsim/osgPCDLoader.h>
00019
00020 #include <sensor_msgs/Imu.h>
00021 #include <sensor_msgs/NavSatFix.h>
00022 #include <sensor_msgs/LaserScan.h>
00023 #include <underwater_sensor_msgs/Pressure.h>
00024 #include <underwater_sensor_msgs/DVL.h>
00025 #include <std_msgs/Bool.h>
00026 #include <osg/LineStipple>
00027 #include <robot_state_publisher/robot_state_publisher.h>
00028 #include <kdl_parser/kdl_parser.hpp>
00029
00030
00031 ros::Time ROSInterface::current_time_;
00032
00033 ROSSubscriberInterface::ROSSubscriberInterface(std::string topic) :
00034 ROSInterface(topic)
00035 {
00036 startThread();
00037 }
00038
00039
00040 void ROSSubscriberInterface::run()
00041 {
00042 ros::Duration(2).sleep();
00043 createSubscriber (nh_);
00044 }
00045
00046 ROSSubscriberInterface::~ROSSubscriberInterface()
00047 {
00048 join();
00049 }
00050
00051 ROSOdomToPAT::ROSOdomToPAT(osg::Group *rootNode, std::string topic, std::string vehicleName) :
00052 ROSSubscriberInterface(topic)
00053 {
00054 findNodeVisitor findNode(vehicleName);
00055 rootNode->accept(findNode);
00056 osg::Node *first = findNode.getFirst();
00057 if (first == NULL)
00058 {
00059 transform = NULL;
00060 }
00061 else
00062 {
00063 transform = dynamic_cast<osg::MatrixTransform*>(first);
00064 }
00065 started = 0;
00066 }
00067
00068 void ROSOdomToPAT::createSubscriber(ros::NodeHandle &nh)
00069 {
00070 ROS_INFO("ROSOdomToPAT subscriber on topic %s", topic.c_str());
00071 sub_ = nh.subscribe < nav_msgs::Odometry > (topic, 10, &ROSOdomToPAT::processData, this);
00072 if (sub_ == ros::Subscriber())
00073 {
00074 ROS_ERROR("ROSOdomToPAT::createSubscriber cannot subscribe to topic %s", topic.c_str());
00075 }
00076 }
00077
00078 void ROSOdomToPAT::processData(const nav_msgs::Odometry::ConstPtr& odom)
00079 {
00080 if (transform != NULL)
00081 {
00082
00083 osg::Matrixd sMsv_osg;
00084
00085
00086 if (odom->pose.pose.orientation.x != 0 || odom->pose.pose.orientation.y != 0 || odom->pose.pose.orientation.z != 0
00087 || odom->pose.pose.position.x != 0 || odom->pose.pose.position.y != 0 || odom->pose.pose.position.z != 0)
00088 {
00089 sMsv_osg.setTrans(odom->pose.pose.position.x, odom->pose.pose.position.y, odom->pose.pose.position.z);
00090 sMsv_osg.setRotate(
00091 osg::Quat(odom->pose.pose.orientation.x, odom->pose.pose.orientation.y, odom->pose.pose.orientation.z,
00092 odom->pose.pose.orientation.w));
00093 sMsv_osg.preMultScale(transform->getMatrix().getScale());
00094 }
00095 else
00096 {
00097
00098 sMsv_osg = transform->getMatrix();
00099
00100
00101 double elapsed = 0;
00102 if (started != 0)
00103 {
00104 ros::WallDuration t_diff = ros::WallTime::now() - last;
00105 elapsed = t_diff.toSec();
00106
00107 if (elapsed > 1)
00108 elapsed = 0;
00109 }
00110 started = 1;
00111 last = ros::WallTime::now();
00112
00113
00114 osg::Matrixd vMnv;
00115 osg::Matrixd T, Rx, Ry, Rz;
00116 T.makeTranslate(odom->twist.twist.linear.x * elapsed, odom->twist.twist.linear.y * elapsed,
00117 odom->twist.twist.linear.z * elapsed);
00118 Rx.makeRotate(odom->twist.twist.angular.x * elapsed, 1, 0, 0);
00119 Ry.makeRotate(odom->twist.twist.angular.y * elapsed, 0, 1, 0);
00120 Rz.makeRotate(odom->twist.twist.angular.z * elapsed, 0, 0, 1);
00121 vMnv = Rz * Ry * Rx * T;
00122
00123 sMsv_osg = vMnv * sMsv_osg;
00124 }
00125 transform->setMatrix(sMsv_osg);
00126 }
00127 }
00128
00129 ROSOdomToPAT::~ROSOdomToPAT()
00130 {
00131 }
00132
00133 ROSTwistToPAT::ROSTwistToPAT(osg::Group *rootNode, std::string topic, std::string vehicleName) :
00134 ROSSubscriberInterface(topic)
00135 {
00136 findNodeVisitor findNode(vehicleName);
00137 rootNode->accept(findNode);
00138 osg::Node *first = findNode.getFirst();
00139 if (first == NULL)
00140 {
00141 transform = NULL;
00142 }
00143 else
00144 {
00145 transform = dynamic_cast<osg::MatrixTransform*>(first);
00146 }
00147 started = 0;
00148 }
00149
00150 void ROSTwistToPAT::createSubscriber(ros::NodeHandle &nh)
00151 {
00152 ROS_INFO("ROSTwistToPAT subscriber on topic %s", topic.c_str());
00153 sub_ = nh.subscribe < geometry_msgs::TwistStamped > (topic, 10, &ROSTwistToPAT::processData, this);
00154 }
00155
00156 void ROSTwistToPAT::processData(const geometry_msgs::TwistStamped::ConstPtr& twist)
00157 {
00158 if (transform != NULL)
00159 {
00160
00161 osg::Matrixd sMsv_osg;
00162
00163 sMsv_osg = transform->getMatrix();
00164
00165
00166 double elapsed = 0;
00167 if (started != 0)
00168 {
00169 ros::WallDuration t_diff = ros::WallTime::now() - last;
00170 elapsed = t_diff.toSec();
00171
00172 if (elapsed > 1)
00173 elapsed = 0;
00174 }
00175 started = 1;
00176 last = ros::WallTime::now();
00177
00178 osg::Matrixd vMnv;
00179 osg::Matrixd T, Rx, Ry, Rz;
00180 T.makeTranslate(twist->twist.linear.x * elapsed, twist->twist.linear.y * elapsed, twist->twist.linear.z * elapsed);
00181 Rx.makeRotate(twist->twist.angular.x * elapsed, 1, 0, 0);
00182 Ry.makeRotate(twist->twist.angular.y * elapsed, 0, 1, 0);
00183 Rz.makeRotate(twist->twist.angular.z * elapsed, 0, 0, 1);
00184 vMnv = Rz * Ry * Rx * T;
00185
00186 sMsv_osg = vMnv * sMsv_osg;
00187
00188 transform->setMatrix(sMsv_osg);
00189 }
00190 }
00191
00192 ROSTwistToPAT::~ROSTwistToPAT()
00193 {
00194 }
00195
00196 ROSPoseToPAT::ROSPoseToPAT(osg::Group *rootNode, std::string topic, std::string vehicleName) :
00197 ROSSubscriberInterface(topic)
00198 {
00199 findNodeVisitor findNode(vehicleName);
00200 rootNode->accept(findNode);
00201 osg::Node *first = findNode.getFirst();
00202 if (first == NULL)
00203 {
00204 transform = NULL;
00205 }
00206 else
00207 {
00208 transform = dynamic_cast<osg::MatrixTransform*>(first);
00209 }
00210 }
00211
00212 void ROSPoseToPAT::createSubscriber(ros::NodeHandle &nh)
00213 {
00214 ROS_INFO("ROSPoseToPAT subscriber on topic %s", topic.c_str());
00215 sub_ = nh.subscribe < geometry_msgs::Pose > (topic, 10, &ROSPoseToPAT::processData, this);
00216 }
00217
00218 void ROSPoseToPAT::processData(const geometry_msgs::Pose::ConstPtr& pose)
00219 {
00220 if (transform != NULL)
00221 {
00222
00223 osg::Matrixd sMsv_osg;
00224
00225 sMsv_osg.setTrans(pose->position.x, pose->position.y, pose->position.z);
00226 sMsv_osg.setRotate(osg::Quat(pose->orientation.x, pose->orientation.y, pose->orientation.z, pose->orientation.w));
00227 sMsv_osg.preMultScale(transform->getMatrix().getScale());
00228
00229 transform->setMatrix(sMsv_osg);
00230
00231 }
00232 }
00233
00234 ROSPoseToPAT::~ROSPoseToPAT()
00235 {
00236 }
00237
00238 ROSPointCloudLoader::ROSPointCloudLoader(std::string topic, osg::ref_ptr<osg::Group> root,unsigned int mask,bool del)
00239 : ROSSubscriberInterface(topic), scene_root(root), nodeMask(mask), deleteLastPCD(del)
00240 {
00241
00242 }
00243
00244 void ROSPointCloudLoader::createSubscriber(ros::NodeHandle &nh)
00245 {
00246 ROS_INFO("ROSPointCloudLoader subscriber on topic %s", topic.c_str());
00247 sub_ = nh.subscribe<pcl::PointCloud<pcl::PointXYZ> >(topic, 10, &ROSPointCloudLoader::processData, this);
00248 }
00249
00250 void ROSPointCloudLoader::processData(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr& msg)
00251 {
00252 osgPCDLoader<pcl::PointXYZ> pcdLoader(*msg.get());
00253
00254 osg::ref_ptr < osg::Node > frame_id=findRN(msg->header.frame_id,scene_root);
00255
00256 if(frame_id)
00257 {
00258 osg::ref_ptr < osg::Node > LWNode=findRN("localizedWorld",scene_root);
00259 boost::shared_ptr<osg::Matrix> LWMat=getWorldCoords(LWNode);
00260 LWMat->invert(*LWMat);
00261
00262 boost::shared_ptr<osg::Matrix> WorldToBase=getWorldCoords(frame_id);
00263
00264 osg::Matrixd res=*WorldToBase * *LWMat;
00265 osg::ref_ptr < osg::MatrixTransform > WorldToBaseTransform= new osg::MatrixTransform(res);
00266 WorldToBaseTransform->addChild(pcdLoader.getGeode());
00267
00268 pcdLoader.getGeode()->setNodeMask(nodeMask);
00269 LWNode->asGroup()->addChild(WorldToBaseTransform);
00270 if(deleteLastPCD)
00271 {
00272 LWNode->asGroup()->removeChild(lastPCD);
00273 lastPCD=WorldToBaseTransform;
00274 }
00275 }
00276 else
00277 {
00278 ROS_WARN ("%s is not a valid frame id for PointCloudLoader.",msg->header.frame_id.c_str());
00279 }
00280 }
00281
00282 ROSPointCloudLoader::~ROSPointCloudLoader(){}
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 ROSJointStateToArm::ROSJointStateToArm(std::string topic, boost::shared_ptr<SimulatedIAUV> arm) :
00337 ROSSubscriberInterface(topic)
00338 {
00339 this->arm = arm;
00340 }
00341
00342 void ROSJointStateToArm::createSubscriber(ros::NodeHandle &nh)
00343 {
00344 ROS_INFO("ROSJointStateToArm subscriber on topic %s", topic.c_str());
00345 sub_ = nh.subscribe < sensor_msgs::JointState > (topic, 10, &ROSJointStateToArm::processData, this);
00346 }
00347
00348 void ROSJointStateToArm::processData(const sensor_msgs::JointState::ConstPtr& js)
00349 {
00350
00351 if (js->position.size() != 0)
00352 {
00353
00354 std::vector < std::string > names = js->name;
00355 std::vector<double> position = js->position;
00356 arm->urdf->setJointPosition(position, names);
00357 }
00358 else if (js->velocity.size() != 0)
00359 {
00360
00361 std::vector < std::string > names = js->name;
00362 std::vector<double> velocity = js->velocity;
00363 arm->urdf->setJointVelocity(velocity, names);
00364 }
00365 }
00366
00367 ROSJointStateToArm::~ROSJointStateToArm()
00368 {
00369 }
00370
00371 ROSImageToHUDCamera::ROSImageToHUDCamera(std::string topic, std::string info_topic, boost::shared_ptr<HUDCamera> camera) :
00372 ROSSubscriberInterface(info_topic), cam(camera), image_topic(topic)
00373 {
00374 }
00375
00376 void ROSImageToHUDCamera::createSubscriber(ros::NodeHandle &nh)
00377 {
00378 ROS_INFO("ROSImageToHUDCamera subscriber on topic %s", topic.c_str());
00379 it.reset(new image_transport::ImageTransport(nh));
00380 OSG_DEBUG << "ROSImageToHUDCamera::createSubscriber Subscribing to image topic " << image_topic << std::endl;
00381 image_sub = it->subscribe(image_topic, 1, &ROSImageToHUDCamera::processData, this);
00382
00383
00384 }
00385
00386 void ROSImageToHUDCamera::processData(const sensor_msgs::ImageConstPtr& msg)
00387 {
00388 OSG_DEBUG << "ROSImageToHUDCamera::imageCallback start: " << msg->width << "x" << msg->height << " step:" << msg->step
00389 << std::endl;
00390
00391
00392
00393 char *osgimage_data = (char*)cam->osg_image->data();
00394
00395
00396
00397 for (unsigned int i = 0; i < msg->height; i++)
00398 {
00399 for (unsigned int j = 0; j < msg->step; j++)
00400 {
00401 osgimage_data[i * msg->step + j] = msg->data[(msg->height - i - 1) * msg->step + j];
00402 }
00403 }
00404 cam->ready_ = true;
00405 OSG_DEBUG << "ROSImageToHUDCamera::imageCallback exit" << std::endl;
00406 }
00407
00408 ROSImageToHUDCamera::~ROSImageToHUDCamera()
00409 {
00410 }
00411
00412 ROSPublisherInterface::ROSPublisherInterface(std::string topic, int publish_rate) :
00413 ROSInterface(topic)
00414 {
00415 this->publish_rate = publish_rate;
00416 OSG_DEBUG << "ROSPublisherInterface Thread starting..." << topic << std::endl;
00417 startThread();
00418 OSG_DEBUG << "ROSPublisherInterface Thread created" << std::endl;
00419 }
00420
00421
00422 void ROSPublisherInterface::run()
00423 {
00424 ros::Duration(2).sleep();
00425 createPublisher (nh_);
00426
00427 ros::Rate rate(publish_rate);
00428 while (ros::ok())
00429 {
00430 publish();
00431
00432 rate.sleep();
00433 }
00434 }
00435
00436 ROSPublisherInterface::~ROSPublisherInterface()
00437 {
00438 join();
00439 }
00440
00441 PATToROSOdom::PATToROSOdom(osg::Group *rootNode, std::string vehicleName, std::string topic, int rate) :
00442 ROSPublisherInterface(topic, rate)
00443 {
00444
00445 findNodeVisitor findNode(vehicleName);
00446 rootNode->accept(findNode);
00447 osg::Node *first = findNode.getFirst();
00448 if (first == NULL)
00449 {
00450 transform = NULL;
00451 }
00452 else
00453 {
00454 transform = dynamic_cast<osg::MatrixTransform*>(first);
00455 }
00456 }
00457
00458 void PATToROSOdom::createPublisher(ros::NodeHandle &nh)
00459 {
00460 ROS_INFO("PATToROSOdom publisher on topic %s", topic.c_str());
00461 pub_ = nh.advertise < nav_msgs::Odometry > (topic, 1);
00462 }
00463
00464 void PATToROSOdom::publish()
00465 {
00466 if (transform != NULL)
00467 {
00468 nav_msgs::Odometry odom;
00469 odom.header.stamp = getROSTime();
00470
00471 osg::Matrixd mat = transform->getMatrix();
00472 osg::Vec3d pos = mat.getTrans();
00473 osg::Quat rot = mat.getRotate();
00474
00475 odom.pose.pose.position.x = pos.x();
00476 odom.pose.pose.position.y = pos.y();
00477 odom.pose.pose.position.z = pos.z();
00478 odom.pose.pose.orientation.x = rot.x();
00479 odom.pose.pose.orientation.y = rot.y();
00480 odom.pose.pose.orientation.z = rot.z();
00481 odom.pose.pose.orientation.w = rot.w();
00482
00483
00484 odom.twist.twist.linear.x = 0;
00485 odom.twist.twist.linear.y = 0;
00486 odom.twist.twist.linear.z = 0;
00487 odom.twist.twist.angular.x = 0;
00488 odom.twist.twist.angular.y = 0;
00489 odom.twist.twist.angular.z = 0;
00490 for (int i = 0; i < 36; i++)
00491 {
00492 odom.twist.covariance[i] = 0;
00493 odom.pose.covariance[i] = 0;
00494 }
00495
00496 pub_.publish(odom);
00497 }
00498 }
00499
00500 PATToROSOdom::~PATToROSOdom()
00501 {
00502 }
00503
00504 ImuToROSImu::ImuToROSImu(InertialMeasurementUnit *imu, std::string topic, int rate) :
00505 ROSPublisherInterface(topic, rate), imu_(imu)
00506 {
00507 }
00508
00509 void ImuToROSImu::createPublisher(ros::NodeHandle &nh)
00510 {
00511 ROS_INFO("Imu publisher on topic %s", topic.c_str());
00512 pub_ = nh.advertise < sensor_msgs::Imu > (topic, 1);
00513 }
00514
00515 void ImuToROSImu::publish()
00516 {
00517 if (imu_ != NULL)
00518 {
00519 osg::Quat rot = imu_->getMeasurement();
00520
00521 sensor_msgs::Imu imu;
00522 imu.header.stamp = getROSTime();
00523 imu.header.frame_id = "world";
00524 imu.orientation.x = rot.x();
00525 imu.orientation.y = rot.y();
00526 imu.orientation.z = rot.z();
00527 imu.orientation.w = rot.w();
00528
00529 imu.orientation_covariance[0] = imu.orientation_covariance[4] = imu.orientation_covariance[8] = std::pow(
00530 imu_->getStandardDeviation(), 2);
00531
00532 pub_.publish(imu);
00533 }
00534 }
00535
00536 ImuToROSImu::~ImuToROSImu()
00537 {
00538 }
00539
00540 PressureSensorToROS::PressureSensorToROS(PressureSensor *sensor, std::string topic, int rate) :
00541 ROSPublisherInterface(topic, rate), sensor_(sensor)
00542 {
00543 }
00544
00545 void PressureSensorToROS::createPublisher(ros::NodeHandle &nh)
00546 {
00547 ROS_INFO("PressureSensor publisher on topic %s", topic.c_str());
00548 pub_ = nh.advertise < underwater_sensor_msgs::Pressure > (topic, 1);
00549 }
00550
00551 void PressureSensorToROS::publish()
00552 {
00553 if (sensor_ != NULL)
00554 {
00555 double pressure = sensor_->getMeasurement();
00556
00557 underwater_sensor_msgs::Pressure v;
00558 v.pressure = pressure;
00559 v.header.stamp = getROSTime();
00560 v.header.frame_id = "world";
00561
00562 pub_.publish(v);
00563 }
00564 }
00565
00566 PressureSensorToROS::~PressureSensorToROS()
00567 {
00568 }
00569
00570 void GPSSensorToROS::createPublisher(ros::NodeHandle &nh)
00571 {
00572 ROS_INFO("GPSSensor publisher on topic %s", topic.c_str());
00573 pub_ = nh.advertise < sensor_msgs::NavSatFix > (topic, 1);
00574 }
00575
00576 void GPSSensorToROS::publish()
00577 {
00578 if (sensor_ != NULL)
00579 {
00580 osg::Vec3d wTgps = sensor_->getMeasurement();
00581
00582
00583 if (sensor_->depthBelowWater() < 0.5)
00584 {
00585 sensor_msgs::NavSatFix m;
00586 m.latitude = wTgps[0];
00587 m.longitude = wTgps[1];
00588 m.position_covariance[0] = m.position_covariance[4] = m.position_covariance[8] = std::pow(
00589 sensor_->getStandardDeviation(), 2);
00590 m.position_covariance_type = m.COVARIANCE_TYPE_DIAGONAL_KNOWN;
00591
00592 pub_.publish(m);
00593 }
00594 }
00595 }
00596
00597 void DVLSensorToROS::createPublisher(ros::NodeHandle &nh)
00598 {
00599 ROS_INFO("DVLSensor publisher on topic %s", topic.c_str());
00600 pub_ = nh.advertise < underwater_sensor_msgs::DVL > (topic, 1);
00601 }
00602
00603 void DVLSensorToROS::publish()
00604 {
00605 if (sensor_ != NULL)
00606 {
00607 osg::Vec3d vdvl = sensor_->getMeasurement();
00608
00609 underwater_sensor_msgs::DVL m;
00610 m.bi_x_axis = vdvl.x();
00611 m.bi_y_axis = vdvl.y();
00612 m.bi_z_axis = vdvl.z();
00613
00614 pub_.publish(m);
00615 }
00616 }
00617
00618 ArmToROSJointState::ArmToROSJointState(SimulatedIAUV *arm, std::string topic, int rate) :
00619 ROSPublisherInterface(topic, rate)
00620 {
00621 this->arm = arm->urdf;
00622 }
00623
00624 void ArmToROSJointState::createPublisher(ros::NodeHandle &nh)
00625 {
00626 ROS_INFO("ArmToROSJointState publisher on topic %s", topic.c_str());
00627 pub_ = nh.advertise < sensor_msgs::JointState > (topic, 1);
00628 }
00629
00630 void ArmToROSJointState::publish()
00631 {
00632 if (arm != NULL)
00633 {
00634 sensor_msgs::JointState js;
00635 js.header.stamp = getROSTime();
00636 std::vector<double> q = arm->getJointPosition();
00637 std::vector<std::string> names=arm->getJointName();
00638 for (size_t i = 0; i < q.size(); i++)
00639 {
00640 js.name.push_back(names[i]);
00641 js.position.push_back(q[i]);
00642 js.effort.push_back(0);
00643 }
00644
00645 pub_.publish(js);
00646 }
00647 }
00648
00649 ArmToROSJointState::~ArmToROSJointState()
00650 {
00651 }
00652
00653 void VirtualCameraToROSImage::CameraBufferCallback::operator () (const osg::Camera& camera) const
00654 {
00655 if(pub)
00656 {
00657 pub->mutex.lock();
00658 if (depth)
00659 {
00660 pub->osgimage = new osg::Image(*cam->depthTexture.get());
00661 }
00662 else
00663 {
00664 pub->osgimage = new osg::Image(*cam->renderTexture.get());
00665 }
00666 pub->mutex.unlock();
00667 }
00668 }
00669
00670 VirtualCameraToROSImage::CameraBufferCallback::CameraBufferCallback(VirtualCameraToROSImage * publisher,VirtualCamera *camera,int depth)
00671 {
00672 pub = publisher;
00673 cam=camera;
00674 this->depth=depth;
00675 }
00676
00677 VirtualCameraToROSImage::VirtualCameraToROSImage(VirtualCamera *camera, std::string topic, std::string info_topic,
00678 int rate, int depth) :
00679 ROSPublisherInterface(info_topic, rate), cam(camera), image_topic(topic)
00680 {
00681 it.reset(new image_transport::ImageTransport(nh_));
00682 this->depth = depth;
00683 this->bw = camera->bw;
00684 CameraBufferCallback * buffercb = new CameraBufferCallback(this,cam,depth);
00685 cam->textureCamera->setPostDrawCallback(buffercb);
00686 }
00687
00688 void VirtualCameraToROSImage::createPublisher(ros::NodeHandle &nh)
00689 {
00690 ROS_INFO("VirtualCameraToROSImage publisher on topic %s", topic.c_str());
00691 while (!it)
00692 {
00693 ROS_INFO("VirtualCameraToROSImage Waiting for transport to be initialized...");
00694 }
00695 img_pub_ = it->advertise(image_topic, 1);
00696 pub_ = nh.advertise < sensor_msgs::CameraInfo > (topic, 1);
00697 }
00698
00699 void VirtualCameraToROSImage::publish()
00700 {
00701
00702 if (osgimage != NULL && osgimage->getTotalSizeInBytes() != 0)
00703 {
00704
00705 int w, h, d;
00706 w = osgimage->s();
00707 h = osgimage->t();
00708 d = osgimage->getTotalSizeInBytes();
00709
00710 if (d != 0)
00711 {
00712 sensor_msgs::Image img;
00713 sensor_msgs::CameraInfo img_info;
00714 img_info.header.stamp = img.header.stamp = getROSTime();
00715 img_info.header.frame_id = img.header.frame_id = cam->frameId;
00716 if (depth)
00717 img.encoding = std::string("32FC1");
00718 else if (bw)
00719 img.encoding = std::string("mono8");
00720 else
00721 img.encoding = std::string("rgb8");
00722
00723 img.is_bigendian = 0;
00724 img.height = h;
00725 img.width = w;
00726 if (bw)
00727 d /=3;
00728 img.step = d / h;
00729 img.data.resize(d);
00730 img_info.width = w;
00731 img_info.height = h;
00732
00733 img_info.D.resize(4, 0.0);
00734
00735 img_info.R[0] = 1.0;
00736 img_info.R[4] = 1.0;
00737 img_info.R[8] = 1.0;
00738
00739 img_info.K[0] = cam->fx;
00740 img_info.K[2] = cam->cx;
00741 img_info.K[4] = cam->fy;
00742 img_info.K[5] = cam->cy;
00743 img_info.K[8] = 1;
00744
00745 img_info.P[0] = cam->fx;
00746 img_info.P[2] = cam->cx;
00747 img_info.P[3] = cam->Tx;
00748 img_info.P[5] = cam->fy;
00749 img_info.P[6] = cam->cy;
00750 img_info.P[7] = cam->Ty;
00751 img_info.P[10] = 1;
00752
00753 img_info.roi.x_offset = 0;
00754 img_info.roi.y_offset = 0;
00755 img_info.roi.height = img_info.height;
00756 img_info.roi.width = img_info.width;
00757 img_info.roi.do_rectify = false;
00758
00759 img_info.binning_x = 0;
00760 img_info.binning_y = 0;
00761
00762 double fov, aspect, near, far;
00763 cam->textureCamera->getProjectionMatrixAsPerspective(fov, aspect, near, far);
00764 double a = far / (far - near);
00765 double b = (far * near) / (near - far);
00766
00767
00768
00769 mutex.lock();
00770 unsigned char *virtualdata = (unsigned char*)osgimage->data();
00771
00772
00773
00774
00775 if (virtualdata != NULL)
00776 for (int i = 0; i < h; i++)
00777 {
00778 unsigned char *srcRow = virtualdata + i * img.step*(bw?3:1);
00779 unsigned char *dstRow = img.data.data() + (h - i - 1) * img.step;
00780 for (unsigned int j = 0;
00781 (!depth && j < img.step) || (depth && j < w); j++)
00782 {
00783 if (bw)
00784 {
00785 dstRow[j] = srcRow[j * 3] * 0.2989;
00786 dstRow[j] += srcRow[j * 3 + 1] * 0.5870;
00787 dstRow[j] += srcRow[j * 3 + 2] * 0.1140;
00788 }
00789 else if (depth)
00790 {
00791 float D = b / (((float*)srcRow)[j] - a);
00792 if (D == far)
00793 D = INFINITY;
00794 else if (D == near)
00795 D = -INFINITY;
00796 else if (!isfinite(D) || D < near || D > far)
00797 D = NAN;
00798 ((float*)dstRow)[j] = D;
00799 }
00800 else
00801 dstRow[j] = srcRow[j];
00802 }
00803 }
00804 else
00805 memset(&(img.data.front()), 0, d);
00806 mutex.unlock();
00807
00808 img_pub_.publish(img);
00809 pub_.publish(img_info);
00810 }
00811 }
00812
00813 }
00814
00815 VirtualCameraToROSImage::~VirtualCameraToROSImage()
00816 {
00817 }
00818
00819 RangeSensorToROSRange::RangeSensorToROSRange(VirtualRangeSensor *rangesensor, std::string topic, int rate) :
00820 ROSPublisherInterface(topic, rate), rs(rangesensor)
00821 {
00822 }
00823
00824 void RangeSensorToROSRange::createPublisher(ros::NodeHandle &nh)
00825 {
00826 ROS_INFO("RangeSensorToROSRange publisher on topic %s", topic.c_str());
00827 pub_ = nh.advertise < sensor_msgs::Range > (topic, 1);
00828 }
00829
00830 void RangeSensorToROSRange::publish()
00831 {
00832 if (rs != NULL)
00833 {
00834 sensor_msgs::Range r;
00835 r.header.stamp = getROSTime();
00836 r.radiation_type = sensor_msgs::Range::ULTRASOUND;
00837 r.field_of_view = 0;
00838 r.min_range = 0;
00839 r.max_range = rs->range;
00840 r.range = (rs->node_tracker != NULL) ? rs->node_tracker->distance_to_obstacle : r.max_range;
00841
00842 pub_.publish(r);
00843 }
00844 }
00845
00846 RangeSensorToROSRange::~RangeSensorToROSRange()
00847 {
00848 }
00849
00850 MultibeamSensorToROS::MultibeamSensorToROS(MultibeamSensor *multibeamSensor, std::string topic, int rate) :
00851 ROSPublisherInterface(topic, rate), MB(multibeamSensor)
00852 {
00853 }
00854
00855 void MultibeamSensorToROS::createPublisher(ros::NodeHandle &nh)
00856 {
00857 ROS_INFO(" MultibeamSensorToROS publisher on topic %s", topic.c_str());
00858 pub_ = nh.advertise < sensor_msgs::LaserScan > (topic, 1);
00859 }
00860
00861 void MultibeamSensorToROS::publish()
00862 {
00863 if (MB != NULL)
00864 {
00865 sensor_msgs::LaserScan ls;
00866 ls.header.stamp = getROSTime();
00867 ls.header.frame_id = MB->name;
00868
00869 double fov, aspect, near, far;
00870
00871 ls.range_min = near;
00872 ls.range_max = MB->range;
00873 ls.angle_min = MB->initAngle * M_PI / 180;
00874 ls.angle_max = MB->finalAngle * M_PI / 180;
00875 ls.angle_increment = MB->angleIncr * M_PI / 180;
00876
00877 std::vector<double> tmp;
00878 tmp.resize(MB->camPixels*MB->nCams);
00879 for(unsigned int j=0; j<MB->nCams ;j++)
00880 {
00881 MB->vcams[j].textureCamera->getProjectionMatrixAsPerspective(fov, aspect, near, far);
00882
00883 float * data = (float *)MB->vcams[j].depthTexture->data();
00884 double a = far / (far - near);
00885 double b = (far * near) / (near - far);
00886
00887 for (int i = 0; i < MB->camPixels; i++)
00888 {
00889 double Z = (data[i]);
00890 tmp[i+MB->camPixels*j] = b / (Z - a);
00891 }
00892 }
00893
00894 ls.ranges.resize(MB->numpixels);
00895 for (int i = 0; i < MB->numpixels; i++)
00896 {
00897 ls.ranges[i] = (tmp[MB->remapVector[i].pixel1] * MB->remapVector[i].weight1
00898 + tmp[MB->remapVector[i].pixel2] * MB->remapVector[i].weight2) * MB->remapVector[i].distort;
00899 if (ls.ranges[i] > MB->range)
00900 ls.ranges[i] = MB->range;
00901 }
00902
00903 pub_.publish(ls);
00904 }
00905 }
00906
00907 MultibeamSensorToROS::~MultibeamSensorToROS()
00908 {
00909 }
00910
00911 contactSensorToROS::contactSensorToROS(osg::Group *rootNode, BulletPhysics * physics, std::string target,
00912 std::string topic, int rate) :
00913 ROSPublisherInterface(topic, rate)
00914 {
00915 this->rootNode = rootNode;
00916 this->physics = physics;
00917 this->target = target;
00918 }
00919
00920 void contactSensorToROS::createPublisher(ros::NodeHandle &nh)
00921 {
00922 ROS_INFO("contactSensorToROS publisher on topic %s", topic.c_str());
00923 pub_ = nh.advertise < std_msgs::Bool > (topic, 1);
00924 }
00925
00926 void contactSensorToROS::publish()
00927 {
00928 int colliding = 0;
00929
00930 for (int i = 0; i < physics->getNumCollisions(); i++)
00931 {
00932 btPersistentManifold * col = physics->getCollision(i);
00933
00934 #if BT_BULLET_VERSION <= 279
00935
00936 btRigidBody* obA = static_cast<btRigidBody*>(col->getBody0());
00937 btRigidBody* obB = static_cast<btRigidBody*>(col->getBody1());
00938
00939
00940 CollisionDataType * data = (CollisionDataType *)obA->getUserPointer();
00941 CollisionDataType * data2 = (CollisionDataType *)obB->getUserPointer();
00942
00943 #else
00944 CollisionDataType * data = (CollisionDataType *)col->getBody0()->getUserPointer();
00945 CollisionDataType * data2 = (CollisionDataType *)col->getBody0()->getUserPointer();
00946 #endif
00947
00948 int numContacts = col->getNumContacts();
00949
00950 if (data2->getObjectName() == target || data->getObjectName() == target)
00951 {
00952 for (int j = 0; j < numContacts; j++)
00953 {
00954 btManifoldPoint pt = col->getContactPoint(j);
00955 if (pt.getDistance() < 0.f)
00956 colliding = 1;
00957 }
00958 }
00959
00960 }
00961 std_msgs::Bool msg;
00962 msg.data = colliding;
00963 pub_.publish(msg);
00964 }
00965
00966 contactSensorToROS::~contactSensorToROS()
00967 {
00968 }
00969
00970
00971 WorldToROSTF::WorldToROSTF(osg::Group *rootNode, std::vector< boost::shared_ptr<SimulatedIAUV> > iauvFile, std::vector<osg::ref_ptr<osg::Node> > objects, std::string worldRootName, unsigned int enableObjects, int rate ) :
00972 ROSPublisherInterface(worldRootName, rate)
00973 {
00974 iauvFile_ = iauvFile;
00975 objects_ = objects;
00976 rootNode_ = rootNode;
00977 for(int i = 0; i < iauvFile_.size(); i++)
00978 {
00979 KDL::Tree tree;
00980 if (!kdl_parser::treeFromFile(iauvFile[i].get()->urdf->URDFFile, tree))
00981 {
00982 ROS_ERROR("Failed to construct kdl tree");
00983 }
00984 else
00985 {
00986 ROS_INFO("Loaded tree, %d segments, %d joints", tree.getNrOfSegments(), tree.getNrOfJoints());
00987 }
00988
00989 osg::ref_ptr<osg::MatrixTransform> transform;
00990 robot_pubs_.push_back(boost::shared_ptr<robot_state_publisher::RobotStatePublisher>(
00991 new robot_state_publisher::RobotStatePublisher(tree)));
00992
00993 findNodeVisitor findNode(iauvFile[i].get()->name);
00994 rootNode->accept(findNode);
00995 osg::Node *first = findNode.getFirst();
00996 if (first == NULL)
00997 {
00998 transform = NULL;
00999 }
01000 else
01001 {
01002 transform = dynamic_cast<osg::MatrixTransform*>(first);
01003 }
01004 transforms_.push_back(transform);
01005 }
01006 worldRootName_ = worldRootName;
01007 enableObjects_ = enableObjects;
01008 }
01009
01010 void WorldToROSTF::createPublisher(ros::NodeHandle &nh)
01011 {
01012 tfpub_ = boost::shared_ptr<tf::TransformBroadcaster>(new tf::TransformBroadcaster());
01013 }
01014
01015 void WorldToROSTF::publish()
01016 {
01017
01018
01019 for( int i = 0; i < iauvFile_.size(); i++ )
01020 {
01021
01022 robot_pubs_[i]->RobotStatePublisher::publishTransforms(iauvFile_[i].get()->urdf->getFullJointMap(), getROSTime(), iauvFile_[i].get()->name);
01023
01024 robot_pubs_[i]->RobotStatePublisher::publishFixedTransforms(iauvFile_[i].get()->name);
01025
01026 if (transforms_[i] != NULL)
01027 {
01028 osg::Matrixd mat = transforms_[i]->getMatrix();
01029 osg::Vec3d pos = mat.getTrans();
01030 osg::Quat rot = mat.getRotate();
01031
01032 tf::Vector3 p(pos.x(), pos.y(), pos.z());
01033 tf::Quaternion q(rot.x(), rot.y(), rot.z(), rot.w());
01034 tf::Pose pose(q,p);
01035 tf::StampedTransform t(pose, getROSTime(), "/" + worldRootName_, "/"+iauvFile_[i].get()->name);
01036
01037 tf::Vector3 p2(0, 0, 0);
01038 tf::Quaternion q2(0, 0, 0, 1);
01039 tf::Pose pose2(q2,p2);
01040 tf::StampedTransform t2(pose2, getROSTime(), "/"+iauvFile_[i].get()->name, "/"+iauvFile_[i].get()->name + "/base_link");
01041
01042 tfpub_->sendTransform(t2);
01043 tfpub_->sendTransform(t);
01044 }
01045
01046
01047 for(int j=0; j< iauvFile_[i].get()->camview.size();j++)
01048 {
01049 tf::Pose pose;
01050 std::string parent;
01051 tf::Pose OSGToTFconvention;
01052 if(iauvFile_[i].get()->camview[j].getTFTransform(pose,parent))
01053 {
01054 OSGToTFconvention.setOrigin(tf::Vector3(0,0,0));
01055 OSGToTFconvention.setRotation(tf::Quaternion(tf::Vector3(1,0,0),M_PI));
01056
01057
01058
01059 int multibeam=false;
01060 for(int k=0;k<iauvFile_[i].get()->multibeam_sensors.size();k++)
01061 if(iauvFile_[i].get()->multibeam_sensors[k].name==iauvFile_[i].get()->camview[j].name)
01062 multibeam=true;
01063
01064
01065 if(!multibeam){
01066 pose=pose*OSGToTFconvention;
01067 tf::StampedTransform t(pose, getROSTime(), "/"+iauvFile_[i].get()->name + "/" +parent, iauvFile_[i].get()->camview[j].name);
01068 tfpub_->sendTransform(t);
01069 }
01070 }
01071 }
01072
01073
01074 for(int j=0; j< iauvFile_[i].get()->multibeam_sensors.size();j++)
01075 {
01076 tf::Pose pose;
01077 std::string parent;
01078 if(iauvFile_[i].get()->multibeam_sensors[j].getTFTransform(pose,parent))
01079 {
01080 tf::StampedTransform t(pose, getROSTime(), "/"+iauvFile_[i].get()->name + "/" +parent, iauvFile_[i].get()->multibeam_sensors[i].name);
01081 tfpub_->sendTransform(t);
01082 }
01083 }
01084
01085
01086
01087 for(int j=0; j< iauvFile_[i].get()->imus.size();j++)
01088 {
01089 tf::Pose pose;
01090 std::string parent;
01091 if(iauvFile_[i].get()->imus[j].getTFTransform(pose,parent))
01092 {
01093 tf::StampedTransform t(pose, getROSTime(), "/"+iauvFile_[i].get()->name + "/" +parent, iauvFile_[i].get()->imus[i].name);
01094 tfpub_->sendTransform(t);
01095 }
01096 }
01097
01098
01099 for(int j=0; j< iauvFile_[i].get()->range_sensors.size();j++)
01100 {
01101 tf::Pose pose;
01102 std::string parent;
01103 if(iauvFile_[i].get()->range_sensors[j].getTFTransform(pose,parent))
01104 {
01105 tf::StampedTransform t(pose, getROSTime(), "/"+iauvFile_[i].get()->name + "/" +parent, iauvFile_[i].get()->range_sensors[i].name);
01106 tfpub_->sendTransform(t);
01107 }
01108 }
01109
01110
01111 for(int j=0; j< iauvFile_[i].get()->pressure_sensors.size();j++)
01112 {
01113 tf::Pose pose;
01114 std::string parent;
01115 if(iauvFile_[i].get()->pressure_sensors[j].getTFTransform(pose,parent))
01116 {
01117 tf::StampedTransform t(pose, getROSTime(), "/"+iauvFile_[i].get()->name + "/" +parent, iauvFile_[i].get()->pressure_sensors[i].name);
01118 tfpub_->sendTransform(t);
01119 }
01120 }
01121
01122
01123 for(int j=0; j< iauvFile_[i].get()->gps_sensors.size();j++)
01124 {
01125 tf::Pose pose;
01126 std::string parent;
01127 if(iauvFile_[i].get()->gps_sensors[j].getTFTransform(pose,parent))
01128 {
01129 tf::StampedTransform t(pose, getROSTime(), "/"+iauvFile_[i].get()->name + "/" +parent, iauvFile_[i].get()->gps_sensors[i].name);
01130 tfpub_->sendTransform(t);
01131 }
01132 }
01133
01134
01135 for(int j=0; j< iauvFile_[i].get()->dvl_sensors.size();j++)
01136 {
01137 tf::Pose pose;
01138 std::string parent;
01139 if(iauvFile_[i].get()->dvl_sensors[j].getTFTransform(pose,parent))
01140 {
01141 tf::StampedTransform t(pose, getROSTime(), "/"+iauvFile_[i].get()->name + "/" +parent, iauvFile_[i].get()->dvl_sensors[i].name);
01142 tfpub_->sendTransform(t);
01143 }
01144 }
01145
01146 }
01147
01148
01149 if(enableObjects_)
01150 {
01151
01152 boost::shared_ptr<osg::Matrix> LWMat=getWorldCoords(findRN("localizedWorld",rootNode_));
01153 LWMat->invert(*LWMat);
01154
01155 for(unsigned int i=0;i<objects_.size();i++)
01156 {
01157 boost::shared_ptr<osg::Matrix> objectMat= getWorldCoords(objects_[i]);
01158
01159 osg::Matrixd res=*objectMat * *LWMat;
01160
01161 tf::Vector3 p2(res.getTrans().x(), res.getTrans().y(), res.getTrans().z());
01162 tf::Quaternion q2(res.getRotate().x(), res.getRotate().y(), res.getRotate().z(), res.getRotate().w());
01163 tf::Pose pose2(q2,p2);
01164 tf::StampedTransform t(pose2, getROSTime(), "/" + worldRootName_, objects_[i]->getName());
01165
01166 tfpub_->sendTransform(t);
01167 }
01168
01169 }
01170
01171
01172
01173 }
01174
01175 WorldToROSTF::~WorldToROSTF()
01176 {
01177 }