52 #include <geometry_msgs/Vector3Stamped.h>
54 #include <sensor_msgs/Imu.h>
55 #include <sensor_msgs/Temperature.h>
79 ROS_INFO(
"Initializing HCL layer...");
82 "Error: could not initialize the Seiko Epson HCL layer. Exiting...");
85 std::cout <<
"...done." << std::endl;
87 ROS_INFO(
"Initializing GPIO interface...");
89 ROS_ERROR(
"Error: could not initialize the GPIO layer. Exiting...");
93 std::cout <<
"...done." << std::endl;
95 ROS_INFO(
"Initializing SPI interface...");
98 ROS_ERROR(
"Error: could not initialize SPI interface. Exiting...");
103 std::cout <<
"...done." << std::endl;
108 std::cout <<
"...done." << std::endl;
110 ROS_INFO(
"Checking sensor NOT_READY status...");
112 ROS_ERROR(
"Error: failed to power on Sensor. Exiting...");
118 std::cout <<
"...done." << std::endl;
120 ROS_INFO(
"Detecting sensor model...");
122 ROS_ERROR(
"Error: failed to detect sensor model. Exiting...");
125 std::cout <<
"...done." << std::endl;
129 ROS_ERROR(
"Error: could not initialize Epson Sensor. Exiting...");
135 std::cout <<
"...done." << std::endl;
137 ROS_INFO(
"Epson IMU initialized.\n");
156 const int64_t ONE_SEC_NSEC = 1000000000;
157 const int64_t HALF_SEC_NSEC = 500000000;
159 const int64_t GEN2_MAX = 1398080000;
161 const int64_t GEN3_MAX = 1048560000;
183 max_count = GEN3_MAX;
184 almost_rollover = max_count;
188 time_sec_current = 0;
190 time_nsec_current = 0;
191 count_corrected_old = 0;
193 flag_imu_lead =
false;
210 max_count = (is_gen2_imu) ? GEN2_MAX : GEN3_MAX;
227 almost_rollover = max_count * 0.96;
229 count_diff = count - count_old;
230 if (count > almost_rollover) {
232 }
else if (count_diff < 0) {
234 count_diff = count + (max_count - count_old);
236 "Warning: time_correction enabled but IMU reset counter "
237 "rollover detected. If 1PPS not connected to IMU GPIO2/EXT "
238 "pin, disable time_correction.");
245 count_corrected = (count_corrected + count_diff) % ONE_SEC_NSEC;
246 if ((time_sec_current != time_sec_old) && (count_corrected > HALF_SEC_NSEC)) {
247 time_sec_current = time_sec_current - 1;
248 }
else if (((count_corrected - count_corrected_old) < 0) &&
249 (time_nsec_current > HALF_SEC_NSEC)) {
250 time_sec_current = time_sec_current + 1;
251 flag_imu_lead =
true;
252 }
else if ((flag_imu_lead) && (time_nsec_current > HALF_SEC_NSEC)) {
253 time_sec_current = time_sec_current + 1;
255 flag_imu_lead =
false;
258 time.
nsec = count_corrected;
259 time.
sec = time_sec_current;
260 time_sec_old = time_sec_current;
262 count_corrected_old = count_corrected;
271 int main(
int argc,
char** argv) {
272 ros::init(argc, argv,
"ess_imu_driver_node");
276 setvbuf(stdout,
nullptr, _IONBF, BUFSIZ);
281 std::string frame_id =
"imu_link";
282 std::string imu_topic =
"epson_imu";
283 std::string temperature_topic =
"epson_tempc";
297 sensor_msgs::Temperature tempc_msg;
298 sensor_msgs::Imu imu_msg;
300 int time_correction =
false;
328 np.
param(
"time_correction", time_correction, 0);
330 if (!
init_imu(&epson_sensor, &epson_options))
return -1;
334 imu_topic = (
static_cast<bool>(epson_options.
qtn_out) ==
false)
335 ?
"/epson_imu/data_raw"
339 if (time_correction) {
344 nh.
advertise<sensor_msgs::Temperature>(temperature_topic, 1);
346 for (
int i = 0; i < 9; i++) {
347 imu_msg.orientation_covariance[i] = 0;
348 imu_msg.angular_velocity_covariance[i] = 0;
349 imu_msg.linear_acceleration_covariance[i] = 0;
351 imu_msg.orientation_covariance[0] = -1;
360 imu_msg.header.frame_id = frame_id;
361 if (!time_correction)
365 imu_msg.angular_velocity.x = epson_data.
gyro_x;
366 imu_msg.angular_velocity.y = epson_data.
gyro_y;
367 imu_msg.angular_velocity.z = epson_data.
gyro_z;
368 imu_msg.linear_acceleration.x = epson_data.
accel_x;
369 imu_msg.linear_acceleration.y = epson_data.
accel_y;
370 imu_msg.linear_acceleration.z = epson_data.
accel_z;
373 imu_msg.orientation.x = epson_data.
qtn1;
374 imu_msg.orientation.y = epson_data.
qtn2;
375 imu_msg.orientation.z = epson_data.
qtn3;
376 imu_msg.orientation.w = epson_data.
qtn0;
380 tempc_msg.header = imu_msg.header;
386 "Warning: Checksum error or incorrect delimiter bytes in imu_msg "