6 #include <sensor_msgs/Imu.h> 7 #include <sensor_msgs/MagneticField.h> 8 #include <sensor_msgs/FluidPressure.h> 9 #include <geometry_msgs/Vector3Stamped.h> 10 #include <geometry_msgs/QuaternionStamped.h> 12 #include <thormang3_imu_3dm_gx4/FilterOutput.h> 18 #define kEarthGravity (9.80665) 31 std::shared_ptr<diagnostic_updater::Updater>
updater;
32 std::shared_ptr<diagnostic_updater::TopicDiagnostic>
imuDiag;
33 std::shared_ptr<diagnostic_updater::TopicDiagnostic>
filterDiag;
37 sensor_msgs::MagneticField field;
38 sensor_msgs::FluidPressure pressure;
50 field.header.stamp = imu.header.stamp;
51 field.header.frame_id =
frameId;
52 pressure.header.stamp = imu.header.stamp;
53 pressure.header.frame_id =
frameId;
55 imu.orientation_covariance[0] =
62 imu.angular_velocity.x = data.
gyro[0];
63 imu.angular_velocity.y = data.
gyro[1];
64 imu.angular_velocity.z = data.
gyro[2];
66 field.magnetic_field.x = data.
mag[0];
67 field.magnetic_field.y = data.
mag[1];
68 field.magnetic_field.z = data.
mag[2];
70 pressure.fluid_pressure = data.
pressure;
77 imuDiag->tick(imu.header.stamp);
87 thormang3_imu_3dm_gx4::FilterOutput output;
89 output.header.frame_id =
frameId;
98 output.bias.x = data.
bias[0];
99 output.bias.y = data.
bias[1];
100 output.bias.z = data.
bias[2];
125 const std::string& name,
double * target) {
126 std::shared_ptr<diagnostic_updater::TopicDiagnostic> diag;
127 const double period = 1.0 / *target;
141 std::map<std::string,std::string> map = info.
toMap();
142 for (
const std::pair<std::string,std::string>& p : map) {
143 stat.
add(p.first, p.second);
150 auto map = fields.
toMap();
151 for (
const std::pair<std::string, unsigned int>& p : map) {
152 stat.
add(p.first, p.second);
154 stat.
summary(diagnostic_msgs::DiagnosticStatus::OK,
"Read diagnostic info.");
156 catch (std::exception& e) {
157 const std::string message = std::string(
"Failed: ") + e.what();
158 stat.
summary(diagnostic_msgs::DiagnosticStatus::ERROR, message);
162 int main(
int argc,
char **argv) {
169 bool enableMagUpdate, enableAccelUpdate;
170 int requestedImuRate, requestedFilterRate;
174 nh.
param<std::string>(
"device", device,
"/dev/ttyACM0");
175 nh.
param<
int>(
"baudrate", baudrate, 115200);
176 nh.
param<std::string>(
"frameId",
frameId, std::string(
"imu"));
177 nh.
param<
int>(
"imu_rate", requestedImuRate, 100);
178 nh.
param<
int>(
"filter_rate", requestedFilterRate, 100);
179 nh.
param<
bool>(
"enable_filter", enableFilter,
false);
180 nh.
param<
bool>(
"enable_mag_update", enableMagUpdate,
false);
181 nh.
param<
bool>(
"enable_accel_update", enableAccelUpdate,
true);
182 nh.
param<
bool>(
"verbose", verbose,
false);
184 if (requestedFilterRate < 0 || requestedImuRate < 0) {
185 ROS_ERROR(
"imu_rate and filter_rate must be > 0");
189 pubIMU = nh.
advertise<sensor_msgs::Imu>(
"imu", 1);
190 pubMag = nh.
advertise<sensor_msgs::MagneticField>(
"magnetic_field", 1);
191 pubPressure = nh.
advertise<sensor_msgs::FluidPressure>(
"pressure", 1);
194 pubFilter = nh.
advertise<thormang3_imu_3dm_gx4::FilterOutput>(
"filter", 1);
198 Imu imu(device, verbose);
202 ROS_INFO(
"Selecting baud rate %u", baudrate);
203 imu.selectBaudRate(baudrate);
206 imu.getDeviceInfo(info);
207 std::map<std::string,std::string> map = info.
toMap();
208 for (
const std::pair<std::string,std::string>& p : map) {
209 ROS_INFO(
"\t%s: %s", p.first.c_str(), p.second.c_str());
216 uint16_t imuBaseRate, filterBaseRate;
217 imu.getIMUDataBaseRate(imuBaseRate);
218 ROS_INFO(
"IMU data base rate: %u Hz", imuBaseRate);
219 imu.getFilterDataBaseRate(filterBaseRate);
220 ROS_INFO(
"Filter data base rate: %u Hz", filterBaseRate);
223 if (static_cast<uint16_t>(requestedImuRate) > imuBaseRate) {
224 throw std::runtime_error(
"imu_rate cannot exceed " +
225 std::to_string(imuBaseRate));
227 if (static_cast<uint16_t>(requestedFilterRate) > filterBaseRate) {
228 throw std::runtime_error(
"filter_rate cannot exceed " +
229 std::to_string(filterBaseRate));
232 const uint16_t imuDecimation = imuBaseRate / requestedImuRate;
233 const uint16_t filterDecimation = filterBaseRate / requestedFilterRate;
235 ROS_INFO(
"Selecting IMU decimation: %u", imuDecimation);
242 ROS_INFO(
"Selecting filter decimation: %u", filterDecimation);
248 ROS_INFO(
"Enabling IMU data stream");
249 imu.enableIMUStream(
true);
252 ROS_INFO(
"Enabling filter data stream");
253 imu.enableFilterStream(
true);
255 ROS_INFO(
"Enabling filter measurements");
256 imu.enableMeasurements(enableAccelUpdate, enableMagUpdate);
258 ROS_INFO(
"Enabling gyro bias estimation");
259 imu.enableBiasEstimation(
true);
261 ROS_INFO(
"Disabling filter data stream");
262 imu.enableFilterStream(
false);
268 if (!nh.
hasParam(
"diagnostic_period")) {
269 nh.
setParam(
"diagnostic_period", 0.2);
277 double imuRate = imuBaseRate / (1.0 * imuDecimation);
278 double filterRate = filterBaseRate / (1.0 * filterDecimation);
284 updater->add(
"diagnostic_info",
287 ROS_INFO(
"Resuming the device");
302 catch (std::exception &e) {
void publishData(const Imu::IMUData &data)
std::map< std::string, std::string > toMap() const
Device options (range of the sensor)
std::shared_ptr< diagnostic_updater::TopicDiagnostic > configTopicDiagnostic(const std::string &name, double *target)
void publish(const boost::shared_ptr< M > &message) const
std::string modelNumber
Model name.
sensor_msgs::Imu imuFilterData
void summary(unsigned char lvl, const std::string s)
std::string modelName
Firmware version.
void updateDiagnosticInfo(diagnostic_updater::DiagnosticStatusWrapper &stat, imu_3dm_gx4::Imu *imu)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::map< std::string, unsigned int > toMap() const
Convert to map of human readable strings and integers.
int main(int argc, char **argv)
io_error Generated when a low-level IO command fails.
DiagnosticFields struct (See 3DM documentation for these fields)
uint16_t biasUncertaintyStatus
uint16_t quaternionStatus
void getDiagnosticInfo(Imu::DiagnosticFields &fields)
getDiagnosticInfo Get diagnostic information from the IMU.
Imu::DiagnosticFields fields
FilterData Estimator readings produced by the sensor.
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
IMUData IMU readings produced by the sensor.
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
timeout_error Generated when read or write times out, usually indicates device hang up...
std::shared_ptr< diagnostic_updater::TopicDiagnostic > filterDiag
ros::Publisher pubPressure
std::shared_ptr< diagnostic_updater::TopicDiagnostic > imuDiag
uint16_t angleUncertaintyStatus
void publishFilter(const Imu::FilterData &data)
Imu Interface to the Microstrain 3DM-GX4-25 IMU.
void add(const std::string &key, const T &val)
bool hasParam(const std::string &key) const
std::shared_ptr< diagnostic_updater::Updater > updater
Info Structure generated by the getDeviceInfo command.
float angleUncertainty[3]
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const