4 static double min(
double a, 
double b) {
return (a<b)?a:b;}
     7   trace_size_(trace_size), 
    10   backemf_constant_(0.0),
    11   motor_voltage_error_(0.2),
    12   abs_motor_voltage_error_(0.02),
    13   measured_voltage_error_(0.2),
    14   abs_measured_voltage_error_(0.02),
    16   abs_current_error_(0.02),
    18   abs_measured_current_(0.02),
    19   abs_board_voltage_(0.02),
    20   abs_position_delta_(0.02)
    54                             const ethercat_hardware::BoardInfo &board_info)
    56   std::string topic(
"motor_trace");
    57   if (!actuator_info.name.empty())
    58     topic = topic + 
"/" + actuator_info.name;
    77     msg.actuator_info = actuator_info;  
    78     msg.board_info = board_info;
   107   msg.samples.reserve(size);
   110   for (
unsigned i=0; i<size; ++i) {
   129   else if (delay > 900) {
   146   double motor_voltage_error; 
   147   double motor_voltage_error_max; 
   148   double abs_motor_voltage_error; 
   149   double abs_motor_voltage_error_max; 
   150   double current_error; 
   151   double current_error_max; 
   152   double abs_current_error; 
   153   double abs_current_error_max;
   154   double est_motor_resistance;
   177   d.
addf(
"Motor Voltage Error %", 
"%f",        100.0 * motor_voltage_error);
   178   d.
addf(
"Max Motor Voltage Error %", 
"%f",    100.0 * motor_voltage_error_max);
   179   d.
addf(
"Abs Filtered Voltage Error %", 
"%f",     100.0 * abs_motor_voltage_error);
   180   d.
addf(
"Max Abs Filtered Voltage Error %", 
"%f", 100.0 * abs_motor_voltage_error_max);
   183   d.
addf(
"Current Error", 
"%f",              current_error);
   184   d.
addf(
"Max Current Error", 
"%f",          current_error_max);
   185   d.
addf(
"Abs Filtered Current Error", 
"%f",     abs_current_error);
   186   d.
addf(
"Max Abs Filtered Current Error", 
"%f", abs_current_error_max);
   188   d.
addf(
"Motor Resistance Estimate", 
"%f", est_motor_resistance);
   202   const ethercat_hardware::BoardInfo &bi(
board_info_);
   205   double board_voltage = s.supply_voltage * s.programmed_pwm - bi.board_resistance * s.measured_current;
   208   double resistance_voltage = s.measured_current * ai.motor_resistance;
   210   double motor_voltage =  resistance_voltage + backemf_voltage;
   213   const double resistance_error = 2.00;    
   214   const double backemf_constant_error = 0.15; 
   215   double motor_voltage_error_limit = 4.0 + fabs(resistance_voltage*resistance_error) + fabs(backemf_voltage * backemf_constant_error);
   217   motor_voltage_error_limit = 
min(motor_voltage_error_limit, 10.0);
   220   double est_motor_resistance = 0.0;
   221   double est_motor_resistance_accuracy = 0.0;
   223   if (fabs(s.measured_current) > (0.02 * bi.hw_max_current + 0.005)) 
   225     est_motor_resistance = (board_voltage - backemf_voltage) / s.measured_current;
   229     est_motor_resistance_accuracy = 1.0 / (1.0 + fabs(backemf_voltage / resistance_voltage));
   245     bool pwm_saturated = ((s.programmed_pwm > bi.max_pwm_ratio*0.95) || (s.programmed_pwm < -bi.max_pwm_ratio*0.95));
   246     double current_error = s.measured_current-s.executed_current;
   247     bool new_max_current_error = 
false;
   296     s2.motor_voltage_error_limit           = motor_voltage_error_limit;
   322   double measured_voltage_error_limit = 
board_info_.poor_measured_motor_voltage ? 10.0 : 4.0;
   331   if (is_motor_voltage_error || is_measured_voltage_error) 
   335     reason = 
"Problem with the MCB, motor, encoder, or actuator model.";  
   337     if( is_measured_voltage_error ) 
   340       reason += 
" Board may be damaged.";
   342     else if (is_motor_voltage_error) 
   346       const double current_epsilon = 0.010;
   347       double encoder_tick_delta = 2 * M_PI / 
actuator_info_.pulses_per_revolution;
   353         reason += 
" Current near zero - check for unconnected motor leads.";
   358         reason += 
" Voltage near zero - check for short circuit.";
   363         reason += 
" Velocity near zero - check for encoder error.";
   368         reason += 
" Encoder delta below 1 - check encoder wiring.";
   377     reason = 
"Current loop error too large (MCB failing to hit desired current)";
   382     reason = 
"Potential problem with the MCB, motor, encoder, or actuator model.";  
   387     reason = 
"Potential current loop error (MCB failing to hit desired current)";  
   411   filtered_value_ += filter_coefficient * (value-filtered_value_);  
   420   bool new_max = 
false;
   422   if (fabs(filtered_value_) > max_filtered_value_) {
   424     max_filtered_value_ = fabs(filtered_value_);
   436   filter_coefficient_(filter_coefficient)
 
double filter_max() const 
 
boost::mutex diagnostics_mutex_
 
bool verify()
Check for errors between sample data and motor model. 
 
double current_error_limit_
 
void sample(double value, double filter_coefficient)
Updates filter with newly sampled value. 
 
double max_filtered_value_
 
bool sample(double value)
Updates filter with newly sampled value, also tracks max value. 
 
Filter abs_position_delta_
 
Filter abs_measured_voltage_error_
 
ethercat_hardware::BoardInfo board_info_
 
unsigned published_traces_
 
Filter motor_voltage_error_
 
Filter abs_measured_current_
 
void diagnostics(diagnostic_updater::DiagnosticStatusWrapper &d)
Collects and publishes device diagnostics. 
 
SimpleFilter motor_resistance_
 
void addf(const std::string &key, const char *format,...)
 
Filter(double filter_coefficient)
 
realtime_tools::RealtimePublisher< ethercat_hardware::MotorTrace > * publisher_
 
std::string diagnostics_reason_
 
Filter measured_voltage_error_
 
void sample(const ethercat_hardware::MotorTraceSample &s)
Call for each update. 
 
bool initialize(const ethercat_hardware::ActuatorInfo &actuator_info, const ethercat_hardware::BoardInfo &board_info)
Initializes motor trace publisher. 
 
Filter abs_board_voltage_
 
Filter abs_motor_voltage_error_
 
std::vector< ethercat_hardware::MotorTraceSample > trace_buffer_
 
bool previous_pwm_saturated_
 
void checkPublish()
Publishes motor trace if delay time is up. 
 
void flagPublish(const std::string &reason, int level, int delay)
flags delayed publish of motor trace. 
 
void mergeSummary(unsigned char lvl, const std::string s)
 
std::string publish_reason_
 
ethercat_hardware::ActuatorInfo actuator_info_
 
static double min(double a, double b)
 
MotorModel(unsigned trace_size)
 
Filter abs_current_error_