Xl-320の制御方法で自由な位置で止める方法

xl-320を15個を制御して五脚ロボット制作しているのですが、プログラミングの知識が足りずArduino ideの例にあるposition_modeを工夫して使っていたのですが、このプログラミングだと自由な位置にいったら最後戻ってしまうためどうにか戻らないで自由な位置で止めたいのですが、プログラミングの仕方が分からないもでご教示お願い致します。

Have you tried setting the Present Position as being the “new” Goal Position, i.e.:

present_position = dxl.getPresentPosition(DXL_ID);
dxl.setGoalPosition(DXL_ID, present_position);

Thank you roboteer for your answer.
i will try.

I’m a beginner in programming, so could you please tell me what to change in this file?
I don’t usually use English so I’m sorry for my bad English.
position_mode1.ino (4.5 KB)

I am not clear on your question about what to change in the ino file you sent.

Which Arduino board are you using? Did this example code give you problems with XL-320s? And what kind of problems?

Arduino board is openRB-150
xL-320 worked without problems
Running the program in this file will eventually return you to the starting position. I want to stop at a specified position without returning to the starting position.

This example program was designed so that the XL-320 will bounce around between two Goal Positions. The First Position is Position 1000 (in RAW position unit and see line 92) and the Second Position is Position 5.7 (in unit of degrees and see Line 106).

If you want the XL-320 to bounce around between two other Goal Positions, then you need to change the “1000” value to something else (may be 900?) and the “5.7” value to like “15.5” for example.

image

In this example, the relevant code is put inside the loop() function so the bouncing repeats itself forever.

Do you mean that you want this operation to be performed only once? Then you have to move ALL the code from inside loop() into setup(). The loop() function should be empty.

Thank you roboteer for your answer.
i will try.

Changing the second 5.7 did not change the target position. I don’t know the cause

What did you change it to? Try a bigger change, like 45 degrees.
Do you still have the code inside the loop() function?

When I changed the value to 45, the target position changed.
However, when I went to setup() I got an error.

OK, this is my sketch when I keep the position changing code inside loop()

// position_mode_1_loop.ino
#include <Dynamixel2Arduino.h>
#define DXL_SERIAL Serial1
#define DEBUG_SERIAL Serial
const int DXL_DIR_PIN = -1;
const uint8_t DXL_ID = 1;
const float DXL_PROTOCOL_VERSION = 2.0;

Dynamixel2Arduino dxl(DXL_SERIAL, DXL_DIR_PIN);

//This namespace is required to use Control table item names
using namespace ControlTableItem;

void setup() {
  // put your setup code here, to run once:
  
  // Use UART port of DYNAMIXEL Shield to debug.
  DEBUG_SERIAL.begin(115200);
  while(!DEBUG_SERIAL);

  // Set Port baudrate to 1000000 bps. This has to match with DYNAMIXEL baudrate.
  dxl.begin(1000000);
  // Set Port Protocol Version. This has to match with DYNAMIXEL protocol version.
  dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
  // Get DYNAMIXEL information
  // dxl.ping(DXL_ID);

  // Turn off torque when configuring items in EEPROM area
  dxl.torqueOff(DXL_ID);
  dxl.setOperatingMode(DXL_ID, OP_POSITION);
  dxl.torqueOn(DXL_ID);

  // Limit the maximum velocity in Position Control Mode. Use 0 for Max speed
  dxl.writeControlTableItem(PROFILE_VELOCITY, DXL_ID, 100);

}

void loop() {
  // put your main code here, to run repeatedly:
    // Please refer to e-Manual(http://emanual.robotis.com/docs/en/parts/interface/dynamixel_shield/) for available range of value. 
  // Set Goal Position in RAW value
  dxl.setGoalPosition(DXL_ID, 1000);  // raw position set at 1000

  int i_present_position = 0;
  float f_present_position = 0.0;

  while (abs(1000 - i_present_position) > 10) // raw position set at 1000
  {  
    i_present_position = dxl.getPresentPosition(DXL_ID);
    DEBUG_SERIAL.print("Present_Position(raw) : ");
    DEBUG_SERIAL.println(i_present_position);
  }
  delay(1000);

  // Set Goal Position in DEGREE value
  dxl.setGoalPosition(DXL_ID, 45.0, UNIT_DEGREE);  // changed to 45 deg.
  
  while (abs(45.0 - f_present_position) > 2.0)  // changed to 45 deg.
  {
    f_present_position = dxl.getPresentPosition(DXL_ID, UNIT_DEGREE);
    DEBUG_SERIAL.print("Present_Position(degree) : ");
    DEBUG_SERIAL.println(f_present_position);
  }
  delay(1000);
 
}

and this is a video clip of what my XL-320 did at run time

Next is a sketch where I keep the position changing code inside setup()

// position_mode_1_setup.ino
#include <Dynamixel2Arduino.h>
#define DXL_SERIAL Serial1
#define DEBUG_SERIAL Serial
const int DXL_DIR_PIN = -1;
const uint8_t DXL_ID = 1;
const float DXL_PROTOCOL_VERSION = 2.0;

Dynamixel2Arduino dxl(DXL_SERIAL, DXL_DIR_PIN);

//This namespace is required to use Control table item names
using namespace ControlTableItem;

