Skip to content

Commit ac0d04a

Browse files
committed
Fixed bugs and added missing parts
1 parent ab38853 commit ac0d04a

File tree

6 files changed

+63
-50
lines changed

6 files changed

+63
-50
lines changed

README.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,12 @@ platformio.iniのlib_depsに下記の記述を追加してください。(その
77

88
```
99
lib_deps =
10-
11-
arminjo/ServoEasing@^2.4.0
12-
madhephaestus/ESP32Servo @ 0.13.0
13-
bblanchon/ArduinoJson @ ^6
14-
tobozo/YAMLDuino
1510
https://github.com/mongonta0716/stackchan-arduino.git
16-
https://github.com/mongonta0716/SCServo
1711
lib_ldf_mode = deep ; これを忘れるとリンクエラーになります。
1812
```
1913

2014
# 設定ファイル
15+
設定内容は各ファイルに詳しくコメントしています。
2116
- [SC_BasicConfig.yaml](./data/yaml/SC_BasicConfig.yaml)<br>スタックチャンを起動するために必要な基本的なパラメータを集めています。
2217
- [SC_SecConfig.yaml](./data/yaml/SC_SecConfig.yaml)<br>個人情報用の設定ファイルです。(WiFiやAPIKey等)
2318
- [SC_ExConfig.yaml](./data/yaml/SC_ExConfig.yaml)<br>アプリケーション側で、設定を追加したいときに使用します。使い方はexamples/Advanceを参照してください。

data/yaml/SC_BasicConfig.yaml

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,30 @@ servo:
33
# ServoPin
44
# Core1 PortA X:22,Y:21 PortC X:16,Y:17
55
# Core2 PortA X:33,Y:32 PortC X:13,Y:14
6+
# CoreS3 PortA X:2, Y:1 PortB X:9, Y:8 PortC X:17, Y:18
67
# Stack-chanPCB Core1 X:5,Y:2 Core2 X:19,Y27
7-
# When using SCS0009, x:RX, y:TX (not used).(StackchanRT Version:Core1 x16,y17, Core2: x13,y14)
8+
# When using SCS0009 or Dynamixel XL330, x:RX, y:TX (not used).(StackchanRT Version:Core1 x16,y17, Core2: x13,y14)
89
x: 17
910
y: 18
1011
offset:
1112
# Specified by +- from 90 degree during servo initialization
1213
x: 0
1314
y: 0
15+
center:
16+
# サーボの初期位置
17+
# SG90: x:90 y:90
18+
# SCS0009: x:150, y:150
19+
# Dynamixel XL330: x:180, y:270
20+
x: 90
21+
y: 90
22+
lower_limit:
23+
# 可動範囲の下限(下限と言っても取り付け方により逆の場合あり, 値の小さい方を指定。)
24+
x: 0
25+
y: 60
26+
upper_limit:
27+
# 可動範囲の上限(上限と言っても取り付け方により逆の場合もあり, 値の大きい方を指定。)
28+
x: 90
29+
y: 100
1430
speed:
1531
normal_mode:
1632
interval_min: 3000
@@ -42,8 +58,10 @@ led_lr: 0 # 0:stereo, 1:left_only, 2:right_only
4258
led_pin: 15 # GoBottom1:15 GoBottom2:25
4359
takao_base: false # Whether to use takaobase to feed power from the rear connector.(Stack-chan_Takao_Base https://ssci.to/8905)
4460
servo_type: "PWM" # "PWM": SG90PWMServo, "SCS": Feetech SCS0009 "DYN_XL330": Dynamixel XL330
45-
extend_config_filename: "/yaml/SC_ExConfig.yaml" # Configuration file for the application.
46-
extend_config_filesize: 2048 # Buffer size for feature extensions
47-
secret_config_filename: "/yaml/SC_SecConfig.yaml" # Configuration file for the File for personal information.
48-
secret_config_filesize: 2048 # Buffer size for personal information.
49-
secret_info_show: true # Whether personal information is output to the log or not.
61+
62+
# 下記は拡張用の設定ファイルを使用する場合に設定します。(初期値はありません。)
63+
extend_config_filename: "" # "/yaml/SC_ExConfig.yaml" # Configuration file for the application.
64+
extend_config_filesize: 0 # 2048 # Buffer size for feature extensions
65+
secret_config_filename: "" # "/yaml/SC_SecConfig.yaml" # Configuration file for the File for personal information.
66+
secret_config_filesize: 0 # 2048 # Buffer size for personal information.
67+
secret_info_show: true # Whether personal information is output to the log or not.

library.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"version": "^6"
3838
},
3939
{
40-
"owner": "roboies-git",
40+
"owner": "robotis-git",
4141
"name": "Dynamixel2Arduino",
4242
"version": "^0.7.0"
4343
},
@@ -47,8 +47,8 @@
4747
"version": "1.4.2"
4848
},
4949
{
50-
"name": "SCSServo",
51-
"version": "https://github.com/mongonta0716/SCSServo.git"
50+
"name": "SCServo",
51+
"version": "https://github.com/mongonta0716/SCServo.git"
5252
}
5353
],
5454
"version": "0.0.1",

