Skip to content

Conversation

breakds
Copy link
Contributor

@breakds breakds commented Apr 23, 2024

Recently we are planning to use torque control for the gripper motor, while keeping all the rest of the motors with position control.

Previously, only position control is supported in the "wx armor" driver. This PR extends it so that current control, velocity control and PWM control are now supported. Specifically, a flag (environment variable) is introduced to turn on "PWM control" for the gripper, which approximately resembles the torque control.

The following changes are made to implement the above idea:

  1. In profile, now joint_motors are added so that we can directly iterate over the (main) motor of each joint.
  2. TORQUE control mode is removed from OpMode because it is not supported by the hardware.
  3. Environment variable WX_ARMOR_GRIPPER_PWM_CTRL is introduced as the flag to turn PWM control on gripper on and off.
  4. The syncWrite is now writing 5 bytes on each motor instead of 3 bytes. The two extra bytes are for the goal PWM, goal current and goal velocity.
  5. SetPosition is renamed to SendCommand as it is no longer position control only.
  6. Since we now have 5 bytes per motor to worry about, the code is refactored so that the SendCommand and InitWriteHandler is clearner. Specifically, which goal to set is now purely based on the OpMode of the motor.

How is it tested?

This is tested with the canonical policy on the deployment tool, with both the gripper pwm control turned on and off.

Note

We probably need to monitor the joint position of the gripper while in PWM mode so that it does not "over-open" the fingers.

@breakds breakds requested a review from le-horizon as a code owner April 23, 2024 23:54
@breakds breakds requested a review from QuantuMope April 23, 2024 23:54
QuantuMope
QuantuMope previously approved these changes Apr 24, 2024
Copy link
Contributor

@QuantuMope QuantuMope left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a small Nit. Overall, LGTM. The way you handled the multi address writes is very clean. Thanks for this update!

Comment on lines 489 to 518
inline void WritePosition(int32_t int_pos,
int32_t moving_time_ms,
int32_t acc_time_ms) {
buffer_ptr_[2] = acc_time_ms;
buffer_ptr_[3] = moving_time_ms;
buffer_ptr_[4] = int_pos;
buffer_ptr_ += NUM_DWORDS;
}

inline void WriteCurrent(float tau) {
int16_t int_current =
static_cast<int16_t>(std::round(NEWTON_METER_TO_INT_CURRENT * tau));
buffer_ptr_[0] = (int_current << 16) | PWM_LIMIT;
buffer_ptr_ += NUM_DWORDS;
}

inline void WritePWM(float tau) {
int16_t int_pwm =
static_cast<int16_t>(std::round(NEWTON_METER_TO_INT_PWM * tau));
// We need to put the 2 bytes (signed) integer PWM in the position of the
// lower 2 bytes at buffer's [0]. This is how we do it.
uint16_t unsigned_pwm = static_cast<uint16_t>(int_pwm);
buffer_ptr_[0] = 0 | unsigned_pwm;
buffer_ptr_ += NUM_DWORDS;
}

inline void WriteVelocity(int32_t int_velocity) {
buffer_ptr_[2] = int_velocity;
buffer_ptr_ += NUM_DWORDS;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Could be consistent and perform the conversions from real units to Dynamixel units within the functions for WritePosition and WriteVelocity similar to how WriteCurrent and WritePWM are written.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like this either. I actually deliberately implemented it this way so that the command buffer does not need to know about the workbench.

For some reason dynamixel has this annoying design that converting actually need dxl_wb as input.

I still think it is slightly better to keep dxl_wb out of this class.

le-horizon
le-horizon previously approved these changes Apr 30, 2024
Copy link
Contributor

@le-horizon le-horizon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG. Just noting that even with 0/1 command, there could still be sim2real differences in gripper open and close dynamics. It's best to verify and plot before actual deployment.

@breakds
Copy link
Contributor Author

breakds commented Apr 30, 2024

LG. Just noting that even with 0/1 command, there could still be sim2real differences in gripper open and close dynamics. It's best to verify and plot before actual deployment.

Agree. We will nee to test this with Jerry's checkpoint.

@breakds breakds dismissed stale reviews from le-horizon and QuantuMope February 27, 2025 22:43

The merge-base changed after approval.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants