ODrive icon indicating copy to clipboard operation
ODrive copied to clipboard

Position control with loaded encoder issues

Open fllmn opened this issue 4 years ago • 0 comments

Describe the bug

  • Homing does not reset the loaded encoder position
  • CAN interface reads position estimate from "own" encoder

To Reproduce

  • Use secondary encoder input with an incremental encoder and use as position/velocity feedback (use hall sensors on primary input) odrv.axis0.controller.config.load_encoder_axis = 1. Home the axis and move to position 0. Motor will move since odrv.axis1.encoder did not reset.
  • Query the position over CAN and you'll notice an offset when reaching position due to a lower resolution of the hall sensors

Solution I found a solution but I'm not sure it's the right way to do it. Basically during homing, reset the loaded encoder if it's different from self.

 1 file changed, 6 insertions(+)

diff --git a/Firmware/MotorControl/axis.cpp b/Firmware/MotorControl/axis.cpp
index 0f834d0b..2a9336a9 100644
--- a/Firmware/MotorControl/axis.cpp
+++ b/Firmware/MotorControl/axis.cpp
@@ -438,6 +438,12 @@ bool Axis::run_homing() {
 
     // Set the current position to 0.
     encoder_.set_linear_count(0);
+    // Set loaded encoder position to 0 if used
+    if (controller_.config_.load_encoder_axis != axis_num_ && controller_.config_.load_encoder_axis < AXIS_COUNT)
+    {
+        Axis* ax = &axes[controller_.config_.load_encoder_axis];
+        ax->encoder_.set_linear_count(0);
+    }
     controller_.input_pos_ = 0;
     controller_.input_pos_updated(); 

Use InputPort from the controller instead of the OutputPort from the encoder

 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Firmware/communication/can/can_simple.cpp b/Firmware/communication/can/can_simple.cpp
index a7af01ef..d9e64472 100644
--- a/Firmware/communication/can/can_simple.cpp
+++ b/Firmware/communication/can/can_simple.cpp
@@ -221,8 +221,8 @@ bool CANSimple::get_encoder_estimates_callback(const Axis& axis) {
     txmsg.isExt = axis.config_.can.is_extended;
     txmsg.len = 8;
 
-    can_setSignal<float>(txmsg, axis.encoder_.pos_estimate_.any().value_or(0.0f), 0, 32, true);
-    can_setSignal<float>(txmsg, axis.encoder_.vel_estimate_.any().value_or(0.0f), 32, 32, true);
+    can_setSignal<float>(txmsg, axis.controller_.pos_estimate_linear_src_.any().value_or(0.0f), 0, 32, true);
+    can_setSignal<float>(txmsg, axis.controller_.vel_estimate_src_.any().value_or(0.0f), 32, 32, true);
 
     return canbus_->send_message(txmsg);
 }

Happy to send a PR if you're happy with the proposals

fllmn avatar Dec 27 '21 08:12 fllmn