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+ 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+
1119// シリアルサーボ用のEasing関数
1220float quadraticEaseInOut (float p) {
1321 // return p;
@@ -21,20 +29,45 @@ float quadraticEaseInOut(float p) {
2129 }
2230}
2331
32+
2433StackchanSERVO::StackchanSERVO () {}
2534
2635StackchanSERVO::~StackchanSERVO () {}
2736
2837
2938void StackchanSERVO::attachServos () {
30- if (_servo_type == SCS) {
39+ if (_servo_type == ServoType:: SCS) {
3140 // SCS0009
3241 Serial2.begin (1000000 , SERIAL_8N1, _init_param.servo [AXIS_X].pin , _init_param.servo [AXIS_Y].pin );
3342 _sc.pSerial = &Serial2;
3443 _sc.WritePos (AXIS_X + 1 , convertSCS0009Pos (_init_param.servo [AXIS_X].start_degree + _init_param.servo [AXIS_X].offset ), 1000 );
3544 _sc.WritePos (AXIS_Y + 1 , convertSCS0009Pos (_init_param.servo [AXIS_Y].start_degree + _init_param.servo [AXIS_Y].offset ), 1000 );
3645 vTaskDelay (1000 /portTICK_PERIOD_MS);
3746
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+
3871 } else {
3972 // SG90 PWM
4073 if (_servo_x.attach (_init_param.servo [AXIS_X].pin ,
@@ -47,7 +80,7 @@ void StackchanSERVO::attachServos() {
4780 _init_param.servo [AXIS_Y].start_degree + _init_param.servo [AXIS_Y].offset ,
4881 DEFAULT_MICROSECONDS_FOR_0_DEGREE,
4982 DEFAULT_MICROSECONDS_FOR_180_DEGREE)) {
50- Serial.print (" Error attaching servo x " );
83+ Serial.print (" Error attaching servo y " );
5184 }
5285
5386 _servo_x.setEasingType (EASE_QUADRATIC_IN_OUT);
@@ -81,6 +114,14 @@ void StackchanSERVO::moveX(int x, uint32_t millis_for_move) {
81114 _isMoving = true ;
82115 vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
83116 _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 ;
84125 } else {
85126 if (millis_for_move == 0 ) {
86127 _servo_x.easeTo (x + _init_param.servo [AXIS_X].offset );
@@ -100,11 +141,19 @@ void StackchanSERVO::moveX(servo_param_s servo_param_x) {
100141}
101142
102143void StackchanSERVO::moveY (int y, uint32_t millis_for_move) {
103- if (_servo_type == SCS) {
144+ if (_servo_type == ServoType:: SCS) {
104145 _sc.WritePos (AXIS_Y + 1 , convertSCS0009Pos (y + _init_param.servo [AXIS_Y].offset ), millis_for_move);
105146 _isMoving = true ;
106147 vTaskDelay (millis_for_move/portTICK_PERIOD_MS);
107148 _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 ;
108157 } else {
109158 if (millis_for_move == 0 ) {
110159 _servo_y.easeTo (y + _init_param.servo [AXIS_Y].offset );
@@ -123,7 +172,7 @@ void StackchanSERVO::moveY(servo_param_s servo_param_y) {
123172 moveY (servo_param_y.degree , servo_param_y.millis_for_move );
124173}
125174void StackchanSERVO::moveXY (int x, int y, uint32_t millis_for_move) {
126- if (_servo_type == SCS) {
175+ if (_servo_type == ServoType:: SCS) {
127176 int increase_degree_x = x - _last_degree_x;
128177 int increase_degree_y = y - _last_degree_y;
129178 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) {
137186 // vTaskDelay(division_time);
138187 }
139188 _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 ;
140194 } else {
141195 _servo_x.setEaseToD (x + _init_param.servo [AXIS_X].offset , millis_for_move);
142196 _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) {
150204}
151205
152206void 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) {
154208 _sc.WritePos (AXIS_X + 1 , convertSCS0009Pos (servo_param_x.degree + servo_param_x.offset ), servo_param_x.millis_for_move );
155209 _sc.WritePos (AXIS_Y + 1 , convertSCS0009Pos (servo_param_y.degree + servo_param_y.offset ), servo_param_y.millis_for_move );
156210 _isMoving = true ;
157211 vTaskDelay (max (servo_param_x.millis_for_move , servo_param_y.millis_for_move )/portTICK_PERIOD_MS);
158212 _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 ;
159218 } else {
160219 if (servo_param_x.degree != 0 ) {
161220 _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) {
211270 delay (1000 );
212271 moveXY (_init_param.servo [AXIS_X].start_degree , _init_param.servo [AXIS_Y].degree , 1000 );
213272}
273+
0 commit comments