1
+ #include < boost/make_shared.hpp>
1
2
#include " phidgets_imu/imu_ros_i.h"
2
3
3
4
namespace phidgets {
4
5
5
6
ImuRosI::ImuRosI (ros::NodeHandle nh, ros::NodeHandle nh_private):
6
7
Imu (),
7
- nh_ (nh),
8
+ nh_ (nh),
8
9
nh_private_ (nh_private),
10
+ is_connected_ (false ),
11
+ error_number_ (0 ),
12
+ target_publish_freq_ (0.0 ),
9
13
initialized_ (false )
10
14
{
11
15
ROS_INFO (" Starting Phidgets IMU" );
@@ -45,13 +49,27 @@ ImuRosI::ImuRosI(ros::NodeHandle nh, ros::NodeHandle nh_private):
45
49
cal_publisher_ = nh_.advertise <std_msgs::Bool>(
46
50
" imu/is_calibrated" , 5 );
47
51
52
+ // Set up the topic publisher diagnostics monitor for imu/data_raw
53
+ // 1. The frequency status component monitors if imu data is published
54
+ // within 10% tolerance of the desired frequency of 1.0 / period
55
+ // 2. The timstamp status component monitors the delay between
56
+ // the header.stamp of the imu message and the real (ros) time
57
+ // the maximum tolerable drift is +- 100ms
58
+ target_publish_freq_ = 1000.0 / static_cast <double >(period_);
59
+ imu_publisher_diag_ptr_ = boost::make_shared<diagnostic_updater::TopicDiagnostic>(
60
+ " imu/data_raw" ,
61
+ boost::ref (diag_updater_),
62
+ diagnostic_updater::FrequencyStatusParam (&target_publish_freq_, &target_publish_freq_, 0.1 , 5 ),
63
+ diagnostic_updater::TimeStampStatusParam (-0.1 , 0.1 )
64
+ );
65
+
48
66
// **** advertise services
49
67
50
68
cal_srv_ = nh_.advertiseService (
51
69
" imu/calibrate" , &ImuRosI::calibrateService, this );
52
70
53
71
// **** initialize variables and device
54
-
72
+
55
73
imu_msg_.header .frame_id = frame_id_;
56
74
57
75
// build covariance matrices
@@ -79,6 +97,10 @@ ImuRosI::ImuRosI(ros::NodeHandle nh, ros::NodeHandle nh_private):
79
97
// signal that we have no orientation estimate (see Imu.msg)
80
98
imu_msg_.orientation_covariance [0 ] = -1 ;
81
99
100
+ // init diagnostics, we set the hardware id properly when the device is connected
101
+ diag_updater_.setHardwareID (" none" );
102
+ diag_updater_.add (" IMU Driver Status" , this , &phidgets::ImuRosI::phidgetsDiagnostics);
103
+
82
104
initDevice ();
83
105
84
106
if (has_compass_params)
@@ -108,7 +130,10 @@ void ImuRosI::initDevice()
108
130
int result = waitForAttachment (10000 );
109
131
if (result)
110
132
{
111
- const char *err;
133
+ is_connected_ = false ;
134
+ error_number_ = result;
135
+ diag_updater_.force_update ();
136
+ const char *err;
112
137
CPhidget_getErrorDescription (result, &err);
113
138
ROS_FATAL (" Problem waiting for IMU attachment: %s Make sure the USB cable is connected and you have executed the phidgets_api/share/setup-udev.sh script." , err);
114
139
}
@@ -118,6 +143,11 @@ void ImuRosI::initDevice()
118
143
119
144
// calibrate on startup
120
145
calibrate ();
146
+
147
+ // set the hardware id for diagnostics
148
+ diag_updater_.setHardwareIDf (" %s-%d" ,
149
+ getDeviceName ().c_str (),
150
+ getDeviceSerialNumber ());
121
151
}
122
152
123
153
bool ImuRosI::calibrateService (std_srvs::Empty::Request &req,
@@ -144,7 +174,7 @@ void ImuRosI::calibrate()
144
174
void ImuRosI::processImuData (CPhidgetSpatial_SpatialEventDataHandle* data, int i)
145
175
{
146
176
// **** calculate time from timestamp
147
- ros::Duration time_imu (data[i]->timestamp .seconds +
177
+ ros::Duration time_imu (data[i]->timestamp .seconds +
148
178
data[i]->timestamp .microseconds * 1e-6 );
149
179
150
180
ros::Time time_now = time_zero_ + time_imu;
@@ -159,14 +189,14 @@ void ImuRosI::processImuData(CPhidgetSpatial_SpatialEventDataHandle* data, int i
159
189
// **** initialize if needed
160
190
161
191
if (!initialized_)
162
- {
192
+ {
163
193
last_imu_time_ = time_now;
164
194
initialized_ = true ;
165
195
}
166
196
167
197
// **** create and publish imu message
168
198
169
- boost::shared_ptr<ImuMsg> imu_msg =
199
+ boost::shared_ptr<ImuMsg> imu_msg =
170
200
boost::make_shared<ImuMsg>(imu_msg_);
171
201
172
202
imu_msg->header .stamp = time_now;
@@ -182,12 +212,13 @@ void ImuRosI::processImuData(CPhidgetSpatial_SpatialEventDataHandle* data, int i
182
212
imu_msg->angular_velocity .z = data[i]->angularRate [2 ] * (M_PI / 180.0 );
183
213
184
214
imu_publisher_.publish (imu_msg);
215
+ imu_publisher_diag_ptr_->tick (time_now);
185
216
186
217
// **** create and publish magnetic field message
187
218
188
- boost::shared_ptr<MagMsg> mag_msg =
219
+ boost::shared_ptr<MagMsg> mag_msg =
189
220
boost::make_shared<MagMsg>();
190
-
221
+
191
222
mag_msg->header .frame_id = frame_id_;
192
223
mag_msg->header .stamp = time_now;
193
224
@@ -205,8 +236,11 @@ void ImuRosI::processImuData(CPhidgetSpatial_SpatialEventDataHandle* data, int i
205
236
mag_msg->vector .y = nan;
206
237
mag_msg->vector .z = nan;
207
238
}
208
-
239
+
209
240
mag_publisher_.publish (mag_msg);
241
+
242
+ // diagnostics
243
+ diag_updater_.update ();
210
244
}
211
245
212
246
void ImuRosI::dataHandler (CPhidgetSpatial_SpatialEventDataHandle *data, int count)
@@ -215,5 +249,51 @@ void ImuRosI::dataHandler(CPhidgetSpatial_SpatialEventDataHandle *data, int coun
215
249
processImuData (data, i);
216
250
}
217
251
252
+ // Added for diagnostics
253
+ void ImuRosI::attachHandler ()
254
+ {
255
+ Imu::attachHandler ();
256
+ is_connected_ = true ;
257
+ // Reset error number to no error if the prev error was disconnect
258
+ if (error_number_ == 13 ) error_number_ = 0 ;
259
+ diag_updater_.force_update ();
260
+ }
261
+
262
+ void ImuRosI::detachHandler ()
263
+ {
264
+ Imu::detachHandler ();
265
+ is_connected_ = false ;
266
+ diag_updater_.force_update ();
267
+ }
268
+
269
+ void ImuRosI::errorHandler (int error)
270
+ {
271
+ Imu::errorHandler (error);
272
+ error_number_ = error;
273
+ diag_updater_.force_update ();
274
+ }
275
+
276
+ void ImuRosI::phidgetsDiagnostics (diagnostic_updater::DiagnosticStatusWrapper &stat)
277
+ {
278
+ if (is_connected_)
279
+ {
280
+ stat.summary (diagnostic_msgs::DiagnosticStatus::OK, " The Phidget is connected." );
281
+ stat.add (" Device Serial Number" , getDeviceSerialNumber ());
282
+ stat.add (" Device Name" , getDeviceName ());
283
+ stat.add (" Device Type" , getDeviceType ());
284
+ }
285
+ else
286
+ {
287
+ stat.summary (diagnostic_msgs::DiagnosticStatus::ERROR, " The Phidget is not connected. Check the USB." );
288
+ }
289
+
290
+ if (error_number_ != 0 )
291
+ {
292
+ stat.summary (diagnostic_msgs::DiagnosticStatus::ERROR, " The Phidget reports error." );
293
+ stat.add (" Error Number" , error_number_);
294
+ stat.add (" Error message" , getErrorDescription (error_number_));
295
+ }
296
+ }
297
+
218
298
} // namespace phidgets
219
299
0 commit comments