@@ -8,6 +8,14 @@ long convertSCS0009Pos(int16_t degree) {
8
8
return map (degree, 0 , 300 , 1023 , 0 );
9
9
}
10
10
11
+ 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,41 @@ 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.torqueOn (AXIS_X + 1 );
56
+ _dxl.torqueOn (AXIS_Y + 1 );
57
+ _dxl.setOperatingMode (AXIS_X + 1 , OP_POSITION);
58
+ _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 );
62
+ _dxl.setGoalPosition (AXIS_X + 1 , 2048 );
63
+ _dxl.setGoalPosition (AXIS_Y + 1 , 3073 );
64
+ // _dxl.torqueOff(AXIS_X + 1);
65
+ // _dxl.torqueOff(AXIS_Y + 1);
66
+
38
67
} else {
39
68
// SG90 PWM
40
69
if (_servo_x.attach (_init_param.servo [AXIS_X].pin ,
@@ -81,6 +110,13 @@ void StackchanSERVO::moveX(int x, uint32_t millis_for_move) {
81
110
_isMoving = true ;
82
111
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
83
112
_isMoving = false ;
113
+ } else if (_servo_type == ServoType::DYN_XL330) {
114
+ _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_X + 1 , calcVelocity (ServoAxis::AXIS_X, x, millis_for_move));
115
+ vTaskDelay (10 /portTICK_PERIOD_MS);
116
+ _dxl.setGoalPosition (AXIS_X + 1 , convertDYNIXELXL330 (x + _init_param.servo [AXIS_X].offset ));
117
+ _isMoving = true ;
118
+ vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
119
+ _isMoving = false ;
84
120
} else {
85
121
if (millis_for_move == 0 ) {
86
122
_servo_x.easeTo (x + _init_param.servo [AXIS_X].offset );
@@ -100,11 +136,18 @@ void StackchanSERVO::moveX(servo_param_s servo_param_x) {
100
136
}
101
137
102
138
void StackchanSERVO::moveY (int y, uint32_t millis_for_move) {
103
- if (_servo_type == SCS) {
139
+ if (_servo_type == ServoType:: SCS) {
104
140
_sc.WritePos (AXIS_Y + 1 , convertSCS0009Pos (y + _init_param.servo [AXIS_Y].offset ), millis_for_move);
105
141
_isMoving = true ;
106
142
vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
107
143
_isMoving = false ;
144
+ } else if (_servo_type == ServoType::DYN_XL330) {
145
+ _dxl.writeControlTableItem (PROFILE_VELOCITY, AXIS_Y + 1 , calcVelocity (ServoAxis::AXIS_Y, y, millis_for_move));
146
+ vTaskDelay (10 /portTICK_PERIOD_MS);
147
+ _dxl.setGoalPosition (AXIS_Y + 1 , convertDYNIXELXL330 (y + 90 + _init_param.servo [AXIS_Y].offset ));
148
+ _isMoving = true ;
149
+ vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
150
+ _isMoving = false ;
108
151
} else {
109
152
if (millis_for_move == 0 ) {
110
153
_servo_y.easeTo (y + _init_param.servo [AXIS_Y].offset );
@@ -123,7 +166,7 @@ void StackchanSERVO::moveY(servo_param_s servo_param_y) {
123
166
moveY (servo_param_y.degree , servo_param_y.millis_for_move );
124
167
}
125
168
void StackchanSERVO::moveXY (int x, int y, uint32_t millis_for_move) {
126
- if (_servo_type == SCS) {
169
+ if (_servo_type == ServoType:: SCS) {
127
170
int increase_degree_x = x - _last_degree_x;
128
171
int increase_degree_y = y - _last_degree_y;
129
172
uint32_t division_time = millis_for_move / SERIAL_EASE_DIVISION;
@@ -137,6 +180,7 @@ void StackchanSERVO::moveXY(int x, int y, uint32_t millis_for_move) {
137
180
// vTaskDelay(division_time);
138
181
}
139
182
_isMoving = false ;
183
+ } else if (_servo_type == ServoType::DYN_XL330) {
140
184
} else {
141
185
_servo_x.setEaseToD (x + _init_param.servo [AXIS_X].offset , millis_for_move);
142
186
_servo_y.setEaseToD (y + _init_param.servo [AXIS_Y].offset , millis_for_move);
@@ -150,12 +194,13 @@ void StackchanSERVO::moveXY(int x, int y, uint32_t millis_for_move) {
150
194
}
151
195
152
196
void StackchanSERVO::moveXY (servo_param_s servo_param_x, servo_param_s servo_param_y) {
153
- if (_servo_type == SCS) {
197
+ if (_servo_type == ServoType:: SCS) {
154
198
_sc.WritePos (AXIS_X + 1 , convertSCS0009Pos (servo_param_x.degree + servo_param_x.offset ), servo_param_x.millis_for_move );
155
199
_sc.WritePos (AXIS_Y + 1 , convertSCS0009Pos (servo_param_y.degree + servo_param_y.offset ), servo_param_y.millis_for_move );
156
200
_isMoving = true ;
157
201
vTaskDelay (max (servo_param_x.millis_for_move , servo_param_y.millis_for_move )/portTICK_PERIOD_MS);
158
202
_isMoving = false ;
203
+ } else if (_servo_type == ServoType::DYN_XL330) {
159
204
} else {
160
205
if (servo_param_x.degree != 0 ) {
161
206
_servo_x.setEaseToD (servo_param_x.degree + servo_param_x.offset , servo_param_x.millis_for_move );
@@ -211,3 +256,19 @@ void StackchanSERVO::motion(Motion motion_number) {
211
256
delay (1000 );
212
257
moveXY (_init_param.servo [AXIS_X].start_degree , _init_param.servo [AXIS_Y].degree , 1000 );
213
258
}
259
+
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