lpms_imu_node.cpp
Go to the documentation of this file.
1 
17 #include <string>
18 #include <map>
19 
20 #include "ros/ros.h"
21 #include "sensor_msgs/Imu.h"
22 #include "sensor_msgs/MagneticField.h"
23 
24 #include "lpsensor/LpmsSensorI.h"
25 #include "lpsensor/LpmsSensorManagerI.h"
26 
27 #include "timesync/TimestampSynchronizer.h"
28 
30 
34 {
35  public:
37  {
38  // Initialize mapping of LPMS sensor types
39  device_map = {{"DEVICE_LPMS_B", DEVICE_LPMS_B},
40  {"DEVICE_LPMS_U", DEVICE_LPMS_U},
41  {"DEVICE_LPMS_C", DEVICE_LPMS_C},
42  {"DEVICE_LPMS_BLE", DEVICE_LPMS_BLE},
43  {"DEVICE_LPMS_RS232", DEVICE_LPMS_RS232},
44  {"DEVICE_LPMS_B2", DEVICE_LPMS_B2},
45  {"DEVICE_LPMS_U2", DEVICE_LPMS_U2},
46  {"DEVICE_LPMS_C2", DEVICE_LPMS_C2}};
47 
48  // Get node parameters
49  private_nh.param<std::string>("sensor_model", sensor_model, "DEVICE_LPMS_U2");
50  private_nh.param<std::string>("port", port, "/dev/ttyUSB0");
51  private_nh.param<std::string>("frame_id", frame_id, "imu");
52  private_nh.param("rate", rate, 200);
53 
54  // Timestamp synchronization
55  private_nh.param("enable_time_sync", enable_Tsync, true);
56 
57  // Connect to the LP IMU device
58  manager = LpmsSensorManagerFactory();
59  imu = manager->addSensor(device_map[sensor_model], port.c_str());
60 
61  imu_pub = nh.advertise<sensor_msgs::Imu>("imu",1);
62  mag_pub = nh.advertise<sensor_msgs::MagneticField>("mag",1);
63 
64  TimestampSynchronizer::Options defaultSyncOptions;
65  defaultSyncOptions.useMedianFilter = true;
66  defaultSyncOptions.medianFilterWindow = 1500;
67  defaultSyncOptions.useHoltWinters = true;
68  defaultSyncOptions.alfa_HoltWinters = 4e-4;
69  defaultSyncOptions.beta_HoltWinters = 3e-4;
70  defaultSyncOptions.alfa_HoltWinters_early = 5e-2;
71  defaultSyncOptions.beta_HoltWinters_early = 1e-3;
72  defaultSyncOptions.earlyClamp = true;
73  defaultSyncOptions.earlyClampWindow = 120*200;
74  defaultSyncOptions.timeOffset = 0.0;
75  defaultSyncOptions.initialB_HoltWinters = -3.4e-7;
76  pstampSynchronizer = std::make_unique<TimestampSynchronizer>(defaultSyncOptions);
77 
78  }
79 
81  {
82  manager->removeSensor(imu);
83  delete manager;
84  }
85 
86  void update(const ros::TimerEvent& te)
87  {
88  if (imu->getConnectionStatus() == SENSOR_CONNECTION_CONNECTED &&
89  imu->hasImuData())
90  {
91  data = imu->getCurrentData();
92 
93  /* Fill the IMU message */
94 
95  // Fill the header
96  imu_msg.header.stamp = enable_Tsync ? ros::Time(pstampSynchronizer->sync(data.timeStamp, ros::Time::now().toSec(), data.frameCount)) : ros::Time::now();
97  imu_msg.header.frame_id = frame_id;
98 
99  // Fill orientation quaternion
100  imu_msg.orientation.w = data.q[0];
101  imu_msg.orientation.x = -data.q[1];
102  imu_msg.orientation.y = -data.q[2];
103  imu_msg.orientation.z = -data.q[3];
104 
105  // Fill angular velocity data
106  // - scale from deg/s to rad/s
107  imu_msg.angular_velocity.x = data.g[0]*3.1415926/180;
108  imu_msg.angular_velocity.y = data.g[1]*3.1415926/180;
109  imu_msg.angular_velocity.z = data.g[2]*3.1415926/180;
110 
111  // Fill linear acceleration data
112  imu_msg.linear_acceleration.x = -data.a[0]*9.81;
113  imu_msg.linear_acceleration.y = -data.a[1]*9.81;
114  imu_msg.linear_acceleration.z = -data.a[2]*9.81;
115 
116  // \TODO: Fill covariance matrices
117  // msg.orientation_covariance = ...
118  // msg.angular_velocity_covariance = ...
119  // msg linear_acceleration_covariance = ...
120 
121  /* Fill the magnetometer message */
122  mag_msg.header.stamp = imu_msg.header.stamp;
123  mag_msg.header.frame_id = frame_id;
124 
125  // Units are microTesla in the LPMS library, Tesla in ROS.
126  mag_msg.magnetic_field.x = data.b[0]*1e-6;
127  mag_msg.magnetic_field.y = data.b[1]*1e-6;
128  mag_msg.magnetic_field.z = data.b[2]*1e-6;
129 
130  // Publish the messages
133  }
134  }
135 
136  void run(void)
137  {
138  // The timer ensures periodic data publishing
141  this));
142  }
143 
144  private:
145 
146  // Access to LPMS data
147  LpmsSensorManagerI* manager;
148  LpmsSensorI* imu;
149  ImuData data;
150  std::map<std::string,int> device_map;
151 
152  // Access to ROS node
156  sensor_msgs::Imu imu_msg;
157  sensor_msgs::MagneticField mag_msg;
158 
159  // Parameters
160  std::string sensor_model;
161  std::string port;
162  std::string frame_id;
163  int rate;
164 
165  // Timestamp syncronization
167 
168  std::unique_ptr<TimestampSynchronizer> pstampSynchronizer;
169 };
170 
171 int main(int argc, char *argv[])
172 {
173 
174  ros::init(argc, argv, "lpms_imu");
176 
177  LpImuProxy lpImu;
178 
179  lpImu.run();
180 
181  ros::spin();
182 
183  return 0;
184 }
std::string port
std::unique_ptr< TimestampSynchronizer > pstampSynchronizer
std::string sensor_model
void publish(const boost::shared_ptr< M > &message) const
LpmsSensorI * imu
int main(int argc, char *argv[])
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::map< std::string, int > device_map
ros::Timer updateTimer
std::string frame_id
sensor_msgs::Imu imu_msg
bool param(const std::string &param_name, T &param_val, const T &default_val) const
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
void run(void)
LpmsSensorManagerI * manager
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSCPP_DECL void spin()
ros::Publisher imu_pub
~LpImuProxy(void)
ros::NodeHandle private_nh
Manages connection with the sensor, publishes data.
static Time now()
void update(const ros::TimerEvent &te)
ros::NodeHandle nh
sensor_msgs::MagneticField mag_msg
ros::Publisher mag_pub


lpms_imu
Author(s):
autogenerated on Sun May 3 2020 03:57:17