@@ -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