src/Stackchan_servo.cpp

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33

44
#include <ServoEasing.hpp>
55

6-
long convertSCS0009Pos(int16_t degree) {
6+
static long convertSCS0009Pos(int16_t degree) {
77
//Serial.printf("Degree: %d\n", degree);
88
return map(degree, 0, 300, 1023, 0);
99
}
1010

11-
long convertDYNIXELXL330(int16_t degree) {
11+
static long convertDYNIXELXL330(int16_t degree) {
1212
M5_LOGI("Degree: %d\n", degree);
1313

1414
long ret = map(degree, 0, 360, 0, 4095);
@@ -52,13 +52,17 @@ void StackchanSERVO::attachServos() {
5252
_dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
5353
_dxl.ping(AXIS_X + 1);
5454
_dxl.ping(AXIS_Y + 1);
55-
_dxl.torqueOn(AXIS_X + 1);
56-
_dxl.torqueOn(AXIS_Y + 1);
5755
_dxl.setOperatingMode(AXIS_X + 1, OP_POSITION);
5856
_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);
6266
_dxl.setGoalPosition(AXIS_X + 1, 2048);
6367
_dxl.setGoalPosition(AXIS_Y + 1, 3073);
6468
//_dxl.torqueOff(AXIS_X + 1);
@@ -76,7 +80,7 @@ void StackchanSERVO::attachServos() {
7680
_init_param.servo[AXIS_Y].start_degree + _init_param.servo[AXIS_Y].offset,
7781
DEFAULT_MICROSECONDS_FOR_0_DEGREE,
7882
DEFAULT_MICROSECONDS_FOR_180_DEGREE)) {
79-
Serial.print("Error attaching servo x");
83+
Serial.print("Error attaching servo y");
8084
}
8185

8286
_servo_x.setEasingType(EASE_QUADRATIC_IN_OUT);
@@ -111,9 +115,10 @@ void StackchanSERVO::moveX(int x, uint32_t millis_for_move) {
111115
vTaskDelay(millis_for_move/portTICK_PERIOD_MS);
112116
_isMoving = false;
113117
} 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);
115119
vTaskDelay(10/portTICK_PERIOD_MS);
116120
_dxl.setGoalPosition(AXIS_X + 1, convertDYNIXELXL330(x + _init_param.servo[AXIS_X].offset));
121+
vTaskDelay(10/portTICK_PERIOD_MS);
117122
_isMoving = true;
118123
vTaskDelay(millis_for_move/portTICK_PERIOD_MS);
119124
_isMoving = false;
@@ -142,9 +147,10 @@ void StackchanSERVO::moveY(int y, uint32_t millis_for_move) {
142147
vTaskDelay(millis_for_move/portTICK_PERIOD_MS);
143148
_isMoving = false;
144149
} 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°しています。
146153
vTaskDelay(10/portTICK_PERIOD_MS);
147-
_dxl.setGoalPosition(AXIS_Y + 1, convertDYNIXELXL330(y + 90 + _init_param.servo[AXIS_Y].offset));
148154
_isMoving = true;
149155
vTaskDelay(millis_for_move/portTICK_PERIOD_MS);
150156
_isMoving = false;
@@ -181,6 +187,10 @@ void StackchanSERVO::moveXY(int x, int y, uint32_t millis_for_move) {
181187
}
182188
_isMoving = false;
183189
} 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;
184194
} else {
185195
_servo_x.setEaseToD(x + _init_param.servo[AXIS_X].offset, millis_for_move);
186196
_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
201211
vTaskDelay(max(servo_param_x.millis_for_move, servo_param_y.millis_for_move)/portTICK_PERIOD_MS);
202212
_isMoving = false;
203213
} 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;
204218
} else {
205219
if (servo_param_x.degree != 0) {
206220
_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) {
257271
moveXY(_init_param.servo[AXIS_X].start_degree, _init_param.servo[AXIS_Y].degree, 1000);
258272
}
259273

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-
}

