@@ -16,6 +16,14 @@ static long convertDYNIXELXL330(int16_t degree) {
1616  return  ret;
1717}
1818
19+ static  long  convertDYNIXELXL330_RT (int16_t  degree) {
20+   M5_LOGI (" Degree: %d\n "  , degree);
21+   
22+   long  ret =  map (degree, -360 , 720 , -4095 , 8191 );
23+   M5_LOGI (" Position: %d\n "  , ret);
24+   return  ret;
25+ }
26+ 
1927//  シリアルサーボ用のEasing関数
2028float  quadraticEaseInOut (float  p) {
2129  // return p;
@@ -34,6 +42,13 @@ StackchanSERVO::StackchanSERVO() {}
3442
3543StackchanSERVO::~StackchanSERVO () {}
3644
45+ float  StackchanSERVO::getPosition (int  x){
46+   if  (_servo_type == RT_DYN_XL330){
47+     return  _dxl.getPresentPosition (x);;
48+   } else  {
49+     M5_LOGI (" getPosition::Command is only supprted in RT_DYN_XL330"  );
50+   }
51+ };
3752
3853void  StackchanSERVO::attachServos () {
3954  if  (_servo_type == ServoType::SCS) {
@@ -58,7 +73,7 @@ void StackchanSERVO::attachServos() {
5873    _dxl.writeControlTableItem (DRIVE_MODE, AXIS_X + 1 , 4 );  //  Velocityのパラメータを移動時間(msec)で指定するモードに変更
5974    _dxl.writeControlTableItem (DRIVE_MODE, AXIS_Y + 1 , 4 );  //  Velocityのパラメータを移動時間(msec)で指定するモードに変更
6075    _dxl.torqueOn (AXIS_X + 1 );
61-     delay (10 ); //  ここでWaitを入れないと、Y(tilt)サーボが動かない場合がある。
76+     delay (100 ); //  ここでWaitを入れないと、Y(tilt)サーボが動かない場合がある。
6277    _dxl.torqueOn (AXIS_Y + 1 );
6378    delay (100 );
6479    _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , 1000 );
@@ -69,6 +84,43 @@ void StackchanSERVO::attachServos() {
6984    // _dxl.torqueOff(AXIS_X + 1);
7085    // _dxl.torqueOff(AXIS_Y + 1);
7186
87+   } else  if  (_servo_type == ServoType::RT_DYN_XL330){
88+     M5_LOGI (" RT_DYN_XL330"  );
89+     Serial2.begin (1000000 , SERIAL_8N1, _init_param.servo [AXIS_X].pin , _init_param.servo [AXIS_Y].pin );
90+     _dxl = Dynamixel2Arduino (Serial2);
91+     _dxl.begin (1000000 );
92+     _dxl.setPortProtocolVersion (DXL_PROTOCOL_VERSION);
93+     _dxl.ping (AXIS_X + 1 );
94+     _dxl.ping (AXIS_Y + 1 );
95+     _dxl.setOperatingMode (AXIS_X + 1 , OP_EXTENDED_POSITION);
96+     _dxl.setOperatingMode (AXIS_Y + 1 , OP_EXTENDED_POSITION);
97+     _dxl.writeControlTableItem (DRIVE_MODE, AXIS_X + 1 , 4 );  //  Velocityのパラメータを移動時間(msec)で指定するモードに変更
98+     _dxl.writeControlTableItem (DRIVE_MODE, AXIS_Y + 1 , 4 );  //  Velocityのパラメータを移動時間(msec)で指定するモードに変更
99+     _dxl.torqueOn (AXIS_X + 1 );
100+     delay (10 ); //  ここでWaitを入れないと、Y(tilt)サーボが動かない場合がある。
101+     _dxl.torqueOn (AXIS_Y + 1 );
102+     delay (100 );
103+     _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , 1000 );
104+     _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_Y + 1 , 1000 );
105+     delay (100 );
106+ 
107+     M5_LOGI (" CurrentPosition X:%f, Y:%f"  ,  _dxl.getPresentPosition (AXIS_X + 1 ), _dxl.getPresentPosition (AXIS_Y + 1 ));
108+ 
109+     if  (_dxl.getPresentPosition (AXIS_X + 1 ) > 4096 ) {
110+       _init_param.servo [AXIS_X].offset  = _init_param.servo [AXIS_X].offset  + 360 ;
111+     }
112+     if  ((_dxl.getPresentPosition (AXIS_Y + 1 )-convertDYNIXELXL330_RT (_init_param.servo [AXIS_Y].lower_limit  + _init_param.servo [AXIS_Y].offset )) > convertDYNIXELXL330_RT (270 )) {
113+       _init_param.servo [AXIS_Y].offset  = _init_param.servo [AXIS_Y].offset  + 360 ;
114+     }
115+     // _init_param.servo[AXIS_Y].offset = 360;
116+     
117+     M5_LOGI (" Current Offset X:%d, Y:%d"  , _init_param.servo [AXIS_X].offset , _init_param.servo [AXIS_Y].offset );
118+ 
119+     _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330_RT (_init_param.servo [AXIS_X].start_degree  + _init_param.servo [AXIS_X].offset ));
120+     _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330_RT (_init_param.servo [AXIS_Y].start_degree  + _init_param.servo [AXIS_Y].offset ));
121+     // _dxl.torqueOff(AXIS_X + 1);
122+     // _dxl.torqueOff(AXIS_Y + 1);
123+ 
72124  } else  {
73125    //  SG90 PWM
74126    if  (_servo_x.attach (_init_param.servo [AXIS_X].pin , 
@@ -123,7 +175,16 @@ void StackchanSERVO::moveX(int x, uint32_t millis_for_move) {
123175    _isMoving = true ;
124176    vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
125177    _isMoving = false ;
126-   } else  {
178+   } else  if  (_servo_type == ServoType::RT_DYN_XL330) {
179+     _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , millis_for_move);
180+     vTaskDelay (10 /portTICK_PERIOD_MS);
181+     _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330_RT (x + _init_param.servo [AXIS_X].offset ));
182+     vTaskDelay (10 /portTICK_PERIOD_MS);
183+     _isMoving = true ;
184+     vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
185+     _isMoving = false ;
186+     M5_LOGI (" X:%f"  , getPosition (AXIS_X+1 ));
187+   }else  {
127188    if  (millis_for_move == 0 ) {
128189      _servo_x.easeTo (x + _init_param.servo [AXIS_X].offset );
129190    } else  {
@@ -155,6 +216,15 @@ void StackchanSERVO::moveY(int y, uint32_t millis_for_move) {
155216    _isMoving = true ;
156217    vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
157218    _isMoving = false ;
219+   } else  if  (_servo_type == ServoType::RT_DYN_XL330) {
220+     _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_Y + 1 , millis_for_move);
221+     vTaskDelay (10 /portTICK_PERIOD_MS);
222+     _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330_RT (y + _init_param.servo [AXIS_Y].offset )); //  RT版に合わせて+180°しています。
223+     vTaskDelay (10 /portTICK_PERIOD_MS);
224+     _isMoving = true ;
225+     vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
226+     _isMoving = false ;
227+     M5_LOGI (" Y:%f"  , getPosition (AXIS_Y+1 ));
158228  } else  {
159229    if  (millis_for_move == 0 ) {
160230      _servo_y.easeTo (y + _init_param.servo [AXIS_Y].offset );
@@ -192,6 +262,12 @@ void StackchanSERVO::moveXY(int x, int y, uint32_t millis_for_move) {
192262    _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330 (x + _init_param.servo [AXIS_X].offset )); 
193263    _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330 (y + _init_param.servo [AXIS_Y].offset )); //  RT版に合わせて+180°しています。
194264    _isMoving = false ;
265+   } else  if  (_servo_type == ServoType::RT_DYN_XL330) {
266+     _isMoving = true ;
267+     _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330_RT (x + _init_param.servo [AXIS_X].offset )); 
268+     _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330_RT (y + _init_param.servo [AXIS_Y].offset )); //  RT版に合わせて+180°しています。
269+     _isMoving = false ;
270+     M5_LOGI (" X:%f, Y:%f"  , getPosition (AXIS_X+1 ), getPosition (AXIS_Y+1 ));
195271  } else  {
196272    _servo_x.setEaseToD (x + _init_param.servo [AXIS_X].offset , millis_for_move);
197273    _servo_y.setEaseToD (y + _init_param.servo [AXIS_Y].offset , millis_for_move);
@@ -216,6 +292,12 @@ void StackchanSERVO::moveXY(servo_param_s servo_param_x, servo_param_s servo_par
216292    _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330 (servo_param_x.degree  + _init_param.servo [AXIS_X].offset )); 
217293    _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330 (servo_param_y.degree  + _init_param.servo [AXIS_Y].offset )); //  RT版に合わせて+180°しています。
218294    _isMoving = false ;
295+   } else  if  (_servo_type == ServoType::RT_DYN_XL330) {
296+     _isMoving = true ;
297+     _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330_RT (servo_param_x.degree  + _init_param.servo [AXIS_X].offset )); 
298+     _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330_RT (servo_param_y.degree  + _init_param.servo [AXIS_Y].offset )); //  RT版に合わせて+180°しています。
299+     _isMoving = false ;
300+     M5_LOGI (" X:%f, Y:%f"  , getPosition (AXIS_X+1 ), getPosition (AXIS_Y+1 ));
219301  } else  {
220302    if  (servo_param_x.degree  != 0 ) {
221303      _servo_x.setEaseToD (servo_param_x.degree  + servo_param_x.offset , servo_param_x.millis_for_move );
0 commit comments