Files
Samuel Sadok 7fd0806d49 introduce InputPort and OutputPort, don't use NAN
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.
2020-09-23 16:20:21 +02:00

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