$search
00001 /********************************************************************* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2008, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of the Willow Garage nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 *********************************************************************/ 00034 00035 #ifndef ETHERCAT_HARDWARE__WG0X_H 00036 #define ETHERCAT_HARDWARE__WG0X_H 00037 00038 #include "ethercat_hardware/ethercat_device.h" 00039 #include "ethercat_hardware/motor_model.h" 00040 #include "ethercat_hardware/motor_heating_model.h" 00041 #include "realtime_tools/realtime_publisher.h" 00042 00043 #include <boost/shared_ptr.hpp> 00044 00045 using namespace ethercat_hardware; 00046 00047 enum MbxCmdType {LOCAL_BUS_READ=1, LOCAL_BUS_WRITE=2}; 00048 00049 struct WG0XMbxHdr 00050 { 00051 uint16_t address_; 00052 union 00053 { 00054 uint16_t command_; 00055 struct 00056 { 00057 uint16_t length_:12; 00058 uint16_t seqnum_: 3; // bits[14:12] sequence number, 0=disable, 1-7 normal sequence number 00059 uint16_t write_nread_:1; 00060 }__attribute__ ((__packed__)); 00061 }; 00062 uint8_t checksum_; 00063 00064 bool build(unsigned address, unsigned length, MbxCmdType type, unsigned seqnum); 00065 bool verifyChecksum(void) const; 00066 }__attribute__ ((__packed__)); 00067 00068 static const unsigned MBX_SIZE = 512; 00069 static const unsigned MBX_DATA_SIZE = (MBX_SIZE - sizeof(WG0XMbxHdr) - 1); 00070 struct WG0XMbxCmd 00071 { 00072 WG0XMbxHdr hdr_; 00073 uint8_t data_[MBX_DATA_SIZE]; 00074 uint8_t checksum_; 00075 00076 bool build(unsigned address, unsigned length, MbxCmdType type, unsigned seqnum, void const* data); 00077 }__attribute__ ((__packed__)); 00078 00079 struct WG0XSpiEepromCmd 00080 { 00081 uint16_t page_; 00082 union 00083 { 00084 uint8_t command_; 00085 struct 00086 { 00087 uint8_t operation_ :4; 00088 uint8_t start_ :1; 00089 uint8_t busy_ :1; 00090 uint8_t unused2_ :2; 00091 }__attribute__ ((__packed__)); 00092 }; 00093 00094 void build_read(unsigned page) 00095 { 00096 this->page_ = page & 0xffff; 00097 this->operation_ = SPI_READ_OP; 00098 this->start_ = 1; 00099 } 00100 void build_write(unsigned page) 00101 { 00102 this->page_ = page & 0xffff; 00103 this->operation_ = SPI_WRITE_OP; 00104 this->start_ = 1; 00105 } 00106 void build_arbitrary(unsigned length) 00107 { 00108 this->page_ = (length-1) & 0xffff; 00109 this->operation_ = SPI_ARBITRARY_OP; 00110 this->start_ = 1; 00111 } 00112 00113 static const unsigned SPI_READ_OP = 0; 00114 static const unsigned SPI_WRITE_OP = 1; 00115 static const unsigned SPI_ARBITRARY_OP = 3; 00116 00117 static const unsigned SPI_COMMAND_ADDR = 0x0230; 00118 static const unsigned SPI_BUFFER_ADDR = 0xF400; 00119 }__attribute__ ((__packed__)); 00120 00121 00122 00123 struct EepromStatusReg 00124 { 00125 union { 00126 uint8_t raw_; 00127 struct { 00128 uint8_t page_size_ : 1; 00129 uint8_t write_protect_ : 1; 00130 uint8_t eeprom_size_ : 4; 00131 uint8_t compare_ : 1; 00132 uint8_t ready_ : 1; 00133 } __attribute__ ((__packed__)); 00134 } __attribute__ ((__packed__)); 00135 } __attribute__ ((__packed__)); 00136 00137 00138 // Syncmanger control register 0x804+N*8 00139 struct SyncManControl { 00140 union { 00141 uint8_t raw; 00142 struct { 00143 uint8_t mode : 2; 00144 uint8_t direction : 2; 00145 uint8_t ecat_irq_enable : 1; 00146 uint8_t pdi_irq_enable : 1; 00147 uint8_t watchdog_enable : 1; 00148 uint8_t res1 : 1; 00149 } __attribute__ ((__packed__)); 00150 } __attribute__ ((__packed__)); 00151 //static const unsigned BASE_ADDR=0x804; 00152 //static unsigned base_addr(unsigned num); 00153 //void print(std::ostream &os=std::cout) const; 00154 } __attribute__ ((__packed__)); 00155 00156 // Syncmanger status register 0x805+N*8 00157 struct SyncManStatus { 00158 union { 00159 uint8_t raw; 00160 struct { 00161 uint8_t interrupt_write : 1; 00162 uint8_t interrupt_read : 1; 00163 uint8_t res1 : 1; 00164 uint8_t mailbox_status : 1; 00165 uint8_t buffer_status : 2; 00166 uint8_t res2 : 2; 00167 } __attribute__ ((__packed__)); 00168 } __attribute__ ((__packed__)); 00169 //static const unsigned BASE_ADDR=0x805; 00170 //static unsigned base_addr(unsigned num); 00171 //void print(std::ostream &os=std::cout) const; 00172 } __attribute__ ((__packed__)); 00173 00174 // Syncmanger activation register 0x806+N*8 00175 struct SyncManActivate { 00176 union { 00177 uint8_t raw; 00178 struct { 00179 uint8_t enable : 1; 00180 uint8_t repeat_request : 1; 00181 uint8_t res4 : 4; 00182 uint8_t ecat_latch_event : 1; 00183 uint8_t pdi_latch_event : 1; 00184 } __attribute__ ((__packed__)); 00185 } __attribute__ ((__packed__)); 00186 static const unsigned BASE_ADDR=0x806; 00187 static unsigned baseAddress(unsigned num); 00188 //void print(std::ostream &os=std::cout) const; 00189 bool writeData(EthercatCom *com, EtherCAT_SlaveHandler *sh, EthercatDevice::AddrMode addrMode, unsigned num) const; 00190 } __attribute__ ((__packed__)); 00191 00192 // Syncmanger PDI control register 0x807+N*8 00193 struct SyncManPDIControl { 00194 union { 00195 uint8_t raw; 00196 struct { 00197 uint8_t deactivate : 1; 00198 uint8_t repeat_ack : 1; 00199 uint8_t res6 : 6; 00200 } __attribute__ ((__packed__)); 00201 } __attribute__ ((__packed__)); 00202 //static const unsigned BASE_ADDR=0x807; 00203 //static unsigned base_addr(unsigned num); 00204 //void print(std::ostream &os=std::cout) const; 00205 } __attribute__ ((__packed__)); 00206 00207 00208 // For SyncManager settings REG 0x800+8*N 00209 struct SyncMan { 00210 union { 00211 uint8_t raw[8]; 00212 struct { 00213 uint16_t start_addr; 00214 uint16_t length; 00215 SyncManControl control; 00216 SyncManStatus status; 00217 SyncManActivate activate; 00218 SyncManPDIControl pdi_control; 00219 } __attribute__ ((__packed__)); 00220 } __attribute__ ((__packed__)); 00221 00222 // Base address for first syncmanager 00223 static const unsigned BASE_ADDR=0x800; 00224 // Base address of Nth syncmanager for N=0-7 00225 static unsigned baseAddress(unsigned num); 00226 00227 bool readData(EthercatCom *com, EtherCAT_SlaveHandler *sh, EthercatDevice::AddrMode addrMode, unsigned num); 00228 //void print(unsigned num, std::ostream &os=std::cout) const; 00229 } __attribute__ ((__packed__)); 00230 00231 00232 struct WG0XSafetyDisableStatus 00233 { 00234 uint8_t safety_disable_status_; 00235 uint8_t safety_disable_status_hold_; 00236 uint8_t safety_disable_count_; 00237 static const unsigned BASE_ADDR = 0xA1; 00238 } __attribute__ ((__packed__)); 00239 00240 00241 struct WG0XSafetyDisableCounters 00242 { 00243 uint8_t undervoltage_count_; 00244 uint8_t over_current_count_; 00245 uint8_t board_over_temp_count_; 00246 uint8_t bridge_over_temp_count_; 00247 uint8_t operate_disable_count_; 00248 uint8_t watchdog_disable_count_; 00249 static const unsigned BASE_ADDR = 0x223; 00250 } __attribute__ ((__packed__)); 00251 00252 struct WG0XDiagnosticsInfo 00253 { 00254 int16_t config_offset_current_A_; 00255 int16_t config_offset_current_B_; 00256 uint16_t supply_current_in_; 00257 union { 00258 uint16_t supply_current_out_; 00259 uint16_t voltage_ref_; 00260 } __attribute__ ((__packed__)); 00261 int16_t offset_current_A_; 00262 int16_t offset_current_B_; 00263 int16_t adc_current_; 00264 uint8_t unused1[2]; 00265 uint8_t lowside_deadtime_; 00266 uint8_t highside_deadtime_; 00267 uint8_t unused2[14]; 00268 uint8_t pdo_command_irq_count_; 00269 uint8_t mbx_command_irq_count_; 00270 uint8_t unused3; 00271 WG0XSafetyDisableCounters safety_disable_counters_; 00272 uint8_t unused4; 00273 uint8_t pdi_timeout_error_count_; 00274 uint8_t pdi_checksum_error_count_; 00275 static const unsigned BASE_ADDR = 0x200; 00276 } __attribute__ ((__packed__)); 00277 00278 struct WG0XConfigInfo 00279 { 00280 uint32_t product_id_; 00281 union 00282 { 00283 uint32_t revision_; 00284 struct 00285 { 00286 uint8_t firmware_minor_revision_; 00287 uint8_t firmware_major_revision_; 00288 uint8_t pca_revision_; 00289 uint8_t pcb_revision_; 00290 }__attribute__ ((__packed__)); 00291 }__attribute__ ((__packed__)); 00292 uint32_t device_serial_number_; 00293 uint8_t current_loop_kp_; 00294 uint8_t current_loop_ki_; 00295 uint16_t absolute_current_limit_; 00296 float nominal_current_scale_; 00297 float nominal_voltage_scale_; 00298 uint8_t pad_[8]; 00299 uint8_t configuration_status_; 00300 uint8_t safety_disable_status_; 00301 uint8_t safety_disable_status_hold_; 00302 uint8_t safety_disable_count_; 00303 uint16_t watchdog_limit_; 00304 00305 static const unsigned CONFIG_INFO_BASE_ADDR = 0x0080; 00306 }__attribute__ ((__packed__)); 00307 00308 struct WG0XUserConfigRam 00309 { 00310 uint8_t version_; 00311 uint8_t unused_[3]; 00312 double zero_offset_; 00313 uint32_t crc32_; 00314 00315 static const unsigned BASE_ADDR = 0x00C0; 00316 }__attribute__ ((__packed__)); 00317 00318 struct WG0XActuatorInfo 00319 { 00320 uint16_t major_; // Major revision 00321 uint16_t minor_; // Minor revision 00322 uint32_t id_; // Actuator ID 00323 char name_[64]; // Actuator name 00324 char robot_name_[32]; // Robot name 00325 char motor_make_[32]; // Motor manufacturer 00326 char motor_model_[32]; // Motor model # 00327 double max_current_; // Maximum current 00328 double speed_constant_; // Speed constant 00329 double resistance_; // Resistance 00330 double motor_torque_constant_; // Motor torque constant 00331 double encoder_reduction_; // Reduction and sign between motor and encoder 00332 uint32_t pulses_per_revolution_; // # of encoder ticks per revolution 00333 uint8_t pad1[40]; // Pad structure to 256-4 bytes. 00334 uint32_t crc32_256_; // CRC32 of first 256-4 bytes. (minus 4 bytes for first CRC) 00335 uint8_t pad2[4]; // Pad structure to 264-4 bytes 00336 uint32_t crc32_264_; // CRC32 over entire structure (minus 4 bytes for second CRC) 00337 00338 bool verifyCRC(void) const; 00339 void generateCRC(void); 00340 }; 00341 00342 struct WG0XStatus 00343 { 00344 uint8_t mode_; 00345 uint8_t digital_out_; 00346 int16_t programmed_pwm_value_; 00347 int16_t programmed_current_; 00348 int16_t measured_current_; 00349 uint32_t timestamp_; 00350 int32_t encoder_count_; 00351 int32_t encoder_index_pos_; 00352 uint16_t num_encoder_errors_; 00353 uint8_t encoder_status_; 00354 uint8_t calibration_reading_; 00355 int32_t last_calibration_rising_edge_; 00356 int32_t last_calibration_falling_edge_; 00357 uint16_t board_temperature_; 00358 uint16_t bridge_temperature_; 00359 uint16_t supply_voltage_; 00360 int16_t motor_voltage_; 00361 uint16_t packet_count_; 00362 uint8_t pad_; 00363 uint8_t checksum_; 00364 00365 static const unsigned SIZE=44; 00366 }__attribute__ ((__packed__)); 00367 00368 00369 struct WG0XCommand 00370 { 00371 uint8_t mode_; 00372 uint8_t digital_out_; 00373 int16_t programmed_pwm; 00374 int16_t programmed_current_; 00375 uint8_t pad_; 00376 uint8_t checksum_; 00377 }__attribute__ ((__packed__)); 00378 00379 struct MbxDiagnostics 00380 { 00381 MbxDiagnostics(); 00382 uint32_t write_errors_; 00383 uint32_t read_errors_; 00384 uint32_t lock_errors_; 00385 uint32_t retries_; 00386 uint32_t retry_errors_; 00387 }; 00388 00389 struct WG0XDiagnostics 00390 { 00391 WG0XDiagnostics(); 00392 void update(const WG0XSafetyDisableStatus &new_status, const WG0XDiagnosticsInfo &new_diagnostics_info); 00393 00394 bool first_; 00395 bool valid_; 00396 WG0XSafetyDisableStatus safety_disable_status_; 00397 00398 WG0XDiagnosticsInfo diagnostics_info_; 00399 00400 uint32_t safety_disable_total_; 00401 uint32_t undervoltage_total_; 00402 uint32_t over_current_total_; 00403 uint32_t board_over_temp_total_; 00404 uint32_t bridge_over_temp_total_; 00405 uint32_t operate_disable_total_; 00406 uint32_t watchdog_disable_total_; 00407 00408 uint32_t lock_errors_; 00409 uint32_t checksum_errors_; 00410 00411 // Hack, use diagnostic thread to push new offset values to device 00412 double zero_offset_; 00413 double cached_zero_offset_; 00414 }; 00415 00416 class WG0X : public EthercatDevice 00417 { 00418 public: 00419 void construct(EtherCAT_SlaveHandler *sh, int &start_address); 00420 WG0X(); 00421 virtual ~WG0X(); 00422 00423 virtual int initialize(pr2_hardware_interface::HardwareInterface *, bool allow_unprogrammed=true); 00424 00425 void packCommand(unsigned char *buffer, bool halt, bool reset); 00426 bool unpackState(unsigned char *this_buffer, unsigned char *prev_buffer); 00427 00428 bool program(EthercatCom *com, const WG0XActuatorInfo &actutor_info); 00429 bool program(EthercatCom *com, const MotorHeatingModelParametersEepromConfig &heating_config); 00430 00431 bool readActuatorInfoFromEeprom(EthercatCom *com, WG0XActuatorInfo &actuator_info); 00432 bool readMotorHeatingModelParametersFromEeprom(EthercatCom *com, MotorHeatingModelParametersEepromConfig &config); 00433 00434 void diagnostics(diagnostic_updater::DiagnosticStatusWrapper &d, unsigned char *); 00435 virtual void collectDiagnostics(EthercatCom *com); 00436 00437 bool publishTrace(const string &reason, unsigned level, unsigned delay); 00438 00439 protected: 00440 uint8_t fw_major_; 00441 uint8_t fw_minor_; 00442 uint8_t board_major_; 00443 uint8_t board_minor_; 00444 00445 WG0XActuatorInfo actuator_info_; 00446 WG0XConfigInfo config_info_; 00447 double max_current_; 00448 00449 ethercat_hardware::ActuatorInfo actuator_info_msg_; 00450 static void copyActuatorInfo(ethercat_hardware::ActuatorInfo &out, const WG0XActuatorInfo &in); 00451 00452 pr2_hardware_interface::Actuator actuator_; 00453 pr2_hardware_interface::DigitalOut digital_out_; 00454 00455 enum 00456 { 00457 MODE_OFF = 0x00, 00458 MODE_ENABLE = (1 << 0), 00459 MODE_CURRENT = (1 << 1), 00460 MODE_SAFETY_RESET = (1 << 4), 00461 MODE_SAFETY_LOCKOUT = (1 << 5), 00462 MODE_UNDERVOLTAGE = (1 << 6), 00463 MODE_RESET = (1 << 7) 00464 }; 00465 00466 enum 00467 { 00468 WG05_PRODUCT_CODE = 6805005, 00469 WG06_PRODUCT_CODE = 6805006, 00470 WG021_PRODUCT_CODE = 6805021 00471 }; 00472 00473 static string modeString(uint8_t mode); 00474 static string safetyDisableString(uint8_t status); 00475 bool in_lockout_; 00476 bool resetting_; 00477 bool has_error_; 00478 uint16_t max_bridge_temperature_, max_board_temperature_; 00479 bool too_many_dropped_packets_; 00480 bool status_checksum_error_; 00481 bool timestamp_jump_detected_; 00482 bool fpga_internal_reset_detected_; 00483 00484 void clearErrorFlags(void); 00485 00486 double cached_zero_offset_; 00487 enum {NO_CALIBRATION=0, CONTROLLER_CALIBRATION=1, SAVED_CALIBRATION=2}; 00488 int calibration_status_; 00489 unsigned last_num_encoder_errors_; 00490 00496 ros::Duration sample_timestamp_; 00497 00499 // Application ram is non-volitile memory that application can use to store temporary 00500 // data between runs. 00501 // Currently app ram is used to store zero offset of joint after calibration 00502 // PRESENT - App ram is available 00503 // MISSING - App ram is missing but would typically be availble 00504 // NOT_APPLICABLE - App ram is not availble, but is is not needed for this type of device 00505 enum AppRamStatus { APP_RAM_PRESENT=1, APP_RAM_MISSING=2, APP_RAM_NOT_APPLICABLE=3 }; 00506 AppRamStatus app_ram_status_; 00507 bool readAppRam(EthercatCom *com, double &zero_offset); 00508 bool writeAppRam(EthercatCom *com, double zero_offset); 00509 00510 bool verifyState(WG0XStatus *this_status, WG0XStatus *prev_status); 00511 00512 int writeMailbox(EthercatCom *com, unsigned address, void const *data, unsigned length); 00513 int readMailbox(EthercatCom *com, unsigned address, void *data, unsigned length); 00514 00515 void publishGeneralDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &d); 00516 void publishMailboxDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &d); 00517 00518 bool initializeMotorModel(pr2_hardware_interface::HardwareInterface *hw, 00519 const string &device_description, 00520 double max_pwm_ratio, 00521 double board_resistance, 00522 bool poor_measured_motor_voltage); 00523 00524 bool initializeMotorHeatingModel(bool allow_unprogrammed); 00525 00526 bool verifyChecksum(const void* buffer, unsigned size); 00527 static bool timestamp_jump(uint32_t timestamp, uint32_t last_timestamp, uint32_t amount); 00528 00529 static const int PWM_MAX = 0x4000; 00530 00531 protected: 00532 // Each WG0X device can only support one mailbox operation at a time 00533 bool lockMailbox(); 00534 void unlockMailbox(); 00535 pthread_mutex_t mailbox_lock_; 00536 MbxDiagnostics mailbox_diagnostics_; 00537 MbxDiagnostics mailbox_publish_diagnostics_; 00538 00539 // Mailbox helper functions 00540 int writeMailbox_(EthercatCom *com, unsigned address, void const *data, unsigned length); 00541 int readMailbox_(EthercatCom *com, unsigned address, void *data, unsigned length); 00542 bool verifyDeviceStateForMailboxOperation(); 00543 bool clearReadMailbox(EthercatCom *com); 00544 bool waitForReadMailboxReady(EthercatCom *com); 00545 bool waitForWriteMailboxReady(EthercatCom *com); 00546 bool readMailboxRepeatRequest(EthercatCom *com); 00547 bool _readMailboxRepeatRequest(EthercatCom *com); 00548 bool writeMailboxInternal(EthercatCom *com, void const *data, unsigned length); 00549 bool readMailboxInternal(EthercatCom *com, void *data, unsigned length); 00550 void diagnoseMailboxError(EthercatCom *com); 00551 00552 // SPI Eeprom State machine helper functions 00553 bool readSpiEepromCmd(EthercatCom *com, WG0XSpiEepromCmd &cmd); 00554 bool sendSpiEepromCmd(EthercatCom *com, const WG0XSpiEepromCmd &cmd); 00555 bool waitForSpiEepromReady(EthercatCom *com); 00556 00557 // Eeprom helper functions 00558 bool readEepromStatusReg(EthercatCom *com, EepromStatusReg ®); 00559 bool waitForEepromReady(EthercatCom *com); 00560 bool readEepromPage(EthercatCom *com, unsigned page, void* data, unsigned length); 00561 bool writeEepromPage(EthercatCom *com, unsigned page, const void* data, unsigned length); 00562 00563 00564 static const unsigned COMMAND_PHY_ADDR = 0x1000; 00565 static const unsigned STATUS_PHY_ADDR = 0x2000; 00566 static const unsigned MBX_COMMAND_PHY_ADDR = 0x1400; 00567 static const unsigned MBX_COMMAND_SIZE = 512; 00568 static const unsigned MBX_STATUS_PHY_ADDR = 0x2400; 00569 static const unsigned MBX_STATUS_SIZE = 512; 00570 00571 static const unsigned PDO_COMMAND_SYNCMAN_NUM = 0; 00572 static const unsigned PDO_STATUS_SYNCMAN_NUM = 1; 00573 static const unsigned MBX_COMMAND_SYNCMAN_NUM = 2; 00574 static const unsigned MBX_STATUS_SYNCMAN_NUM = 3; 00575 00576 enum 00577 { 00578 LIMIT_SENSOR_0_STATE = (1 << 0), 00579 LIMIT_SENSOR_1_STATE = (1 << 1), 00580 LIMIT_ON_TO_OFF = (1 << 2), 00581 LIMIT_OFF_TO_ON = (1 << 3) 00582 }; 00583 00584 enum 00585 { 00586 SAFETY_DISABLED = (1 << 0), 00587 SAFETY_UNDERVOLTAGE = (1 << 1), 00588 SAFETY_OVER_CURRENT = (1 << 2), 00589 SAFETY_BOARD_OVER_TEMP = (1 << 3), 00590 SAFETY_HBRIDGE_OVER_TEMP = (1 << 4), 00591 SAFETY_OPERATIONAL = (1 << 5), 00592 SAFETY_WATCHDOG = (1 << 6) 00593 }; 00594 00595 // Board configuration parameters 00596 00597 static const unsigned ACTUATOR_INFO_PAGE = 4095; 00598 static const unsigned NUM_EEPROM_PAGES = 4096; 00599 static const unsigned MAX_EEPROM_PAGE_SIZE = 264; 00600 00601 // Not all devices will need this (WG021 won't) 00602 MotorModel *motor_model_; 00603 bool disable_motor_model_checking_; 00604 ethercat_hardware::MotorTraceSample motor_trace_sample_; 00605 pr2_hardware_interface::DigitalOut publish_motor_trace_; 00606 00607 // Only device with motor heating parameters store in eeprom config will use this 00608 static boost::shared_ptr<ethercat_hardware::MotorHeatingModelCommon> motor_heating_model_common_; 00609 boost::shared_ptr<ethercat_hardware::MotorHeatingModel> motor_heating_model_; 00610 00611 // Diagnostic message values 00612 uint32_t last_timestamp_; 00613 uint32_t last_last_timestamp_; 00614 int drops_; 00615 int consecutive_drops_; 00616 int max_consecutive_drops_; 00617 00618 bool lockWG0XDiagnostics(); 00619 bool tryLockWG0XDiagnostics(); 00620 void unlockWG0XDiagnostics(); 00621 pthread_mutex_t wg0x_diagnostics_lock_; 00622 WG0XDiagnostics wg0x_publish_diagnostics_; 00623 WG0XDiagnostics wg0x_collect_diagnostics_; 00624 00625 public: 00626 static int32_t timestampDiff(uint32_t new_timestamp, uint32_t old_timestamp); 00627 static int32_t positionDiff(int32_t new_position, int32_t old_position); 00628 00629 static ros::Duration timediffToDuration(int32_t timediff_usec); 00630 00631 static double calcEncoderVelocity(int32_t new_position, uint32_t new_timestamp, 00632 int32_t old_position, uint32_t old_timestamp); 00633 00634 static unsigned computeChecksum(void const *data, unsigned length); 00635 static unsigned int rotateRight8(unsigned in); 00636 00637 static double convertRawTemperature(int16_t raw_temp); 00638 }; 00639 00640 00641 #endif // ETHERCAT_HARDWARE__WG0X_H