46 #define _WIN32_WINNT 0x0501 47 #pragma warning(disable: 4996) 48 #pragma warning(disable: 4267) 62 #include "sick_scan/rosconsole_simu.hpp" 66 #include <geometry_msgs/Pose2D.h> 68 #include "sensor_msgs/Imu.h" 70 #define _USE_MATH_DEFINES 77 #ifdef DEBUG_DUMP_ENABLED 128 bool isImuMsg =
false;
129 std::string szKeyWord =
"sEA InertialMeasurementUnit";
130 std::string cmpKeyWord =
"";
131 int keyWordLen = szKeyWord.length();
132 int posTrial[] = {0, 1, 8};
133 for (
int iPos = 0; iPos <
sizeof(posTrial) /
sizeof(posTrial[0]); iPos++)
135 if (datagram_length >= (keyWordLen + posTrial[iPos]))
138 for (
int i = 0; i < keyWordLen; i++)
140 cmpKeyWord += datagram[i + posTrial[iPos]];
143 if (szKeyWord.compare(cmpKeyWord) == 0)
166 bool isImuMsg =
false;
167 std::string szKeyWord =
"sSN InertialMeasurementUnit";
168 std::string cmpKeyWord =
"";
169 int keyWordLen = szKeyWord.length();
170 if (datagram_length >= (keyWordLen + 8))
172 for (
int i = 0; i < keyWordLen; i++)
174 cmpKeyWord += datagram[i + 8];
177 if (szKeyWord.compare(cmpKeyWord) == 0)
197 float tmpArr[13] = {0};
199 unsigned char *receiveBuffer = (
unsigned char *) datagram;
205 unsigned char *bufPtr = (
unsigned char *) datagram;
206 #ifdef DEBUG_DUMP_TO_CONSOLE_ENABLED 209 memcpy(&timeStamp, receiveBuffer + 36 + 13 * 4, 8);
212 for (
int i = 0; i < 13; i++)
214 memcpy(&(tmpArr[i]), receiveBuffer + adrOffset, 4);
233 double angleVelMultiplier = 1.0;
263 bool isImuMsg =
false;
264 std::string szKeyWord =
"sSN InertialMeasurementUnit";
265 int keyWordLen = szKeyWord.length();
266 if (datagram_length >= keyWordLen)
270 ptr = strstr(datagram, szKeyWord.c_str());
273 int offset = ptr - datagram;
274 if ((offset == 0) || (offset == 1))
291 bool dumpData =
false;
292 int verboseLevel = 0;
296 int HEADER_FIELDS = 32;
301 std::vector<char *> fields;
302 fields.reserve(datagram_length / 2);
305 std::vector<char> datagram_copy_vec;
306 datagram_copy_vec.resize(datagram_length + 1);
307 char *datagram_copy = &(datagram_copy_vec[0]);
309 if (verboseLevel > 0)
311 ROS_WARN(
"Verbose LEVEL activated. Only for DEBUG.");
315 strncpy(datagram_copy, datagram, datagram_length);
316 datagram_copy[datagram_length] = 0;
320 cur_field = strtok(datagram,
" ");
322 while (cur_field != NULL)
324 fields.push_back(cur_field);
326 cur_field = strtok(NULL,
" ");
331 count = fields.size();
338 IMU_TOKEN_QUATERNION_W,
339 IMU_TOKEN_QUATERNION_X,
340 IMU_TOKEN_QUATERNION_Y,
341 IMU_TOKEN_QUATERNION_Z,
342 IMU_TOKEN_QUATERNION_ACCURACY,
343 IMU_TOKEN_ANGULAR_VELOCITY_X,
344 IMU_TOKEN_ANGULAR_VELOCITY_Y,
345 IMU_TOKEN_ANGULAR_VELOCITY_Z,
346 IMU_TOKEN_ANGULAR_VELOCITY_RELIABILITY,
347 IMU_TOKEN_LINEAR_ACCELERATION_X,
348 IMU_TOKEN_LINEAR_ACCELERATION_Y,
349 IMU_TOKEN_LINEAR_ACCELERATION_Z,
350 IMU_TOKEN_LINEAR_ACCELERATION_RELIABILITY,
353 for (
int i = 0; i < IMU_TOKEN_NUM; i++)
357 unsigned long int uliDummy;
358 uliDummy = strtoul(fields[i], NULL, 16);
362 case IMU_TOKEN_TIMESTAMP:
365 case IMU_TOKEN_QUATERNION_X:
366 memcpy(&floatDummy, &uliDummy,
sizeof(
float));
369 case IMU_TOKEN_QUATERNION_Y:
370 memcpy(&floatDummy, &uliDummy,
sizeof(
float));
373 case IMU_TOKEN_QUATERNION_Z:
374 memcpy(&floatDummy, &uliDummy,
sizeof(
float));
377 case IMU_TOKEN_QUATERNION_W:
378 memcpy(&floatDummy, &uliDummy,
sizeof(
float));
382 case IMU_TOKEN_QUATERNION_ACCURACY:
383 memcpy(&floatDummy, &uliDummy,
sizeof(
float));
386 case IMU_TOKEN_ANGULAR_VELOCITY_X:
387 memcpy(&floatDummy, &uliDummy,
sizeof(
float));
390 case IMU_TOKEN_ANGULAR_VELOCITY_Y:
391 memcpy(&floatDummy, &uliDummy,
sizeof(
float));
394 case IMU_TOKEN_ANGULAR_VELOCITY_Z:
395 memcpy(&floatDummy, &uliDummy,
sizeof(
float));
398 case IMU_TOKEN_ANGULAR_VELOCITY_RELIABILITY:
399 uiValue = (
UINT16) (0xFFFF & uliDummy);
403 case IMU_TOKEN_LINEAR_ACCELERATION_X:
404 memcpy(&floatDummy, &uliDummy,
sizeof(
float));
407 case IMU_TOKEN_LINEAR_ACCELERATION_Y:
408 memcpy(&floatDummy, &uliDummy,
sizeof(
float));
411 case IMU_TOKEN_LINEAR_ACCELERATION_Z:
412 memcpy(&floatDummy, &uliDummy,
sizeof(
float));
415 case IMU_TOKEN_LINEAR_ACCELERATION_RELIABILITY:
416 uiValue = (
UINT16) (0xFFFF & uliDummy);
433 std::string imuTestStr =
"sSN IMUData 34FEEDF 3F7FF800 BBBC0000 3C848000 00000000 00000000 00000000 3B0B9AB1 00000000 3 BE9F6AD9 BDDCBB53 411D2CF1 0";
434 const char imuTestBinStr[] =
457 "\x02\x02\x02\x02\x00\x00\x00\x58" 458 "\x73\x53\x4e\x20\x49\x6e\x65\x72\x74\x69\x61\x6c\x4d\x65" 459 "\x61\x73\x75\x72\x65\x6d\x65\x6e\x74\x55\x6e\x69\x74\x20\xbe\xa4" 460 "\xe1\x1c\x3b\x6b\x5d\xe5\x41\x1c\x6e\xad\xbb\x0b\xa1\x6f\xbb\x0b" 461 "\xa1\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 462 "\x00\x00\x3f\x7f\xec\x00\x3a\x60\x00\x00\x3c\xcd\x00\x00\x39\xa0" 463 "\x00\x00\x00\x00\x00\x02\x1c\x7e\x6c\x01\x20";
465 char *datagramPtr = (
char *) imuTestStr.c_str();
466 int datagramLen = imuTestStr.size();
473 datagramPtr = (
char *) imuTestBinStr;
474 datagramLen =
sizeof(imuTestBinStr) /
sizeof(imuTestBinStr[0]);
484 bool useBinaryProtocol)
489 sensor_msgs::Imu imuMsg_;
492 static double lastRoll = 0.0;
493 static double lastPitch = 0.0;
494 static double lastYaw = 0.0;
496 static bool firstTime =
true;
526 if (useBinaryProtocol)
545 imuMsg_.header.stamp = timeStamp;
546 imuMsg_.header.seq = 0;
555 imuMsg_.orientation_covariance[0] = 1.0;
558 imuMsg_.orientation.x,
559 imuMsg_.orientation.y,
560 imuMsg_.orientation.z,
561 imuMsg_.orientation.w);
563 double roll, pitch, yaw;
564 m.
getRPY(roll, pitch, yaw);
572 lastTimeStamp = timeStamp;
578 #ifdef DEBUG_DUMP_ENABLED 600 double timeDiff = timeDiffRos.
toSec();
603 double angleDiffX = roll - lastRoll;
604 double angleDiffY = pitch - lastPitch;
605 double angleDiffZ = yaw - lastYaw;
609 double angleAngleApproxX = angleDiffX / timeDiff;
610 double angleAngleApproxY = angleDiffY / timeDiff;
611 double angleAngleApproxZ = angleDiffZ / timeDiff;
613 imuMsg_.angular_velocity.x = angleAngleApproxX;
614 imuMsg_.angular_velocity.y = angleAngleApproxY;
615 imuMsg_.angular_velocity.z = angleAngleApproxZ;
619 lastTimeStamp = timeStamp;
634 for (
int i = 0; i < 9; i++)
636 imuMsg_.angular_velocity_covariance[i] = 0.00;
637 imuMsg_.linear_acceleration_covariance[i] = 0.00;
638 imuMsg_.orientation_covariance[i] = 0.00;
644 imuMsg_.angular_velocity_covariance[0] = 0.02;
645 imuMsg_.angular_velocity_covariance[1] = 0;
646 imuMsg_.angular_velocity_covariance[2] = 0;
647 imuMsg_.angular_velocity_covariance[3] = 0;
648 imuMsg_.angular_velocity_covariance[4] = 0.02;
649 imuMsg_.angular_velocity_covariance[5] = 0;
650 imuMsg_.angular_velocity_covariance[6] = 0;
651 imuMsg_.angular_velocity_covariance[7] = 0;
652 imuMsg_.angular_velocity_covariance[8] = 0.02;
654 imuMsg_.linear_acceleration_covariance[0] = 0.04;
655 imuMsg_.linear_acceleration_covariance[1] = 0;
656 imuMsg_.linear_acceleration_covariance[2] = 0;
657 imuMsg_.linear_acceleration_covariance[3] = 0;
658 imuMsg_.linear_acceleration_covariance[4] = 0.04;
659 imuMsg_.linear_acceleration_covariance[5] = 0;
660 imuMsg_.linear_acceleration_covariance[6] = 0;
661 imuMsg_.linear_acceleration_covariance[7] = 0;
662 imuMsg_.linear_acceleration_covariance[8] = 0.04;
664 imuMsg_.orientation_covariance[0] = 0.0025;
665 imuMsg_.orientation_covariance[1] = 0;
666 imuMsg_.orientation_covariance[2] = 0;
667 imuMsg_.orientation_covariance[3] = 0;
668 imuMsg_.orientation_covariance[4] = 0.0025;
669 imuMsg_.orientation_covariance[5] = 0;
670 imuMsg_.orientation_covariance[6] = 0;
671 imuMsg_.orientation_covariance[7] = 0;
672 imuMsg_.orientation_covariance[8] = 0.0025;
676 imuMsg_.angular_velocity_covariance[0] = 0;
677 imuMsg_.angular_velocity_covariance[1] = 0;
678 imuMsg_.angular_velocity_covariance[2] = 0;
679 imuMsg_.angular_velocity_covariance[3] = 0;
680 imuMsg_.angular_velocity_covariance[4] = 0;
681 imuMsg_.angular_velocity_covariance[5] = 0;
682 imuMsg_.angular_velocity_covariance[6] = 0;
683 imuMsg_.angular_velocity_covariance[7] = 0;
684 imuMsg_.angular_velocity_covariance[8] = 0;
686 imuMsg_.linear_acceleration_covariance[0] = 0;
687 imuMsg_.linear_acceleration_covariance[1] = 0;
688 imuMsg_.linear_acceleration_covariance[2] = 0;
689 imuMsg_.linear_acceleration_covariance[3] = 0;
690 imuMsg_.linear_acceleration_covariance[4] = 0;
691 imuMsg_.linear_acceleration_covariance[5] = 0;
692 imuMsg_.linear_acceleration_covariance[6] = 0;
693 imuMsg_.linear_acceleration_covariance[7] = 0;
694 imuMsg_.linear_acceleration_covariance[8] = 0;
696 imuMsg_.orientation_covariance[0] = -1;
697 imuMsg_.orientation_covariance[1] = 0;
698 imuMsg_.orientation_covariance[2] = 0;
699 imuMsg_.orientation_covariance[3] = 0;
700 imuMsg_.orientation_covariance[4] = 0;
701 imuMsg_.orientation_covariance[5] = 0;
702 imuMsg_.orientation_covariance[6] = 0;
703 imuMsg_.orientation_covariance[7] = 0;
704 imuMsg_.orientation_covariance[8] = 0;
706 imuMsg_.orientation.x = 0;
707 imuMsg_.orientation.y = 0;
708 imuMsg_.orientation.z = 0;
709 imuMsg_.orientation.w = 0;
static void imuParserTest()
bool isImuDatagram(char *datagram, size_t datagram_length)
UINT16 LinearAccelerationReliability() const
void publish(const boost::shared_ptr< M > &message) const
int pushData(double timeStamp, std::string info, double val)
static SoftwarePLL & instance()
bool isImuAckDatagram(char *datagram, size_t datagram_length)
float AngularVelocityZ() const
float LinearAccelerationY() const
SickScanCommon * commonPtr
int parseAsciiDatagram(char *datagram, size_t datagram_length, SickScanImuValue *imValuePtr)
Parsing Ascii datagram.
float AngularVelocityX() const
bool isImuBinaryDatagram(char *datagram, size_t datagram_length)
Checking ASCII diagram for imu message type.
void swap_endian(unsigned char *ptr, int numBytes)
Universal swapping function.
int parseDatagram(ros::Time timeStamp, unsigned char *receiveBuffer, int actual_length, bool useBinaryProtocol)
float QuaternionAccuracy() const
bool getCorrectedTimeStamp(uint32_t &sec, uint32_t &nanoSec, uint32_t tick)
float QuaternionY() const
void getRPY(tfScalar &roll, tfScalar &pitch, tfScalar &yaw, unsigned int solution_number=1) const
float LinearAccelerationZ() const
ros::Publisher imuScan_pub_
bool isImuAsciiDatagram(char *datagram, size_t datagram_length)
Checking ASCII diagram for imu message type.
float AngularVelocityY() const
float QuaternionZ() const
static DataDumper & instance()
float LinearAccelerationX() const
float QuaternionW() const
UINT16 AngularVelocityReliability() const
int parseBinaryDatagram(char *datagram, size_t datagram_length, SickScanImuValue *imValuePtr)
Parsing Ascii datagram.
float QuaternionX() const
int dumpUcharBufferToConsole(unsigned char *buffer, int bufLen)
double simpleFmodTwoPi(double angle)
Checking angle to be in the interval [-M_PI,M_PI] Of course you can also use fmod, e.g. fmod(angle + M_PI,2*M_PI) - M_PI.