Go to the documentation of this file.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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <labust/simulation/matrixfwd.hpp>
00038 #include <labust/ros/SimSensors.hpp>
00039 #include <labust/tools/conversions.hpp>
00040 #include <labust/simulation/RBModel.hpp>
00041 #include <labust/tools/GeoUtilities.hpp>
00042
00043 #include <sensor_msgs/Imu.h>
00044 #include <sensor_msgs/NavSatFix.h>
00045 #include <sensor_msgs/FluidPressure.h>
00046 #include <pluginlib/class_list_macros.h>
00047 #include <ros/ros.h>
00048
00049 namespace labust
00050 {
00051 namespace simulation
00052 {
00053 struct sim_pressure
00054 {
00055 void operator()(sensor_msgs::FluidPressure::Ptr& pressure,
00056 const SimSensorInterface::Hook& data)
00057 {
00058 using namespace labust::simulation;
00059 using namespace Eigen;
00060
00061 pressure->header.stamp = ros::Time::now();
00062 pressure->header.frame_id = "local";
00063
00064 const labust::simulation::vector& nu =
00065 data.noisy?data.model.NuNoisy():data.model.Nu();
00066
00067 pressure->fluid_pressure = data.model.getPressure(nu(RBModel::z));
00068 }
00069 };
00070
00071 struct sim_imu
00072 {
00073 void operator()(sensor_msgs::Imu::Ptr& imu,
00074 const SimSensorInterface::Hook& data)
00075 {
00076 using namespace labust::simulation;
00077 using namespace Eigen;
00078
00079 imu->header.stamp = ros::Time::now();
00080 imu->header.frame_id = "imu_frame";
00081 const labust::simulation::vector& nu =
00082 data.noisy?data.model.NuNoisy():data.model.Nu();
00083 labust::tools::vectorToPoint(data.model.NuAcc(), imu->linear_acceleration);
00084 labust::tools::vectorToPoint(nu, imu->angular_velocity,3);
00085
00086 const labust::simulation::vector& eta =
00087 data.noisy?data.model.EtaNoisy():data.model.Eta();
00088 Quaternion<double> quat;
00089 labust::tools::quaternionFromEulerZYX(eta(RBModel::phi),
00090 eta(RBModel::theta),
00091 eta(RBModel::psi), quat);
00092
00093 imu->orientation.x = quat.x();
00094 imu->orientation.y = quat.y();
00095 imu->orientation.z = quat.z();
00096 imu->orientation.w = quat.w();
00097
00098 tf::Transform transform;
00099 transform.setOrigin(tf::Vector3(0, 0, 0));
00100 transform.setRotation(tf::createQuaternionFromRPY(0,0,0));
00101 data.broadcaster.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "base_link", "imu_frame"));
00102 }
00103 };
00104
00107 struct GPSSensor : public SimSensorInterface
00108 {
00109 GPSSensor():rate(10){};
00110
00111 void configure(ros::NodeHandle& nh, const std::string& topic_name)
00112 {
00113 pub = nh.advertise<sensor_msgs::NavSatFix>(topic_name,1);
00114 ros::NodeHandle ph("~");
00115 ph.param("gps_pub",rate,rate);
00116 };
00117
00118 void step(const Hook& data)
00119 {
00120 static int i=0;
00121 if ((i=++i%rate) == 0)
00122 {
00123 sensor_msgs::NavSatFixPtr msg(new sensor_msgs::NavSatFix());
00124 (*this)(msg, data);
00125 pub.publish(msg);
00126 }
00127 }
00128
00129 void operator()(sensor_msgs::NavSatFix::Ptr& fix,
00130 const SimSensorInterface::Hook& data)
00131 {
00132 using namespace labust::simulation;
00133 using namespace Eigen;
00134
00135 tf::Transform transform2;
00136 transform2.setOrigin(tf::Vector3(0, 0, 0));
00137 transform2.setRotation(tf::createQuaternionFromRPY(0,0,0));
00138 data.broadcaster.sendTransform(tf::StampedTransform(transform2, ros::Time::now(), "base_link", "gps_frame"));
00139
00140 tf::StampedTransform transformLocal, transformDeg;
00141 try
00142 {
00143
00144 data.listener.lookupTransform("/worldLatLon", "/world", ros::Time(0), transformDeg);
00145 data.originLat = transformDeg.getOrigin().y();
00146 data.originLon = transformDeg.getOrigin().x();
00147 }
00148 catch (tf::TransformException& ex)
00149 {
00150 ROS_ERROR("%s",ex.what());
00151 }
00152
00153 try
00154 {
00155 data.listener.lookupTransform("base_link", "gps_frame", ros::Time(0), transformLocal);
00156
00157 const labust::simulation::vector& eta = (data.noisy ? data.model.EtaNoisy():data.model.Eta());
00158 fix->altitude = 0;
00159 fix->altitude = eta(RBModel::z) - transformLocal.getOrigin().z();
00160 std::pair<double, double> diffAngle = labust::tools::meter2deg(eta(RBModel::x),
00161 eta(RBModel::y),
00162
00163 data.originLat);
00164
00165 fix->latitude = data.originLat + diffAngle.first;
00166 fix->longitude = data.originLon + diffAngle.second;
00167 fix->header.stamp = ros::Time::now();
00168 fix->header.frame_id = "worldLatLon";
00169
00170
00171
00172
00173
00174
00175
00176
00177 }
00178 catch (tf::TransformException& ex)
00179 {
00180 ROS_ERROR("%s",ex.what());
00181 }
00182 }
00183
00184 private:
00185 ros::Publisher pub;
00186 int rate;
00187 };
00188
00189 typedef BasicSensor<sensor_msgs::Imu, sim_imu> ImuSensor;
00190 typedef BasicSensor<sensor_msgs::FluidPressure, sim_pressure> PressureSensor;
00191
00192 }
00193 }
00194
00195 PLUGINLIB_EXPORT_CLASS(labust::simulation::ImuSensor,
00196 labust::simulation::SimSensorInterface)
00197 PLUGINLIB_EXPORT_CLASS(labust::simulation::GPSSensor,
00198 labust::simulation::SimSensorInterface)
00199
00200