00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <pluginlib/class_list_macros.h>
00014 #include <uwsim/ForceSensor.h>
00015
00016 ForceSensor::ForceSensor(ForceSensor_Config * cfg, osg::ref_ptr<osg::Node> target) :
00017 SimulatedDevice(cfg)
00018 {
00019 this->target = target;
00020 this->offsetp[0]=cfg->offsetp[0]; this->offsetp[1]=cfg->offsetp[1]; this->offsetp[2]=cfg->offsetp[2];
00021 offset.makeRotate(osg::Quat(cfg->offsetr[0], osg::Vec3d(1, 0, 0), cfg->offsetr[1], osg::Vec3d(0, 1, 0), cfg->offsetr[2],osg::Vec3d(0, 0, 1)));
00022 physics=NULL;
00023 }
00024
00025 static void forceSensorPreTickCallback(btDynamicsWorld *world, btScalar timeStep){
00026 ForceSensor *fs = static_cast<ForceSensor *>(world->getWorldUserInfo());
00027 fs->physicsInternalPreProcessCallback(timeStep);
00028 }
00029
00030 static void forceSensorPostTickCallback(btDynamicsWorld *world, btScalar timeStep){
00031 ForceSensor *fs = static_cast<ForceSensor *>(world->getWorldUserInfo());
00032 fs->physicsInternalPostProcessCallback(timeStep);
00033 }
00034
00035 void ForceSensor::applyPhysics(BulletPhysics * bulletPhysics)
00036 {
00037 physics=bulletPhysics;
00038 osg::ref_ptr<NodeDataType> data = dynamic_cast<NodeDataType*>(target->getUserData());
00039 copy=physics->copyObject(data->rigidBody);
00040 copy->setGravity(btVector3(0,0,0));
00041 copy->setCenterOfMassTransform(btTransform(btQuaternion(0,0,0,1),btVector3(-0.2,0,0.75)));
00042 btTarget = data->rigidBody;
00043 btTarget->setCenterOfMassTransform(btTransform(btQuaternion(0,0,0,1),btVector3(-0.2,0,0.75)));
00044
00045 physics->dynamicsWorld->setInternalTickCallback(forceSensorPreTickCallback, static_cast<void *>(this),true);
00046 physics->dynamicsWorld->setInternalTickCallback(forceSensorPostTickCallback, static_cast<void *>(this));
00047 }
00048
00049 void ForceSensor::physicsInternalPreProcessCallback(btScalar timeStep)
00050 {
00051 if (physics->physicsStep==1){
00052 copy->setCenterOfMassTransform(btTarget->getCenterOfMassTransform());
00053 copy->clearForces();
00054 copy->setLinearVelocity(btTarget->getLinearVelocity());
00055 copy->setAngularVelocity(btTarget->getAngularVelocity());
00056 linInitial=copy->getLinearVelocity();
00057 angInitial=copy->getAngularVelocity();
00058 }
00059 physics->physicsStep++;
00060 }
00061
00062 void ForceSensor::physicsInternalPostProcessCallback(btScalar timeStep)
00063 {
00064 linFinal=copy->getLinearVelocity();
00065 angFinal=copy->getAngularVelocity();
00066 lastTimeStep=timeStep;
00067 }
00068
00069 void ForceSensor::getForceTorque(double force[3], double torque[3])
00070 {
00071 if(physics->physicsStep ==0)
00072 {
00073
00074 osg::Matrix ObjectMat= offset * *getWorldCoords(target);
00075
00076 osg::Vec3 res=ObjectMat.getRotate().inverse()*osg::Vec3(linFinal.x()-linInitial.x(),linFinal.y()-linInitial.y(),linFinal.z()-linInitial.z());
00077
00078 force[0]=res.x();
00079 force[1]=res.y();
00080 force[2]=res.z();
00081
00082 res=ObjectMat.getRotate().inverse()*osg::Vec3(angFinal.x()-angInitial.x(),angFinal.y()-angInitial.y(),angFinal.z()-angInitial.z());
00083
00084
00085 torque[0]=res.x()/10;
00086 torque[1]=res.y()/10;
00087 torque[2]=res.z()/10;
00088 }
00089 else
00090 {
00091 force[0]=0;
00092 force[1]=0;
00093 force[2]=0;
00094
00095 torque[0]=0;
00096 torque[1]=0;
00097 torque[2]=0;
00098
00099 }
00100 }
00101
00102 SimulatedDeviceConfig::Ptr ForceSensor_Factory::processConfig(const xmlpp::Node* node, ConfigFile * config)
00103 {
00104 ForceSensor_Config * cfg = new ForceSensor_Config(getType());
00105 xmlpp::Node::NodeList list = node->get_children();
00106 for (xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
00107 {
00108 xmlpp::Node* child = dynamic_cast<const xmlpp::Node*>(*iter);
00109 if(child->get_name() == "target")
00110 config->extractStringChar(child, cfg->target);
00111 else if(child->get_name() == "offsetp")
00112 config->extractPositionOrColor(child, cfg->offsetp);
00113 else if(child->get_name() == "offsetr")
00114 config->extractPositionOrColor(child, cfg->offsetr);
00115 }
00116 return SimulatedDeviceConfig::Ptr(cfg);
00117 }
00118
00119 bool ForceSensor_Factory::applyConfig(SimulatedIAUV * auv, Vehicle &vehicleChars, SceneBuilder *sceneBuilder,
00120 size_t iteration)
00121 {
00122 if (iteration > 0)
00123 return true;
00124 for (size_t i = 0; i < vehicleChars.simulated_devices.size(); ++i)
00125 if (vehicleChars.simulated_devices[i]->getType() == this->getType())
00126 {
00127 ForceSensor_Config * cfg = dynamic_cast<ForceSensor_Config *>(vehicleChars.simulated_devices[i].get());
00128 osg::ref_ptr<osg::Node> target;
00129 for(i=0;i<auv->urdf->link.size();i++)
00130 {
00131 if(auv->urdf->link[i]->getName()==cfg->target)
00132 {
00133 target=auv->urdf->link[i];
00134 }
00135 }
00136 auv->devices->all.push_back(ForceSensor::Ptr(new ForceSensor(cfg,target)));
00137 }
00138 return true;
00139 }
00140
00141 std::vector<boost::shared_ptr<ROSInterface> > ForceSensor_Factory::getInterface(
00142 ROSInterfaceInfo & rosInterface, std::vector<boost::shared_ptr<SimulatedIAUV> > & iauvFile)
00143 {
00144 std::vector < boost::shared_ptr<ROSInterface> > ifaces;
00145 for (size_t i = 0; i < iauvFile.size(); ++i)
00146 for (size_t d = 0; d < iauvFile[i]->devices->all.size(); ++d)
00147 if (iauvFile[i]->devices->all[d]->getType() == this->getType()
00148 && iauvFile[i]->devices->all[d]->name == rosInterface.targetName)
00149 {
00150 ifaces.push_back(
00151 boost::shared_ptr < ROSInterface
00152 > (new ForceSensor_ROSPublisher(dynamic_cast<ForceSensor*>(iauvFile[i]->devices->all[d].get()),
00153 rosInterface.topic, rosInterface.rate)));
00154
00155
00156
00157
00158 }
00159 if (ifaces.size() == 0)
00160 ROS_WARN("Returning empty ROS interface for device %s...", rosInterface.targetName.c_str());
00161 return ifaces;
00162 }
00163
00164 void ForceSensor_ROSPublisher::createPublisher(ros::NodeHandle &nh)
00165 {
00166 ROS_INFO("ForceSensor_ROSPublisher on topic %s", topic.c_str());
00167 pub_ = nh.advertise < geometry_msgs::WrenchStamped > (topic, 1);
00168 }
00169
00170 void ForceSensor_ROSPublisher::publish()
00171 {
00172
00173 double force[3], torque[3], elapsed;
00174
00175 dev->getForceTorque(force,torque);
00176
00177 ros::WallDuration t_diff = ros::WallTime::now() - last;
00178 elapsed = t_diff.toSec();
00179
00180 geometry_msgs::WrenchStamped msg;
00181 msg.header.stamp = getROSTime();
00182 msg.header.frame_id =dev->target->getName();
00183
00184 msg.wrench.force.x=force[0]/elapsed*(1/dev->btTarget->getInvMass());
00185 msg.wrench.force.y=force[1]/elapsed*(1/dev->btTarget->getInvMass());
00186 msg.wrench.force.z=force[2]/elapsed*(1/dev->btTarget->getInvMass());
00187
00188
00189 msg.wrench.torque.x=torque[0]/elapsed*(1/dev->btTarget->getInvMass());
00190 msg.wrench.torque.y=torque[1]/elapsed*(1/dev->btTarget->getInvMass());
00191 msg.wrench.torque.z=torque[2]/elapsed*(1/dev->btTarget->getInvMass());
00192 pub_.publish(msg);
00193
00194 last = ros::WallTime::now();
00195 }
00196
00197 #if ROS_VERSION_MINIMUM(1, 9, 0)
00198
00199 PLUGINLIB_EXPORT_CLASS(ForceSensor_Factory, uwsim::SimulatedDeviceFactory)
00200 #else
00201 PLUGINLIB_REGISTER_CLASS(ForceSensor_Factory, ForceSensor_Factory, uwsim::SimulatedDeviceFactory)
00202 #endif
00203