From 4b38ed7d99c3fa37cf713a42024db8aa7b9d06e8 Mon Sep 17 00:00:00 2001 From: Sergi Hernandez Juan <shernand@iri.upc.edu> Date: Tue, 28 Feb 2023 16:51:18 +0100 Subject: [PATCH] Added support for the drive_mode. Solved some bugs when computing speeds, accelerations and loads. --- include/dynamixel_motor.h | 40 +++++++ src/dynamixel_motor.cpp | 221 +++++++++++++++++++++++++++++--------- 2 files changed, 211 insertions(+), 50 deletions(-) diff --git a/include/dynamixel_motor.h b/include/dynamixel_motor.h index 71788bb..ec911da 100644 --- a/include/dynamixel_motor.h +++ b/include/dynamixel_motor.h @@ -114,6 +114,16 @@ class CDynamixelMotor * */ control_mode mode; + /** + * \brief + * + */ + bool time_based_mode; + /** + * \brief + * + */ + bool reverse_mode; /** * \brief * @@ -151,6 +161,11 @@ class CDynamixelMotor * */ void set_control_mode(control_mode mode); + /** + * \brief + * + */ + void set_drive_mode(bool time_based,bool reverse); /** * \brief * @@ -161,6 +176,16 @@ class CDynamixelMotor * */ double to_speeds(signed int counts); + /** + * \brief + * + */ + double to_accelerations(signed int counts); + /** + * \brief + * + */ + double to_currents(signed int counts); /** * \brief * @@ -171,6 +196,16 @@ class CDynamixelMotor * */ signed int from_speeds(double speed); + /** + * \brief + * + */ + signed int from_accelerations(double accel); + /** + * \brief + * + */ + signed int from_currents(double current); /** * \brief * @@ -440,6 +475,11 @@ class CDynamixelMotor * */ control_mode get_control_mode(void); + /** + * \brief + * + */ + void get_drive_mode(bool &time_based,bool &reverse); /** * \brief * diff --git a/src/dynamixel_motor.cpp b/src/dynamixel_motor.cpp index d417b52..e2f60a3 100644 --- a/src/dynamixel_motor.cpp +++ b/src/dynamixel_motor.cpp @@ -53,6 +53,7 @@ CDynamixelMotor::CDynamixelMotor(std::string& cont_id,CDynamixelServer *dyn_serv this->info.id=dev_id; this->get_model(); this->get_control_mode(); + this->get_drive_mode(this->time_based_mode,this->reverse_mode); this->config.max_temperature=this->get_temperature_limit(); this->get_voltage_limits(&this->config.min_voltage,&this->config.max_voltage); this->config.max_pwm=this->get_pwm_limit(); @@ -86,12 +87,52 @@ signed int CDynamixelMotor::from_speeds(double speed) { unsigned int counts; - if(speed>this->info.max_speed) - speed=this->info.max_speed; + if(!this->time_based_mode) + { + if(speed>this->info.max_speed) + speed=this->info.max_speed; + if(this->info.ext_memory_map) + counts=(speed/6.0)/0.229; + else + counts=fabs(speed/6.0)/0.111; + } + else + { + counts=speed*1000; + } + + return counts; +} + +signed int CDynamixelMotor::from_accelerations(double accel) +{ + unsigned int counts; + + if(!this->time_based_mode) + { + if(this->info.ext_memory_map) + counts=(accel*10.0)/214.577; + else + counts=0; + } + else + counts=accel*1000; + + return counts; +} + +signed int CDynamixelMotor::from_currents(double current) +{ + unsigned int counts; + + if(current>this->info.max_current) + current=this->info.max_current; + else if(current<-this->info.max_current) + current=-this->info.max_current; if(this->info.ext_memory_map) - counts=speed/0.229; + counts=current/0.00269; else - counts=fabs(speed)/0.666; + counts=1000.0*(current/this->info.max_current); return counts; } @@ -109,14 +150,48 @@ double CDynamixelMotor::to_speeds(signed int counts) { double speed; - if(this->info.ext_memory_map) - speed=counts*0.229; + if(!this->time_based_mode) + { + if(this->info.ext_memory_map) + speed=(counts*0.229)*6.0; + else + speed=(counts*0.111)*6.0; // Taken from the datasheets (sfoix) + } else - speed=counts*0.666; // Taken from the datasheets (sfoix) + speed=counts/1000.0; return speed; } +double CDynamixelMotor::to_accelerations(signed int counts) +{ + double accel; + + if(!this->time_based_mode) + { + if(this->info.ext_memory_map) + accel=(counts*214.577)*10.0; + else + accel=0.0; + } + else + accel=counts/1000.0; + + return accel; +} + +double CDynamixelMotor::to_currents(signed int counts) +{ + double current; + + if(this->info.ext_memory_map) + current=(counts*0.00269); + else + current=(this->info.max_current*counts)/1000.0; + + return current; +} + void CDynamixelMotor::reset_motor(void) { unsigned int current_position; @@ -169,73 +244,73 @@ void CDynamixelMotor::get_model(void) this->info.max_angle=300.0; this->info.center_angle=150.0; this->info.max_speed=354; - this->info.max_current=0.0; + this->info.max_current=0.0; this->info.encoder_resolution=1023; this->info.gear_ratio=254; - this->registers=ax_reg; + this->registers=ax_reg; this->info.pid_control=false; - this->info.multi_turn=false; - this->info.ext_memory_map=false; + this->info.multi_turn=false; + this->info.ext_memory_map=false; break; case 0x012C: this->info.model="AX-12W"; this->info.max_angle=300.0; this->info.center_angle=150.0; this->info.max_speed=2830; - this->info.max_current=0.0; + this->info.max_current=0.0; this->info.encoder_resolution=1023; this->info.gear_ratio=32; - this->registers=ax_reg; + this->registers=ax_reg; this->info.pid_control=false; - this->info.multi_turn=false; - this->info.ext_memory_map=false; + this->info.multi_turn=false; + this->info.ext_memory_map=false; break; case 0x0012: this->info.model="AX-18A"; this->info.max_angle=300.0; this->info.center_angle=150.0; this->info.max_speed=582; - this->info.max_current=0.0; + this->info.max_current=0.0; this->info.encoder_resolution=1023; this->info.gear_ratio=254; - this->registers=ax_reg; + this->registers=ax_reg; this->info.pid_control=false; - this->info.multi_turn=false; - this->info.ext_memory_map=false; + this->info.multi_turn=false; + this->info.ext_memory_map=false; break; case 0x001C: this->info.model="RX-28"; this->info.max_angle=300.0; this->info.center_angle=150.0; this->info.max_speed=510; - this->info.max_current=0.0; + this->info.max_current=0.0; this->info.encoder_resolution=1023; this->info.gear_ratio=193; - this->registers=ax_reg; + this->registers=ax_reg; this->info.pid_control=false; - this->info.multi_turn=false; - this->info.ext_memory_map=false; + this->info.multi_turn=false; + this->info.ext_memory_map=false; break; case 0x0168: this->info.model="MX-12"; this->info.max_angle=360.0; this->info.center_angle=180.0; this->info.max_speed=2820; - this->info.max_current=0.0; + this->info.max_current=0.0; this->info.encoder_resolution=4095; this->info.gear_ratio=32; - this->registers=mx_1_0_reg; + this->registers=mx_1_0_reg; this->info.pid_control=true; - this->info.multi_turn=true; - this->info.ext_memory_map=false; + this->info.multi_turn=true; + this->info.ext_memory_map=false; break; case 0x001D: this->info.model="MX-28"; this->info.max_angle=360.0; this->info.center_angle=180.0; this->info.max_speed=330; - this->info.max_current=0.0; + this->info.max_current=0.0; this->info.encoder_resolution=4095; this->info.gear_ratio=193; - this->registers=mx_1_0_reg; + this->registers=mx_1_0_reg; this->info.pid_control=true; - this->info.multi_turn=true; - this->info.ext_memory_map=false; + this->info.multi_turn=true; + this->info.ext_memory_map=false; break; case 0x001E: this->info.model="MX-28 v2"; this->info.max_angle=360.0; @@ -246,56 +321,56 @@ void CDynamixelMotor::get_model(void) this->info.gear_ratio=193; this->registers=mx_28_2_0_reg; this->info.pid_control=true; - this->info.multi_turn=true; - this->info.ext_memory_map=false; + this->info.multi_turn=true; + this->info.ext_memory_map=true; break; case 0x0136: this->info.model="MX-64"; this->info.max_angle=360.0; this->info.center_angle=180.0; this->info.max_speed=378; - this->info.max_current=0.0; + this->info.max_current=0.0; this->info.encoder_resolution=4095; this->info.gear_ratio=200; - this->registers=mx_1_0_reg; + this->registers=mx_1_0_reg; this->info.pid_control=true; - this->info.multi_turn=true; - this->info.ext_memory_map=false; + this->info.multi_turn=true; + this->info.ext_memory_map=false; break; case 0x0140: this->info.model="MX-106"; this->info.max_angle=360.0; this->info.center_angle=180.0; this->info.max_speed=270; - this->info.max_current=0.0; + this->info.max_current=0.0; this->info.encoder_resolution=4095; this->info.gear_ratio=225; - this->registers=mx_106_1_0_reg; + this->registers=mx_106_1_0_reg; this->info.pid_control=true; - this->info.multi_turn=true; - this->info.ext_memory_map=false; + this->info.multi_turn=true; + this->info.ext_memory_map=false; break; case 0x015E: this->info.model="XL_320"; this->info.max_angle=300.0; this->info.center_angle=150; this->info.max_speed=684; - this->info.max_current=0.0; + this->info.max_current=0.0; this->info.encoder_resolution=1023; this->info.gear_ratio=238; - this->registers=xl_reg; + this->registers=xl_reg; this->info.pid_control=true; - this->info.multi_turn=false; - this->info.ext_memory_map=false; + this->info.multi_turn=false; + this->info.ext_memory_map=false; break; case 0x0406: this->info.model="XM-430-W210"; this->info.max_angle=360.0; this->info.center_angle=180; - this->info.max_speed=4620; - this->info.max_current=2.3; + this->info.max_speed=4620; + this->info.max_current=2.3; this->info.encoder_resolution=4095; this->info.gear_ratio=213; - this->registers=xm_reg; + this->registers=xm_reg; this->info.pid_control=true; - this->info.multi_turn=true; - this->info.ext_memory_map=true; + this->info.multi_turn=true; + this->info.ext_memory_map=true; break; case 0x460: this->info.model="XM540-W270"; this->info.max_angle=350.0; @@ -307,6 +382,7 @@ void CDynamixelMotor::get_model(void) this->registers=xm_reg; this->info.pid_control=true; this->info.multi_turn=true; + this->info.ext_memory_map=true; break; default: this->info.model="unknown"; break; @@ -365,6 +441,17 @@ void CDynamixelMotor::set_control_mode(control_mode mode) } } +void CDynamixelMotor::set_drive_mode(bool time_based,bool reverse) +{ + unsigned int value=0; + + if(time_based) + value|=0x04; + if(reverse) + value|=0x01; + this->write_register(this->registers[drive_mode],value); +} + void CDynamixelMotor::read_register(TDynReg reg, unsigned int &value) { unsigned char reg_value[4]={0}; @@ -1283,6 +1370,40 @@ control_mode CDynamixelMotor::get_control_mode(void) return this->mode; } +void CDynamixelMotor::get_drive_mode(bool &time_based,bool &reverse) +{ + unsigned int value; + + try{ + this->read_register(this->registers[drive_mode],value); + if(value&0x04) + { + this->time_based_mode=true; + time_based=true; + } + else + { + this->time_based_mode=false; + time_based=false; + } + if(value&0x01) + { + this->reverse_mode=true; + reverse=true; + } + else + { + this->reverse_mode=false; + reverse=false; + } + }catch(CException &e){ + this->time_based_mode=false; + time_based=false; + this->reverse_mode=false; + reverse=false; + } +} + CDynamixelMotor::~CDynamixelMotor() { /* stop the motor */ -- GitLab