src/Stackchan_servo.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,5 @@ class StackchanSERVO {
8282
void moveXY(servo_param_s servo_param_x, servo_param_s servo_param_y);
8383
void motion(Motion motion_no);
8484
bool isMoving() { return _isMoving; }
85-
long calcVelocity(ServoAxis axis_id, int16_t degree, uint32_t millis_for_move);
8685
};
8786
#endif // _STACKCHAN_SERVO_H_

src/Stackchan_system_config.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ StackchanSystemConfig::~StackchanSystemConfig() {
1111
}
1212

1313
void StackchanSystemConfig::setDefaultParameters() {
14+
// 設定ファイルが存在しないときはデフォルトパラメータを使用します。
15+
// PWM サーボでPort.Aを想定しています。
1416
switch(M5.getBoard()) {
1517
case m5::board_t::board_M5StackCore2:
1618
_servo[AXIS_X].pin = 33;
@@ -92,7 +94,7 @@ void StackchanSystemConfig::loadConfig(fs::FS& fs, const char *app_yaml_filename
9294
if (secret_yaml_filesize > 0) {
9395
loadSecretConfig(fs, secret_yaml_filename, secret_yaml_filesize);
9496
}
95-
if (app_yaml_filename > 0) {
97+
if (app_yaml_filesize > 0) {
9698
loadExtendConfig(fs, app_yaml_filename, app_yaml_filesize);
9799
}
98100
printAllParameters();
@@ -138,6 +140,9 @@ void StackchanSystemConfig::setSystemConfig(DynamicJsonDocument doc) {
138140
_servo[AXIS_X].offset = servo["offset"]["x"];
139141
_servo[AXIS_Y].offset = servo["offset"]["y"];
140142

143+
_servo[AXIS_X].start_degree = servo["center"]["x"];
144+
_servo[AXIS_Y].start_degree = servo["center"]["y"];
145+
141146
_servo[AXIS_X].lower_limit = servo["lower_limit"]["x"];
142147
_servo[AXIS_X].upper_limit = servo["upper_limit"]["x"];
143148
_servo[AXIS_Y].lower_limit = servo["lower_limit"]["y"];
@@ -174,17 +179,12 @@ void StackchanSystemConfig::setSystemConfig(DynamicJsonDocument doc) {
174179
if (_servo_type_str.indexOf("SCS") != -1) {
175180
// SCS0009
176181
_servo_type = ServoType::SCS;
177-
_servo[AXIS_X].start_degree = 150;
178-
_servo[AXIS_Y].start_degree = 150;
179182
} else if (_servo_type_str.indexOf("DYN_XL330") != -1) {
180183
// Dynamixel XL330
181184
_servo_type = ServoType::DYN_XL330;
182-
_servo[AXIS_X].start_degree = 180;
183-
_servo[AXIS_Y].start_degree = 180;
184185
} else {
185-
_servo_type = ServoType::PWM; // PWMサーボ
186-
_servo[AXIS_X].start_degree = 90;
187-
_servo[AXIS_Y].start_degree = 90;
186+
// PWMサーボ
187+
_servo_type = ServoType::PWM;
188188
}
189189
_secret_config_show = doc["secret_config_show"].as<bool>();
190190
}
@@ -216,6 +216,8 @@ void StackchanSystemConfig::printAllParameters() {
216216
M5_LOGI("servo:pin_y:%d", _servo[AXIS_Y].pin);
217217
M5_LOGI("servo:offset_x:%d", _servo[AXIS_X].offset);
218218
M5_LOGI("servo:offset_y:%d", _servo[AXIS_Y].offset);
219+
M5_LOGI("servo.start_degree_x:%d", _servo[AXIS_X].start_degree);
220+
M5_LOGI("servo.start_degree_y:%d", _servo[AXIS_Y].start_degree);
219221
M5_LOGI("servo.lower_limit_x:%d", _servo[AXIS_X].lower_limit);
220222
M5_LOGI("servo.lower_limit_y:%d", _servo[AXIS_Y].lower_limit);
221223
M5_LOGI("servo.upper_limit_x:%d", _servo[AXIS_X].upper_limit);

0 commit comments

Comments
 (0)