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
+ static long convertDYNIXELXL330 (int16_t degree) {
12
+ M5_LOGI (" Degree: %d\n " , degree);
13
+
14
+ long ret = map (degree, 0 , 360 , 0 , 4095 );
15
+ M5_LOGI (" Position: %d\n " , ret);
16
+ return ret;
17
+ }
18
+
11
19
// シリアルサーボ用のEasing関数
12
20
float quadraticEaseInOut (float p) {
13
21
// return p;
@@ -21,20 +29,45 @@ float quadraticEaseInOut(float p) {
21
29
}
22
30
}
23
31
32
+
24
33
StackchanSERVO::StackchanSERVO () {}
25
34
26
35
StackchanSERVO::~StackchanSERVO () {}
27
36
28
37
29
38
void StackchanSERVO::attachServos () {
30
- if (_servo_type == SCS) {
39
+ if (_servo_type == ServoType:: SCS) {
31
40
// SCS0009
32
41
Serial2.begin (1000000 , SERIAL_8N1, _init_param.servo [AXIS_X].pin , _init_param.servo [AXIS_Y].pin );
33
42
_sc.pSerial = &Serial2;
34
43
_sc.WritePos (AXIS_X + 1 , convertSCS0009Pos (_init_param.servo [AXIS_X].start_degree + _init_param.servo [AXIS_X].offset ), 1000 );
35
44
_sc.WritePos (AXIS_Y + 1 , convertSCS0009Pos (_init_param.servo [AXIS_Y].start_degree + _init_param.servo [AXIS_Y].offset ), 1000 );
36
45
vTaskDelay (1000 /portTICK_PERIOD_MS);
37
46
47
+ } else if (_servo_type == ServoType::DYN_XL330) {
48
+ M5_LOGI (" DYN_XL330" );
49
+ Serial2.begin (1000000 , SERIAL_8N1, _init_param.servo [AXIS_X].pin , _init_param.servo [AXIS_Y].pin );
50
+ _dxl = Dynamixel2Arduino (Serial2);
51
+ _dxl.begin (1000000 );
52
+ _dxl.setPortProtocolVersion (DXL_PROTOCOL_VERSION);
53
+ _dxl.ping (AXIS_X + 1 );
54
+ _dxl.ping (AXIS_Y + 1 );
55
+ _dxl.setOperatingMode (AXIS_X + 1 , OP_POSITION);
56
+ _dxl.setOperatingMode (AXIS_Y + 1 , OP_POSITION);
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 );
66
+ _dxl.setGoalPosition (AXIS_X + 1 , 2048 );
67
+ _dxl.setGoalPosition (AXIS_Y + 1 , 3073 );
68
+ // _dxl.torqueOff(AXIS_X + 1);
69
+ // _dxl.torqueOff(AXIS_Y + 1);
70
+
38
71
} else {
39
72
// SG90 PWM
40
73
if (_servo_x.attach (_init_param.servo [AXIS_X].pin ,
@@ -47,7 +80,7 @@ void StackchanSERVO::attachServos() {
47
80
_init_param.servo [AXIS_Y].start_degree + _init_param.servo [AXIS_Y].offset ,
48
81
DEFAULT_MICROSECONDS_FOR_0_DEGREE,
49
82
DEFAULT_MICROSECONDS_FOR_180_DEGREE)) {
50
- Serial.print (" Error attaching servo x " );
83
+ Serial.print (" Error attaching servo y " );
51
84
}
52
85
53
86
_servo_x.setEasingType (EASE_QUADRATIC_IN_OUT);
@@ -81,6 +114,14 @@ void StackchanSERVO::moveX(int x, uint32_t millis_for_move) {
81
114
_isMoving = true ;
82
115
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
83
116
_isMoving = false ;
117
+ } else if (_servo_type == ServoType::DYN_XL330) {
118
+ _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , millis_for_move);
119
+ vTaskDelay (10 /portTICK_PERIOD_MS);
120
+ _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330 (x + _init_param.servo [AXIS_X].offset ));
121
+ vTaskDelay (10 /portTICK_PERIOD_MS);
122
+ _isMoving = true ;
123
+ vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
124
+ _isMoving = false ;
84
125
} else {
85
126
if (millis_for_move == 0 ) {
86
127
_servo_x.easeTo (x + _init_param.servo [AXIS_X].offset );
@@ -100,11 +141,19 @@ void StackchanSERVO::moveX(servo_param_s servo_param_x) {
100
141
}
101
142
102
143
void StackchanSERVO::moveY (int y, uint32_t millis_for_move) {
103
- if (_servo_type == SCS) {
144
+ if (_servo_type == ServoType:: SCS) {
104
145
_sc.WritePos (AXIS_Y + 1 , convertSCS0009Pos (y + _init_param.servo [AXIS_Y].offset ), millis_for_move);
105
146
_isMoving = true ;
106
147
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
107
148
_isMoving = false ;
149
+ } else if (_servo_type == ServoType::DYN_XL330) {
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°しています。
153
+ vTaskDelay (10 /portTICK_PERIOD_MS);
154
+ _isMoving = true ;
155
+ vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
156
+ _isMoving = false ;
108
157
} else {
109
158
if (millis_for_move == 0 ) {
110
159
_servo_y.easeTo (y + _init_param.servo [AXIS_Y].offset );
@@ -123,7 +172,7 @@ void StackchanSERVO::moveY(servo_param_s servo_param_y) {
123
172
moveY (servo_param_y.degree , servo_param_y.millis_for_move );
124
173
}
125
174
void StackchanSERVO::moveXY (int x, int y, uint32_t millis_for_move) {
126
- if (_servo_type == SCS) {
175
+ if (_servo_type == ServoType:: SCS) {
127
176
int increase_degree_x = x - _last_degree_x;
128
177
int increase_degree_y = y - _last_degree_y;
129
178
uint32_t division_time = millis_for_move / SERIAL_EASE_DIVISION;
@@ -137,6 +186,11 @@ void StackchanSERVO::moveXY(int x, int y, uint32_t millis_for_move) {
137
186
// vTaskDelay(division_time);
138
187
}
139
188
_isMoving = false ;
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 ;
140
194
} else {
141
195
_servo_x.setEaseToD (x + _init_param.servo [AXIS_X].offset , millis_for_move);
142
196
_servo_y.setEaseToD (y + _init_param.servo [AXIS_Y].offset , millis_for_move);
@@ -150,12 +204,17 @@ void StackchanSERVO::moveXY(int x, int y, uint32_t millis_for_move) {
150
204
}
151
205
152
206
void StackchanSERVO::moveXY (servo_param_s servo_param_x, servo_param_s servo_param_y) {
153
- if (_servo_type == SCS) {
207
+ if (_servo_type == ServoType:: SCS) {
154
208
_sc.WritePos (AXIS_X + 1 , convertSCS0009Pos (servo_param_x.degree + servo_param_x.offset ), servo_param_x.millis_for_move );
155
209
_sc.WritePos (AXIS_Y + 1 , convertSCS0009Pos (servo_param_y.degree + servo_param_y.offset ), servo_param_y.millis_for_move );
156
210
_isMoving = true ;
157
211
vTaskDelay (max (servo_param_x.millis_for_move , servo_param_y.millis_for_move )/portTICK_PERIOD_MS);
158
212
_isMoving = false ;
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 ;
159
218
} else {
160
219
if (servo_param_x.degree != 0 ) {
161
220
_servo_x.setEaseToD (servo_param_x.degree + servo_param_x.offset , servo_param_x.millis_for_move );
@@ -211,3 +270,4 @@ void StackchanSERVO::motion(Motion motion_number) {
211
270
delay (1000 );
212
271
moveXY (_init_param.servo [AXIS_X].start_degree , _init_param.servo [AXIS_Y].degree , 1000 );
213
272
}
273
+
0 commit comments