@@ -16,6 +16,14 @@ static long convertDYNIXELXL330(int16_t degree) {
16
16
return ret;
17
17
}
18
18
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
+
19
27
// シリアルサーボ用のEasing関数
20
28
float quadraticEaseInOut (float p) {
21
29
// return p;
@@ -34,6 +42,13 @@ StackchanSERVO::StackchanSERVO() {}
34
42
35
43
StackchanSERVO::~StackchanSERVO () {}
36
44
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
+ };
37
52
38
53
void StackchanSERVO::attachServos () {
39
54
if (_servo_type == ServoType::SCS) {
@@ -58,7 +73,7 @@ void StackchanSERVO::attachServos() {
58
73
_dxl.writeControlTableItem (DRIVE_MODE, AXIS_X + 1 , 4 ); // Velocityのパラメータを移動時間(msec)で指定するモードに変更
59
74
_dxl.writeControlTableItem (DRIVE_MODE, AXIS_Y + 1 , 4 ); // Velocityのパラメータを移動時間(msec)で指定するモードに変更
60
75
_dxl.torqueOn (AXIS_X + 1 );
61
- delay (10 ); // ここでWaitを入れないと、Y(tilt)サーボが動かない場合がある。
76
+ delay (100 ); // ここでWaitを入れないと、Y(tilt)サーボが動かない場合がある。
62
77
_dxl.torqueOn (AXIS_Y + 1 );
63
78
delay (100 );
64
79
_dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , 1000 );
@@ -69,6 +84,43 @@ void StackchanSERVO::attachServos() {
69
84
// _dxl.torqueOff(AXIS_X + 1);
70
85
// _dxl.torqueOff(AXIS_Y + 1);
71
86
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
+
72
124
} else {
73
125
// SG90 PWM
74
126
if (_servo_x.attach (_init_param.servo [AXIS_X].pin ,
@@ -123,7 +175,16 @@ void StackchanSERVO::moveX(int x, uint32_t millis_for_move) {
123
175
_isMoving = true ;
124
176
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
125
177
_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 {
127
188
if (millis_for_move == 0 ) {
128
189
_servo_x.easeTo (x + _init_param.servo [AXIS_X].offset );
129
190
} else {
@@ -155,6 +216,15 @@ void StackchanSERVO::moveY(int y, uint32_t millis_for_move) {
155
216
_isMoving = true ;
156
217
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
157
218
_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 ));
158
228
} else {
159
229
if (millis_for_move == 0 ) {
160
230
_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) {
192
262
_dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330 (x + _init_param.servo [AXIS_X].offset ));
193
263
_dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330 (y + _init_param.servo [AXIS_Y].offset )); // RT版に合わせて+180°しています。
194
264
_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 ));
195
271
} else {
196
272
_servo_x.setEaseToD (x + _init_param.servo [AXIS_X].offset , millis_for_move);
197
273
_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
216
292
_dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330 (servo_param_x.degree + _init_param.servo [AXIS_X].offset ));
217
293
_dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330 (servo_param_y.degree + _init_param.servo [AXIS_Y].offset )); // RT版に合わせて+180°しています。
218
294
_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 ));
219
301
} else {
220
302
if (servo_param_x.degree != 0 ) {
221
303
_servo_x.setEaseToD (servo_param_x.degree + servo_param_x.offset , servo_param_x.millis_for_move );
0 commit comments