@@ -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) {
@@ -68,6 +83,40 @@ void StackchanSERVO::attachServos() {
68
83
// _dxl.torqueOff(AXIS_X + 1);
69
84
// _dxl.torqueOff(AXIS_Y + 1);
70
85
86
+ } else if (_servo_type == ServoType::RT_DYN_XL330){
87
+ M5_LOGI (" RT_DYN_XL330" );
88
+ Serial2.begin (1000000 , SERIAL_8N1, _init_param.servo [AXIS_X].pin , _init_param.servo [AXIS_Y].pin );
89
+ _dxl = Dynamixel2Arduino (Serial2);
90
+ _dxl.begin (1000000 );
91
+ _dxl.setPortProtocolVersion (DXL_PROTOCOL_VERSION);
92
+ _dxl.ping (AXIS_X + 1 );
93
+ _dxl.ping (AXIS_Y + 1 );
94
+ _dxl.setOperatingMode (AXIS_X + 1 , OP_EXTENDED_POSITION);
95
+ _dxl.setOperatingMode (AXIS_Y + 1 , OP_EXTENDED_POSITION);
96
+ _dxl.writeControlTableItem (DRIVE_MODE, AXIS_X + 1 , 4 ); // Velocityのパラメータを移動時間(msec)で指定するモードに変更
97
+ _dxl.writeControlTableItem (DRIVE_MODE, AXIS_Y + 1 , 4 ); // Velocityのパラメータを移動時間(msec)で指定するモードに変更
98
+ _dxl.torqueOn (AXIS_X + 1 );
99
+ delay (10 ); // ここでWaitを入れないと、Y(tilt)サーボが動かない場合がある。
100
+ _dxl.torqueOn (AXIS_Y + 1 );
101
+ delay (100 );
102
+ _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , 1000 );
103
+ _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_Y + 1 , 1000 );
104
+ delay (100 );
105
+
106
+ M5_LOGI (" CurrentPosition X:%d, Y:%d" , _dxl.getPresentPosition (AXIS_X + 1 ), _dxl.getPresentPosition (AXIS_Y + 1 ));
107
+
108
+ if (_dxl.getPresentPosition (AXIS_X + 1 ) > 4096 ) {
109
+ _init_param.servo [AXIS_X].offset = _init_param.servo [AXIS_X].offset + 360 ;
110
+ }
111
+ if (_dxl.getPresentPosition (AXIS_Y + 1 ) > 4096 ) {
112
+ _init_param.servo [AXIS_Y].offset = _init_param.servo [AXIS_Y].offset + 360 ;
113
+ }
114
+
115
+ _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330_RT (_init_param.servo [AXIS_X].start_degree + _init_param.servo [AXIS_X].offset ));
116
+ _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330_RT (_init_param.servo [AXIS_Y].start_degree + _init_param.servo [AXIS_Y].offset ));
117
+ // _dxl.torqueOff(AXIS_X + 1);
118
+ // _dxl.torqueOff(AXIS_Y + 1);
119
+
71
120
} else {
72
121
// SG90 PWM
73
122
if (_servo_x.attach (_init_param.servo [AXIS_X].pin ,
@@ -122,7 +171,16 @@ void StackchanSERVO::moveX(int x, uint32_t millis_for_move) {
122
171
_isMoving = true ;
123
172
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
124
173
_isMoving = false ;
125
- } else {
174
+ } else if (_servo_type == ServoType::RT_DYN_XL330) {
175
+ _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , millis_for_move);
176
+ vTaskDelay (10 /portTICK_PERIOD_MS);
177
+ _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330_RT (x + _init_param.servo [AXIS_X].offset ));
178
+ vTaskDelay (10 /portTICK_PERIOD_MS);
179
+ _isMoving = true ;
180
+ vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
181
+ _isMoving = false ;
182
+ M5_LOGI (" X:%f" , getPosition (AXIS_X+1 ));
183
+ }else {
126
184
if (millis_for_move == 0 ) {
127
185
_servo_x.easeTo (x + _init_param.servo [AXIS_X].offset );
128
186
} else {
@@ -154,6 +212,15 @@ void StackchanSERVO::moveY(int y, uint32_t millis_for_move) {
154
212
_isMoving = true ;
155
213
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
156
214
_isMoving = false ;
215
+ } else if (_servo_type == ServoType::RT_DYN_XL330) {
216
+ _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_Y + 1 , millis_for_move);
217
+ vTaskDelay (10 /portTICK_PERIOD_MS);
218
+ _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330_RT (y + _init_param.servo [AXIS_Y].offset )); // RT版に合わせて+180°しています。
219
+ vTaskDelay (10 /portTICK_PERIOD_MS);
220
+ _isMoving = true ;
221
+ vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
222
+ _isMoving = false ;
223
+ M5_LOGI (" Y:%f" , getPosition (AXIS_Y+1 ));
157
224
} else {
158
225
if (millis_for_move == 0 ) {
159
226
_servo_y.easeTo (y + _init_param.servo [AXIS_Y].offset );
@@ -191,6 +258,12 @@ void StackchanSERVO::moveXY(int x, int y, uint32_t millis_for_move) {
191
258
_dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330 (x + _init_param.servo [AXIS_X].offset ));
192
259
_dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330 (y + _init_param.servo [AXIS_Y].offset )); // RT版に合わせて+180°しています。
193
260
_isMoving = false ;
261
+ } else if (_servo_type == ServoType::RT_DYN_XL330) {
262
+ _isMoving = true ;
263
+ _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330_RT (x + _init_param.servo [AXIS_X].offset ));
264
+ _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330_RT (y + _init_param.servo [AXIS_Y].offset )); // RT版に合わせて+180°しています。
265
+ _isMoving = false ;
266
+ M5_LOGI (" X:%f, Y:%f" , getPosition (AXIS_X+1 ), getPosition (AXIS_Y+1 ));
194
267
} else {
195
268
_servo_x.setEaseToD (x + _init_param.servo [AXIS_X].offset , millis_for_move);
196
269
_servo_y.setEaseToD (y + _init_param.servo [AXIS_Y].offset , millis_for_move);
@@ -215,6 +288,12 @@ void StackchanSERVO::moveXY(servo_param_s servo_param_x, servo_param_s servo_par
215
288
_dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330 (servo_param_x.degree + _init_param.servo [AXIS_X].offset ));
216
289
_dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330 (servo_param_y.degree + _init_param.servo [AXIS_Y].offset )); // RT版に合わせて+180°しています。
217
290
_isMoving = false ;
291
+ } else if (_servo_type == ServoType::RT_DYN_XL330) {
292
+ _isMoving = true ;
293
+ _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330_RT (servo_param_x.degree + _init_param.servo [AXIS_X].offset ));
294
+ _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330_RT (servo_param_y.degree + _init_param.servo [AXIS_Y].offset )); // RT版に合わせて+180°しています。
295
+ _isMoving = false ;
296
+ M5_LOGI (" X:%f, Y:%f" , getPosition (AXIS_X+1 ), getPosition (AXIS_Y+1 ));
218
297
} else {
219
298
if (servo_param_x.degree != 0 ) {
220
299
_servo_x.setEaseToD (servo_param_x.degree + servo_param_x.offset , servo_param_x.millis_for_move );
0 commit comments