void setup() {
  // put your setup code here, to run once:
  
  // Use UART port of DYNAMIXEL Shield to debug.
  DEBUG_SERIAL.begin(115200);
  while(!DEBUG_SERIAL);

  // Set Port baudrate to 1000000 bps. This has to match with DYNAMIXEL baudrate.
  dxl.begin(1000000);
  // Set Port Protocol Version. This has to match with DYNAMIXEL protocol version.
  dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
  // Get DYNAMIXEL information
  // dxl.ping(DXL_ID);

  // Turn off torque when configuring items in EEPROM area
  dxl.torqueOff(DXL_ID);
  dxl.setOperatingMode(DXL_ID, OP_POSITION);
  dxl.torqueOn(DXL_ID);

  // Limit the maximum velocity in Position Control Mode. Use 0 for Max speed
  dxl.writeControlTableItem(PROFILE_VELOCITY, DXL_ID, 100);

// code moved to setup()

  // Please refer to e-Manual(http://emanual.robotis.com/docs/en/parts/interface/dynamixel_shield/) for available range of value. 
  // Set Goal Position in RAW value
  dxl.setGoalPosition(DXL_ID, 1000);  // raw position set at 1000

  int i_present_position = 0;
  float f_present_position = 0.0;

  while (abs(1000 - i_present_position) > 10) // raw position set at 1000
  {  
    i_present_position = dxl.getPresentPosition(DXL_ID);
    DEBUG_SERIAL.print("Present_Position(raw) : ");
    DEBUG_SERIAL.println(i_present_position);
  }
  delay(1000);

  // Set Goal Position in DEGREE value
  dxl.setGoalPosition(DXL_ID, 45.0, UNIT_DEGREE);  // changed to 45 deg.
  
  while (abs(45.0 - f_present_position) > 2.0)  // changed to 45 deg.
  {
    f_present_position = dxl.getPresentPosition(DXL_ID, UNIT_DEGREE);
    DEBUG_SERIAL.print("Present_Position(degree) : ");
    DEBUG_SERIAL.println(f_present_position);
  }
  delay(1000);
  
}

void loop() {
  // put your main code here, to run repeatedly:
  

}

And here is a video clip showing that it did the goal position changing only once.

Perhaps @toukairinn who is connected to ROBOTIS-Japan can help you better in Japanese.

And here is my sketch using a stop technique before the servo can reach its Final Goal Position

// position_mode_1_setup_stop.ino
#include <Dynamixel2Arduino.h>
#define DXL_SERIAL Serial1
#define DEBUG_SERIAL Serial
const int DXL_DIR_PIN = -1;
const uint8_t DXL_ID = 1;
const float DXL_PROTOCOL_VERSION = 2.0;

Dynamixel2Arduino dxl(DXL_SERIAL, DXL_DIR_PIN);

//This namespace is required to use Control table item names
using namespace ControlTableItem;

void setup() {
  // put your setup code here, to run once:
  
  // Use UART port of DYNAMIXEL Shield to debug.
  DEBUG_SERIAL.begin(115200);
  while(!DEBUG_SERIAL);

  // Set Port baudrate to 1000000 bps. This has to match with DYNAMIXEL baudrate.
  dxl.begin(1000000);
  // Set Port Protocol Version. This has to match with DYNAMIXEL protocol version.
  dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
  // Get DYNAMIXEL information
  // dxl.ping(DXL_ID);

  // Turn off torque when configuring items in EEPROM area
  dxl.torqueOff(DXL_ID);
  dxl.setOperatingMode(DXL_ID, OP_POSITION);
  dxl.torqueOn(DXL_ID);

  // Limit the maximum velocity in Position Control Mode. Use 0 for Max speed
  dxl.writeControlTableItem(PROFILE_VELOCITY, DXL_ID, 50);  // using a slower speed 

// code moved to setup()

  // Please refer to e-Manual(http://emanual.robotis.com/docs/en/parts/interface/dynamixel_shield/) for available range of value. 
  // Set Goal Position in RAW value
  dxl.setGoalPosition(DXL_ID, 1000);  // raw position set at 1000

  int i_present_position = 0;
  float f_present_position = 0.0;

  while (abs(1000 - i_present_position) > 10) // raw position set at 1000
  {  
    i_present_position = dxl.getPresentPosition(DXL_ID);
    DEBUG_SERIAL.print("Present_Position(raw) : ");
    DEBUG_SERIAL.println(i_present_position);
  }
  delay(1000);

  // Set Goal Position in DEGREE value
  dxl.setGoalPosition(DXL_ID, 45.0, UNIT_DEGREE);  // changed to 45 deg.
  // so at this point the XL-320 is on its way to Position 45 deg.
  delay(300); // make a short time delay so that the XL-320 does not reach 45 deg. yet
  // then to stop the servo somewhere before it reaches 45 deg. - try different time delay values
  f_present_position = dxl.getPresentPosition(DXL_ID, UNIT_DEGREE);
  dxl.setGoalPosition(DXL_ID, f_present_position, UNIT_DEGREE);  // servo stopped at present_position 
  DEBUG_SERIAL.print("Present_Position(degree) : ");
  DEBUG_SERIAL.println(f_present_position);


/*  
  while (abs(45.0 - f_present_position) > 2.0)  // changed to 45 deg.
  {
    f_present_position = dxl.getPresentPosition(DXL_ID, UNIT_DEGREE);
    DEBUG_SERIAL.print("Present_Position(degree) : ");
    DEBUG_SERIAL.println(f_present_position);
  }
  delay(1000);

  */
  
}

void loop() {
  // put your main code here, to run repeatedly:
  

}

When the time delay was set at 200 ms I got the servo stopped at 175.45 deg.

Stopped_175.45_200

When the time delay was set to 300 ms I got the servo stopped at 109.62 deg, i.e. the servo had 100 ms more to get closer to 45 deg.

Stopped_109.62_300

Thank you for your answer, robot. Thank you for your kindness.

Good to hear that you got your issue resolved.
Have fun with your project.