7 #if defined(SEGWAYRMP_USE_SERIAL) 11 #if !HAS_CLOCK_GETTIME 12 # include <sys/time.h> 18 std::cout <<
"Segway Status:" << std::endl << std::endl
19 << segway_status->str() << std::endl << std::endl;
24 std::cerr <<
"SegwayRMP Debug: " << msg << std::endl;
29 std::cerr <<
"SegwayRMP Info: " << msg << std::endl;
34 std::cerr <<
"SegwayRMP Error: " << msg << std::endl;
41 throw(segwayrmp::NoHighPerformanceTimersException)
46 # if HAS_CLOCK_GETTIME 48 clock_gettime(CLOCK_REALTIME, &start);
49 st.
sec = start.tv_sec;
50 st.
nsec = start.tv_nsec;
52 struct timeval timeofday;
53 gettimeofday(&timeofday, NULL);
54 st.
sec = timeofday.tv_sec;
55 st.
nsec = timeofday.tv_usec * 1000;
69 static LARGE_INTEGER cpu_freq, init_cpu_time;
70 uint32_t start_sec = 0;
71 uint32_t start_nsec = 0;
72 if ( ( start_sec == 0 ) && ( start_nsec == 0 ) ) {
73 QueryPerformanceFrequency(&cpu_freq);
74 if (cpu_freq.QuadPart == 0) {
75 throw segwayrmp::NoHighPerformanceTimersException();
77 QueryPerformanceCounter(&init_cpu_time);
81 GetSystemTimeAsFileTime(&ft);
82 LARGE_INTEGER start_li;
83 start_li.LowPart = ft.dwLowDateTime;
84 start_li.HighPart = ft.dwHighDateTime;
88 start_li.QuadPart -= 116444736000000000Ui64;
90 start_li.QuadPart -= 116444736000000000ULL;
93 start_sec = (uint32_t)(start_li.QuadPart / 10000000);
94 start_nsec = (start_li.LowPart % 10000000) * 100;
96 LARGE_INTEGER cur_time;
97 QueryPerformanceCounter(&cur_time);
98 LARGE_INTEGER delta_cpu_time;
99 delta_cpu_time.QuadPart = cur_time.QuadPart - init_cpu_time.QuadPart;
103 double d_delta_cpu_time =
104 delta_cpu_time.QuadPart / (double) cpu_freq.QuadPart;
105 uint32_t delta_sec = (uint32_t) floor(d_delta_cpu_time);
106 uint32_t delta_nsec =
107 (uint32_t) boost::math::round((d_delta_cpu_time - delta_sec) * 1e9);
109 int64_t sec_sum = (int64_t)start_sec + (int64_t)delta_sec;
110 int64_t nsec_sum = (int64_t)start_nsec + (int64_t)delta_nsec;
113 normalizeSecNSecUnsigned(sec_sum, nsec_sum);
123 std::cerr <<
"SegwayRMP Unhandled Exception: " << error.what()
129 for (
int i = 0; i < length; ++i) {
130 printf(
"0x%.2X ", (
unsigned)(
unsigned char)data[i]);
137 printHex(const_cast<char *>(str.c_str()), str.length());
143 : timestamp(
SegwayTime(0, 0)), pitch(0.0f), pitch_rate(0.0f), roll(0.0f),
144 roll_rate(0.0f), left_wheel_speed(0.0f), right_wheel_speed(0.0f),
145 yaw_rate(0.0f), servo_frames(0.0f), integrated_left_wheel_position(0.0f),
146 integrated_right_wheel_position(0.0f), integrated_forward_position(0.0f),
147 integrated_turn_position(0.0f), left_motor_torque(0.0f),
148 right_motor_torque(0.0f), ui_battery_voltage(0.0f),
149 powerbase_battery_voltage(0.0f), commanded_velocity(0.0f),
150 commanded_yaw_rate(0.0f), operational_mode(
disabled),
151 controller_gain_schedule(
light), motor_status(0), touched(false)
156 std::stringstream ss;
167 <<
"\nIntegrated Right Wheel Position: " 175 <<
"\nOperational Mode: ";
193 ss <<
"\nController Gain Schedule: ";
210 <<
"\nMotor Status: ";
212 ss <<
"Motors Enabled";
221 : interface_type_(
no_interface), segway_rmp_type_(segway_rmp_type),
223 continuously_reading_(false),
233 switch (interface_type) {
235 RMP_THROW_MSG(ConfigurationException,
"CAN is not supported currently");
241 #if defined(SEGWAYRMP_USE_SERIAL) 244 RMP_THROW_MSG(ConfigurationException,
"Library is not built with Serial " 249 RMP_THROW_MSG(ConfigurationException,
"Ethernet is not currently " 256 RMP_THROW_MSG(ConfigurationException,
"Invalid InterfaceType specified");
270 #if defined(SEGWAYRMP_USE_SERIAL) 283 #if SEGWAYRMP_USE_SERIAL 288 RMP_THROW_MSG(ConfigurationException,
"configureSerial: Cannot configure " 289 "serial when the InterfaceType is not serial.");
292 RMP_THROW_MSG(ConfigurationException,
"configureSerial: The segwayrmp " 293 "library is not build with serial support, not implemented.");
303 RMP_THROW_MSG(ConfigurationException,
"configureUSBBySerial: Cannot " 304 "configure ftd2xx usb when the InterfaceType is not usb.");
315 RMP_THROW_MSG(ConfigurationException,
"configureUSBByDescription: " 316 "Cannot configure ftd2xx usb when the InterfaceType is not usb.");
326 RMP_THROW_MSG(ConfigurationException,
"configureUSBByIndex: " 327 "Cannot configure ftd2xx usb when the InterfaceType is not usb.");
338 if (reset_integrators) {
352 RMP_THROW_MSG(ConfigurationException,
"Cannot send shutdown: " 360 }
catch (std::exception &e) {
361 std::stringstream ss;
362 ss <<
"Cannot send shutdown: " << e.what();
373 short int lc = linear_counts;
374 short int ac = angular_counts;
379 packet.
data[0] = (
unsigned char)((lc & 0xFF00) >> 8);
380 packet.
data[1] = (
unsigned char)(lc & 0x00FF);
381 packet.
data[2] = (
unsigned char)((ac & 0xFF00) >> 8);
382 packet.
data[3] = (
unsigned char)(ac & 0x00FF);
383 packet.
data[4] = 0x00;
384 packet.
data[5] = 0x00;
385 packet.
data[6] = 0x00;
386 packet.
data[7] = 0x00;
389 }
catch (std::exception &e) {
400 short int lv = (
short int)(linear_velocity * this->
mps_to_counts_);
401 short int av = (
short int)(angular_velocity * this->
dps_to_counts_);
407 packet.
data[0] = (
unsigned char)((lv & 0xFF00) >> 8);
408 packet.
data[1] = (
unsigned char)(lv & 0x00FF);
409 packet.
data[2] = (
unsigned char)((av & 0xFF00) >> 8);
410 packet.
data[3] = (
unsigned char)(av & 0x00FF);
411 packet.
data[4] = 0x00;
412 packet.
data[5] = 0x00;
413 packet.
data[6] = 0x00;
414 packet.
data[7] = 0x00;
417 }
catch (std::exception &e) {
426 RMP_THROW_MSG(ConfigurationException,
"Cannot set operational mode: " 433 packet.
data[0] = 0x00;
434 packet.
data[1] = 0x00;
435 packet.
data[2] = 0x00;
436 packet.
data[3] = 0x00;
437 packet.
data[4] = 0x00;
438 packet.
data[5] = 0x10;
439 packet.
data[6] = 0x00;
440 packet.
data[7] = (
unsigned char)operational_mode;
448 }
catch (std::exception &e) {
449 std::stringstream ss;
450 ss <<
"Cannot set operational mode: " << e.what();
460 RMP_THROW_MSG(ConfigurationException,
"Cannot set controller gain " 461 "schedule: Not Connected.");
467 packet.
data[0] = 0x00;
468 packet.
data[1] = 0x00;
469 packet.
data[2] = 0x00;
470 packet.
data[3] = 0x00;
471 packet.
data[4] = 0x00;
472 packet.
data[5] = 0x0D;
473 packet.
data[6] = 0x00;
474 packet.
data[7] = (
unsigned char)controller_gain_schedule;
484 }
catch (std::exception &e) {
485 std::stringstream ss;
486 ss <<
"Cannot set controller gain schedule: " << e.what();
495 RMP_THROW_MSG(ConfigurationException,
"Cannot set balance mode lock: " 502 packet.
data[0] = 0x00;
503 packet.
data[1] = 0x00;
504 packet.
data[2] = 0x00;
505 packet.
data[3] = 0x00;
506 packet.
data[4] = 0x00;
507 packet.
data[5] = 0x0F;
508 packet.
data[6] = 0x00;
510 packet.
data[7] = 0x01;
512 packet.
data[7] = 0x00;
515 }
catch (std::exception &e) {
516 std::stringstream ss;
517 ss <<
"Cannot set balance mode lock: " << e.what();
526 RMP_THROW_MSG(ConfigurationException,
"Cannot reset Integrators: Not " 533 packet.
data[0] = 0x00;
534 packet.
data[1] = 0x00;
535 packet.
data[2] = 0x00;
536 packet.
data[3] = 0x00;
537 packet.
data[4] = 0x00;
538 packet.
data[5] = 0x32;
539 packet.
data[6] = 0x00;
540 packet.
data[7] = 0x01;
544 packet.
data[7] = 0x02;
548 packet.
data[7] = 0x04;
552 packet.
data[7] = 0x08;
556 }
catch (std::exception &e) {
557 std::stringstream ss;
558 ss <<
"Cannot reset Integrators: " << e.what();
567 RMP_THROW_MSG(ConfigurationException,
"Cannot set max velocity scale " 568 "factor: Not Connected.");
574 packet.
data[0] = 0x00;
575 packet.
data[1] = 0x00;
576 packet.
data[2] = 0x00;
577 packet.
data[3] = 0x00;
578 packet.
data[4] = 0x00;
579 packet.
data[5] = 0x0A;
580 packet.
data[6] = 0x00;
587 scalar = floor(scalar);
589 short int scalar_int = (
short int)scalar;
591 packet.
data[7] = (
unsigned char)(scalar_int & 0x00FF);
594 }
catch (std::exception &e) {
595 std::stringstream ss;
596 ss <<
"Cannot set max velocity scale factor: " << e.what();
605 RMP_THROW_MSG(ConfigurationException,
"Cannot set max acceleration scale " 606 "factor: Not Connected.");
612 packet.
data[0] = 0x00;
613 packet.
data[1] = 0x00;
614 packet.
data[2] = 0x00;
615 packet.
data[3] = 0x00;
616 packet.
data[4] = 0x00;
617 packet.
data[5] = 0x0B;
618 packet.
data[6] = 0x00;
625 scalar = floor(scalar);
627 short int scalar_int = (
short int)scalar;
629 packet.
data[7] = (
unsigned char)(scalar_int & 0x00FF);
632 }
catch (std::exception &e) {
633 std::stringstream ss;
634 ss <<
"Cannot set max acceleration scale factor: " << e.what();
643 RMP_THROW_MSG(ConfigurationException,
"Cannot set max turn scale factor: " 650 packet.
data[0] = 0x00;
651 packet.
data[1] = 0x00;
652 packet.
data[2] = 0x00;
653 packet.
data[3] = 0x00;
654 packet.
data[4] = 0x00;
655 packet.
data[5] = 0x0C;
656 packet.
data[6] = 0x00;
663 scalar = floor(scalar);
665 short int scalar_int = (
short int)scalar;
667 packet.
data[7] = (
unsigned char)(scalar_int & 0x00FF);
670 }
catch (std::exception &e) {
671 std::stringstream ss;
672 ss <<
"Cannot set max turn scale factor: " << e.what();
681 RMP_THROW_MSG(ConfigurationException,
"Cannot set current limit scale " 682 "factor: Not Connected.");
688 packet.
data[0] = 0x00;
689 packet.
data[1] = 0x00;
690 packet.
data[2] = 0x00;
691 packet.
data[3] = 0x00;
692 packet.
data[4] = 0x00;
693 packet.
data[5] = 0x0E;
694 packet.
data[6] = 0x00;
701 scalar = floor(scalar);
703 short int scalar_int = (
short int)scalar;
705 packet.
data[7] = (
unsigned char)(scalar_int & 0x00FF);
708 }
catch (std::exception &e) {
709 std::stringstream ss;
710 ss <<
"Cannot set current limit scale factor: " << e.what();
723 std::transform(log_level.begin(), log_level.end(),
724 log_level.begin(), ::tolower);
725 if (log_level ==
"debug") {
728 if (log_level ==
"info") {
729 this->
info_ = callback;
731 if (log_level ==
"error") {
750 }
catch (PacketRetrievalException &e) {
751 if (e.error_number() == 2)
752 this->
error_(
"Checksum mismatch...");
753 else if (e.error_number() == 3)
754 this->
error_(
"No data from Segway...");
771 }
catch (std::exception &e) {
810 RMP_THROW_MSG(ConfigurationException,
"Invalid Segway RMP Type");
814 inline short int getShortInt(
unsigned char high,
unsigned char low)
816 return (
short int)(((
unsigned short int)high << 8)
817 | (
unsigned short int)low);
821 getInt(
unsigned char lhigh,
unsigned char llow,
822 unsigned char hhigh,
unsigned char hlow)
825 char data[4] = {llow, lhigh, hlow, hhigh};
826 memcpy(&result, data, 4);
832 bool status_updated =
false;
834 return status_updated;
851 ss_ptr->touched =
true;
860 ss_ptr->servo_frames = (
861 (((
short unsigned int)packet.
data[6]) << 8)
862 | ((
short unsigned int)packet.
data[7])
864 ss_ptr->touched =
true;
867 ss_ptr->integrated_left_wheel_position =
870 ss_ptr->integrated_right_wheel_position =
873 ss_ptr->touched =
true;
876 ss_ptr->integrated_forward_position =
879 ss_ptr->integrated_turn_position =
883 ss_ptr->integrated_turn_position *= 360.0;
884 ss_ptr->touched =
true;
891 ss_ptr->touched =
true;
894 ss_ptr->operational_mode =
896 ss_ptr->controller_gain_schedule =
898 ss_ptr->ui_battery_voltage =
900 (((
short unsigned int)packet.
data[4]) << 8)
901 | ((
short unsigned int)packet.
data[5])
903 ss_ptr->powerbase_battery_voltage =
905 (((
short unsigned int)packet.
data[6]) << 8)
906 | ((
short unsigned int)packet.
data[7])
908 ss_ptr->touched =
true;
911 ss_ptr->commanded_velocity =
914 ss_ptr->commanded_yaw_rate =
917 status_updated =
true;
918 ss_ptr->touched =
true;
921 if (packet.
data[3] == 0x80)
922 ss_ptr->motor_status = 1;
924 ss_ptr->motor_status = 0;
925 ss_ptr->touched =
true;
930 return status_updated;
935 bool status_updated =
false;
942 if (status_updated) {
943 if (this->
ss_queue_.enqueue(this->segway_status_)) {
944 this->
error_(
"Falling behind, SegwayStatus Queue Full, skipping packet "
int getInt(unsigned char lhigh, unsigned char llow, unsigned char hhigh, unsigned char hlow)
void configureUSBByDescription(std::string description, int baudrate)
SegwayRMPType segway_rmp_type_
void configure(std::string port, int baudrate)
void setControllerGainSchedule(ControllerGainSchedule controller_gain_schedule)
SegwayRMP(InterfaceType interface_type=serial, SegwayRMPType segway_rmp_type=rmp200)
short int getShortInt(unsigned char high, unsigned char low)
void configureUSBByIndex(int device_index, int baudrate=460800)
boost::function< void(SegwayStatus::Ptr)> SegwayStatusCallback
void setLogMsgCallback(std::string log_level, LogMsgCallback callback)
boost::shared_ptr< SegwayStatus > Ptr
void setCurrentLimitScaleFactor(double scalar=1.0)
ExceptionCallback handle_exception_
void SetConstantsBySegwayType_(SegwayRMPType &rmp_type)
void connect(bool reset_integrators=true)
void defaultExceptionCallback(const std::exception &error)
void ProcessPacket_(Packet &packet)
void defaultSegwayStatusCallback(segwayrmp::SegwayStatus::Ptr &segway_status)
void StartReadingContinuously_()
GetTimeCallback get_time_
void sendPacket(Packet &packet)
SegwayStatusCallback status_callback_
void defaultDebugMsgCallback(const std::string &msg)
void setStatusCallback(SegwayStatusCallback callback)
boost::function< SegwayTime(void)> GetTimeCallback
ControllerGainSchedule controller_gain_schedule
boost::thread read_thread_
void getPacket(Packet &packet)
void printHex(char *data, int length)
void setBalanceModeLocking(bool state=true)
float integrated_left_wheel_position
SegwayStatus::Ptr segway_status_
boost::function< void(const std::exception &)> ExceptionCallback
void resetAllIntegrators()
float powerbase_battery_voltage
void configureSerial(std::string port, int baudrate=460800)
void move(float linear_velocity, float angular_velocity)
InterfaceType interface_type_
void setExceptionCallback(ExceptionCallback callback)
void configureUSBByDescription(std::string description, int baudrate=460800)
void configureUSBBySerial(std::string serial_number, int baudrate=460800)
bool continuously_reading_
void setMaxVelocityScaleFactor(double scalar=1.0)
float integrated_right_wheel_position
void setOperationalMode(OperationalMode operational_mode)
void setMaxAccelerationScaleFactor(double scalar=1.0)
void moveCounts(short int linear_counts, short int angular_counts)
void StopReadingContinuously_()
void setMaxTurnScaleFactor(double scalar=1.0)
void configureUSBByIndex(unsigned int device_index, int baudrate)
OperationalMode operational_mode
float integrated_turn_position
bool ParsePacket_(Packet &packet, SegwayStatus::Ptr &ss_ptr)
float integrated_forward_position
void printHexFromString(std::string str)
void configureUSBBySerial(std::string serial_number, int baudrate)
void defaultInfoMsgCallback(const std::string &msg)
void setTimestampCallback(GetTimeCallback callback)
FiniteConcurrentSharedQueue< SegwayStatus > ss_queue_
segwayrmp::SegwayTime defaultTimestampCallback()
void defaultErrorMsgCallback(const std::string &msg)
boost::thread callback_execution_thread_
boost::function< void(const std::string &)> LogMsgCallback
#define RMP_THROW_MSG(ExceptionClass, Message)