3
3
4
4
#include < ServoEasing.hpp>
5
5
6
- long convertSCS0009Pos (int16_t degree) {
6
+ static long convertSCS0009Pos (int16_t degree) {
7
7
// Serial.printf("Degree: %d\n", degree);
8
8
return map (degree, 0 , 300 , 1023 , 0 );
9
9
}
10
10
11
- long convertDYNIXELXL330 (int16_t degree) {
11
+ static long convertDYNIXELXL330 (int16_t degree) {
12
12
M5_LOGI (" Degree: %d\n " , degree);
13
13
14
14
long ret = map (degree, 0 , 360 , 0 , 4095 );
@@ -52,13 +52,17 @@ void StackchanSERVO::attachServos() {
52
52
_dxl.setPortProtocolVersion (DXL_PROTOCOL_VERSION);
53
53
_dxl.ping (AXIS_X + 1 );
54
54
_dxl.ping (AXIS_Y + 1 );
55
- _dxl.torqueOn (AXIS_X + 1 );
56
- _dxl.torqueOn (AXIS_Y + 1 );
57
55
_dxl.setOperatingMode (AXIS_X + 1 , OP_POSITION);
58
56
_dxl.setOperatingMode (AXIS_Y + 1 , OP_POSITION);
59
- _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , 100 );
60
- _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_Y + 1 , 100 );
61
- delay (1000 );
57
+ _dxl.writeControlTableItem (DRIVE_MODE, AXIS_X + 1 , 4 ); // Velocityのパラメータを移動時間(msec)で指定するモードに変更
58
+ _dxl.writeControlTableItem (DRIVE_MODE, AXIS_Y + 1 , 4 ); // Velocityのパラメータを移動時間(msec)で指定するモードに変更
59
+ _dxl.torqueOn (AXIS_X + 1 );
60
+ delay (10 ); // ここでWaitを入れないと、Y(tilt)サーボが動かない場合がある。
61
+ _dxl.torqueOn (AXIS_Y + 1 );
62
+ delay (100 );
63
+ _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , 1000 );
64
+ _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_Y + 1 , 1000 );
65
+ delay (100 );
62
66
_dxl.setGoalPosition (AXIS_X + 1 , 2048 );
63
67
_dxl.setGoalPosition (AXIS_Y + 1 , 3073 );
64
68
// _dxl.torqueOff(AXIS_X + 1);
@@ -76,7 +80,7 @@ void StackchanSERVO::attachServos() {
76
80
_init_param.servo [AXIS_Y].start_degree + _init_param.servo [AXIS_Y].offset ,
77
81
DEFAULT_MICROSECONDS_FOR_0_DEGREE,
78
82
DEFAULT_MICROSECONDS_FOR_180_DEGREE)) {
79
- Serial.print (" Error attaching servo x " );
83
+ Serial.print (" Error attaching servo y " );
80
84
}
81
85
82
86
_servo_x.setEasingType (EASE_QUADRATIC_IN_OUT);
@@ -111,9 +115,10 @@ void StackchanSERVO::moveX(int x, uint32_t millis_for_move) {
111
115
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
112
116
_isMoving = false ;
113
117
} else if (_servo_type == ServoType::DYN_XL330) {
114
- _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , calcVelocity (ServoAxis::AXIS_X, x, millis_for_move) );
118
+ _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , millis_for_move);
115
119
vTaskDelay (10 /portTICK_PERIOD_MS);
116
120
_dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330 (x + _init_param.servo [AXIS_X].offset ));
121
+ vTaskDelay (10 /portTICK_PERIOD_MS);
117
122
_isMoving = true ;
118
123
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
119
124
_isMoving = false ;
@@ -142,9 +147,10 @@ void StackchanSERVO::moveY(int y, uint32_t millis_for_move) {
142
147
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
143
148
_isMoving = false ;
144
149
} else if (_servo_type == ServoType::DYN_XL330) {
145
- _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_Y + 1 , calcVelocity (ServoAxis::AXIS_Y, y, millis_for_move));
150
+ _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_Y + 1 , millis_for_move);
151
+ vTaskDelay (10 /portTICK_PERIOD_MS);
152
+ _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330 (y + _init_param.servo [AXIS_Y].offset )); // RT版に合わせて+180°しています。
146
153
vTaskDelay (10 /portTICK_PERIOD_MS);
147
- _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330 (y + 90 + _init_param.servo [AXIS_Y].offset ));
148
154
_isMoving = true ;
149
155
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
150
156
_isMoving = false ;
@@ -181,6 +187,10 @@ void StackchanSERVO::moveXY(int x, int y, uint32_t millis_for_move) {
181
187
}
182
188
_isMoving = false ;
183
189
} else if (_servo_type == ServoType::DYN_XL330) {
190
+ _isMoving = true ;
191
+ _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330 (x + _init_param.servo [AXIS_X].offset ));
192
+ _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330 (y + _init_param.servo [AXIS_Y].offset )); // RT版に合わせて+180°しています。
193
+ _isMoving = false ;
184
194
} else {
185
195
_servo_x.setEaseToD (x + _init_param.servo [AXIS_X].offset , millis_for_move);
186
196
_servo_y.setEaseToD (y + _init_param.servo [AXIS_Y].offset , millis_for_move);
@@ -201,6 +211,10 @@ void StackchanSERVO::moveXY(servo_param_s servo_param_x, servo_param_s servo_par
201
211
vTaskDelay (max (servo_param_x.millis_for_move , servo_param_y.millis_for_move )/portTICK_PERIOD_MS);
202
212
_isMoving = false ;
203
213
} else if (_servo_type == ServoType::DYN_XL330) {
214
+ _isMoving = true ;
215
+ _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330 (servo_param_x.degree + _init_param.servo [AXIS_X].offset ));
216
+ _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330 (servo_param_y.degree + _init_param.servo [AXIS_Y].offset )); // RT版に合わせて+180°しています。
217
+ _isMoving = false ;
204
218
} else {
205
219
if (servo_param_x.degree != 0 ) {
206
220
_servo_x.setEaseToD (servo_param_x.degree + servo_param_x.offset , servo_param_x.millis_for_move );
@@ -257,18 +271,3 @@ void StackchanSERVO::motion(Motion motion_number) {
257
271
moveXY (_init_param.servo [AXIS_X].start_degree , _init_param.servo [AXIS_Y].degree , 1000 );
258
272
}
259
273
260
- // Dynamixel XL330では移動時間の指定はできないので変換する。
261
- long StackchanSERVO::calcVelocity (ServoAxis axis_id, int16_t degree, uint32_t millis_for_move) {
262
- int16_t move_degree = 0 ;
263
- if (axis_id == ServoAxis::AXIS_X) {
264
- move_degree = abs (_last_degree_x - degree);
265
- } else {
266
- move_degree = abs (_last_degree_y - degree);
267
- }
268
-
269
- long rpm = (move_degree / 360 ) / (60 * (millis_for_move / 1000 ));
270
- M5_LOGI (" RPM: %d\n " , rpm);
271
- // return rpm;
272
-
273
- return 300 ;
274
- }
0 commit comments