mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-08-19 19:32:00 +08:00
The InputPort/OutputPort infrastructure facilitates safer data paths between components: OutputPorts store a value and the age of the value measured in number of control loop iterations. InputPorts can be connected to various sources, for instance an OutputPort. InputPorts expose the values to consumers in the form of std::optional to reflect the fact that an InputPort can be dangling or connected to a stale OutputPort.
109 lines
3.9 KiB
C++
109 lines
3.9 KiB
C++
#ifndef __CONTROLLER_HPP
|
|
#define __CONTROLLER_HPP
|
|
|
|
class Controller : public ODriveIntf::ControllerIntf {
|
|
public:
|
|
typedef struct {
|
|
uint32_t index = 0;
|
|
float cogging_map[3600];
|
|
bool pre_calibrated = false;
|
|
bool calib_anticogging = false;
|
|
float calib_pos_threshold = 1.0f;
|
|
float calib_vel_threshold = 1.0f;
|
|
float cogging_ratio = 1.0f;
|
|
bool anticogging_enabled = true;
|
|
} Anticogging_t;
|
|
|
|
struct Config_t {
|
|
ControlMode control_mode = CONTROL_MODE_POSITION_CONTROL; //see: ControlMode_t
|
|
InputMode input_mode = INPUT_MODE_PASSTHROUGH; //see: InputMode_t
|
|
float pos_gain = 20.0f; // [(turn/s) / turn]
|
|
float vel_gain = 1.0f / 6.0f; // [Nm/(turn/s)]
|
|
// float vel_gain = 0.2f / 200.0f, // [Nm/(rad/s)] <sensorless example>
|
|
float vel_integrator_gain = 2.0f / 6.0f; // [Nm/(turn/s * s)]
|
|
float vel_limit = 2.0f; // [turn/s] Infinity to disable.
|
|
float vel_limit_tolerance = 1.2f; // ratio to vel_lim. Infinity to disable.
|
|
float vel_ramp_rate = 1.0f; // [(turn/s) / s]
|
|
float torque_ramp_rate = 0.01f; // Nm / sec
|
|
bool circular_setpoints = false;
|
|
float circular_setpoint_range = 1.0f; // Circular range when circular_setpoints is true. [turn]
|
|
float inertia = 0.0f; // [Nm/(turn/s^2)]
|
|
float input_filter_bandwidth = 2.0f; // [1/s]
|
|
float homing_speed = 0.25f; // [turn/s]
|
|
Anticogging_t anticogging;
|
|
float gain_scheduling_width = 10.0f;
|
|
bool enable_gain_scheduling = false;
|
|
bool enable_vel_limit = true;
|
|
bool enable_overspeed_error = true;
|
|
bool enable_current_mode_vel_limit = true; // enable velocity limit in current control mode (requires a valid velocity estimator)
|
|
uint8_t axis_to_mirror = -1;
|
|
float mirror_ratio = 1.0f;
|
|
uint8_t load_encoder_axis = -1; // default depends on Axis number and is set in load_configuration(). Set to -1 to select sensorless estimator.
|
|
|
|
// custom setters
|
|
Controller* parent;
|
|
void set_input_filter_bandwidth(float value) { input_filter_bandwidth = value; parent->update_filter_gains(); }
|
|
};
|
|
|
|
Controller() {}
|
|
|
|
bool apply_config();
|
|
|
|
void reset();
|
|
void set_error(Error error);
|
|
|
|
constexpr void input_pos_updated() {
|
|
input_pos_updated_ = true;
|
|
}
|
|
|
|
bool select_encoder(size_t encoder_num);
|
|
|
|
// Trajectory-Planned control
|
|
void move_to_pos(float goal_point);
|
|
void move_incremental(float displacement, bool from_goal_point);
|
|
|
|
// TODO: make this more similar to other calibration loops
|
|
void start_anticogging_calibration();
|
|
bool anticogging_calibration(float pos_estimate, float vel_estimate);
|
|
|
|
void update_filter_gains();
|
|
bool update();
|
|
|
|
Config_t config_;
|
|
Axis* axis_ = nullptr; // set by Axis constructor
|
|
|
|
Error error_ = ERROR_NONE;
|
|
|
|
// Inputs
|
|
InputPort<float> pos_estimate_linear_src_;
|
|
InputPort<float> pos_estimate_circular_src_;
|
|
InputPort<float> vel_estimate_src_;
|
|
InputPort<float> pos_wrap_src_;
|
|
|
|
float pos_setpoint_ = 0.0f; // [turns]
|
|
float vel_setpoint_ = 0.0f; // [turn/s]
|
|
// float vel_setpoint = 800.0f; <sensorless example>
|
|
float vel_integrator_torque_ = 0.0f; // [Nm]
|
|
float torque_setpoint_ = 0.0f; // [Nm]
|
|
|
|
float input_pos_ = 0.0f; // [turns]
|
|
float input_vel_ = 0.0f; // [turn/s]
|
|
float input_torque_ = 0.0f; // [Nm]
|
|
float input_filter_kp_ = 0.0f;
|
|
float input_filter_ki_ = 0.0f;
|
|
|
|
bool input_pos_updated_ = false;
|
|
|
|
bool trajectory_done_ = true;
|
|
|
|
bool anticogging_valid_ = false;
|
|
|
|
// Outputs
|
|
OutputPort<float> torque_output_ = 0.0f;
|
|
|
|
// custom setters
|
|
void set_input_pos(float value) { input_pos_ = value; input_pos_updated(); }
|
|
};
|
|
|
|
#endif // __CONTROLLER_HPP
|