mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-09-27 13:23:52 +08:00
Merge branch 'rc-v0.5.0' into rls_spi
This commit is contained in:
@@ -115,8 +115,15 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
|
|||||||
hdma_spi3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
hdma_spi3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||||
hdma_spi3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
hdma_spi3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||||
hdma_spi3_tx.Init.MemInc = DMA_MINC_ENABLE;
|
hdma_spi3_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||||
hdma_spi3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
|
||||||
hdma_spi3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
if(spiHandle->Init.DataSize == SPI_DATASIZE_8BIT){
|
||||||
|
hdma_spi3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||||
|
hdma_spi3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||||
|
} else {
|
||||||
|
hdma_spi3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||||
|
hdma_spi3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||||
|
}
|
||||||
|
|
||||||
hdma_spi3_tx.Init.Mode = DMA_NORMAL;
|
hdma_spi3_tx.Init.Mode = DMA_NORMAL;
|
||||||
hdma_spi3_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
|
hdma_spi3_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
|
||||||
hdma_spi3_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
hdma_spi3_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||||
@@ -133,8 +140,13 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
|
|||||||
hdma_spi3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
hdma_spi3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||||
hdma_spi3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
hdma_spi3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||||
hdma_spi3_rx.Init.MemInc = DMA_MINC_ENABLE;
|
hdma_spi3_rx.Init.MemInc = DMA_MINC_ENABLE;
|
||||||
hdma_spi3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
if (spiHandle->Init.DataSize == SPI_DATASIZE_8BIT) {
|
||||||
hdma_spi3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
hdma_spi3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||||
|
hdma_spi3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||||
|
} else {
|
||||||
|
hdma_spi3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||||
|
hdma_spi3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||||
|
}
|
||||||
hdma_spi3_rx.Init.Mode = DMA_NORMAL;
|
hdma_spi3_rx.Init.Mode = DMA_NORMAL;
|
||||||
hdma_spi3_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
|
hdma_spi3_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
|
||||||
hdma_spi3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
hdma_spi3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||||
|
|||||||
@@ -173,10 +173,9 @@ bool Axis::do_checks() {
|
|||||||
// controller_.do_checks();
|
// controller_.do_checks();
|
||||||
|
|
||||||
// Check for endstop presses
|
// Check for endstop presses
|
||||||
bool vel_dependent_stopping = (current_state_ == AXIS_STATE_HOMING) && (controller_.config_.control_mode >= Controller::CTRL_MODE_VELOCITY_CONTROL);
|
if (min_endstop_.config_.enabled && min_endstop_.get_state() && !(current_state_ == AXIS_STATE_HOMING)) {
|
||||||
if (min_endstop_.config_.enabled && min_endstop_.get_state() && (!vel_dependent_stopping || controller_.vel_setpoint_ < 0.0f)) {
|
|
||||||
error_ |= ERROR_MIN_ENDSTOP_PRESSED;
|
error_ |= ERROR_MIN_ENDSTOP_PRESSED;
|
||||||
} else if (max_endstop_.config_.enabled && max_endstop_.get_state() && (!vel_dependent_stopping || controller_.vel_setpoint_ > 0.0f)) {
|
} else if (max_endstop_.config_.enabled && max_endstop_.get_state() && !(current_state_ == AXIS_STATE_HOMING)) {
|
||||||
error_ |= ERROR_MAX_ENDSTOP_PRESSED;
|
error_ |= ERROR_MAX_ENDSTOP_PRESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ public:
|
|||||||
controller_.error_ = Controller::ERROR_NONE;
|
controller_.error_ = Controller::ERROR_NONE;
|
||||||
sensorless_estimator_.error_ = SensorlessEstimator::ERROR_NONE;
|
sensorless_estimator_.error_ = SensorlessEstimator::ERROR_NONE;
|
||||||
encoder_.error_ = Encoder::ERROR_NONE;
|
encoder_.error_ = Encoder::ERROR_NONE;
|
||||||
|
encoder_.spi_error_rate_ = 0.0f;
|
||||||
|
|
||||||
error_ = Axis::ERROR_NONE;
|
error_ = Axis::ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,8 +181,8 @@ bool Encoder::run_direction_find() {
|
|||||||
// and the encoder state 0.
|
// and the encoder state 0.
|
||||||
// TODO: Do the scan with current, not voltage!
|
// TODO: Do the scan with current, not voltage!
|
||||||
bool Encoder::run_offset_calibration() {
|
bool Encoder::run_offset_calibration() {
|
||||||
static const float start_lock_duration = 1.0f;
|
const float start_lock_duration = 1.0f;
|
||||||
static const int num_steps = (int)(config_.calib_scan_distance / config_.calib_scan_omega * (float)current_meas_hz);
|
const int num_steps = (int)(config_.calib_scan_distance / config_.calib_scan_omega * (float)current_meas_hz);
|
||||||
|
|
||||||
// Require index found if enabled
|
// Require index found if enabled
|
||||||
if (config_.use_index && !index_found_) {
|
if (config_.use_index && !index_found_) {
|
||||||
@@ -440,6 +440,7 @@ void Encoder::abs_spi_cs_pin_init(){
|
|||||||
bool Encoder::update() {
|
bool Encoder::update() {
|
||||||
// update internal encoder state.
|
// update internal encoder state.
|
||||||
int32_t delta_enc = 0;
|
int32_t delta_enc = 0;
|
||||||
|
int32_t pos_abs_latched = pos_abs_; //LATCH
|
||||||
|
|
||||||
switch (mode_) {
|
switch (mode_) {
|
||||||
case MODE_INCREMENTAL: {
|
case MODE_INCREMENTAL: {
|
||||||
@@ -490,7 +491,7 @@ bool Encoder::update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abs_spi_pos_updated_ = false;
|
abs_spi_pos_updated_ = false;
|
||||||
delta_enc = pos_abs_ - count_in_cpr_;
|
delta_enc = pos_abs_latched - count_in_cpr_; //LATCH
|
||||||
delta_enc = mod(delta_enc, config_.cpr);
|
delta_enc = mod(delta_enc, config_.cpr);
|
||||||
if (delta_enc > config_.cpr/2) {
|
if (delta_enc > config_.cpr/2) {
|
||||||
delta_enc -= config_.cpr;
|
delta_enc -= config_.cpr;
|
||||||
@@ -508,7 +509,7 @@ bool Encoder::update() {
|
|||||||
count_in_cpr_ = mod(count_in_cpr_, config_.cpr);
|
count_in_cpr_ = mod(count_in_cpr_, config_.cpr);
|
||||||
|
|
||||||
if(mode_ & MODE_FLAG_ABS)
|
if(mode_ & MODE_FLAG_ABS)
|
||||||
count_in_cpr_ = pos_abs_;
|
count_in_cpr_ = pos_abs_latched;
|
||||||
|
|
||||||
//// run pll (for now pll is in units of encoder counts)
|
//// run pll (for now pll is in units of encoder counts)
|
||||||
// Predict current pos
|
// Predict current pos
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
/* Private macros ------------------------------------------------------------*/
|
/* Private macros ------------------------------------------------------------*/
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
/* Global constant data ------------------------------------------------------*/
|
/* Global constant data ------------------------------------------------------*/
|
||||||
const float adc_full_scale = (float)(1 << 12);
|
constexpr float adc_full_scale = static_cast<float>(1UL << 12UL);
|
||||||
const float adc_ref_voltage = 3.3f;
|
constexpr float adc_ref_voltage = 3.3f;
|
||||||
/* Global variables ----------------------------------------------------------*/
|
/* Global variables ----------------------------------------------------------*/
|
||||||
|
|
||||||
// This value is updated by the DC-bus reading ADC.
|
// This value is updated by the DC-bus reading ADC.
|
||||||
@@ -439,7 +439,7 @@ float get_adc_voltage(GPIO_TypeDef* GPIO_port, uint16_t GPIO_pin) {
|
|||||||
//--------------------------------
|
//--------------------------------
|
||||||
|
|
||||||
void vbus_sense_adc_cb(ADC_HandleTypeDef* hadc, bool injected) {
|
void vbus_sense_adc_cb(ADC_HandleTypeDef* hadc, bool injected) {
|
||||||
static const float voltage_scale = adc_ref_voltage * VBUS_S_DIVIDER_RATIO / adc_full_scale;
|
constexpr float voltage_scale = adc_ref_voltage * VBUS_S_DIVIDER_RATIO / adc_full_scale;
|
||||||
// Only one conversion in sequence, so only rank1
|
// Only one conversion in sequence, so only rank1
|
||||||
uint32_t ADCValue = HAL_ADCEx_InjectedGetValue(hadc, ADC_INJECTED_RANK_1);
|
uint32_t ADCValue = HAL_ADCEx_InjectedGetValue(hadc, ADC_INJECTED_RANK_1);
|
||||||
vbus_voltage = ADCValue * voltage_scale;
|
vbus_voltage = ADCValue * voltage_scale;
|
||||||
@@ -478,7 +478,7 @@ static void decode_hall_samples(Encoder& enc, uint16_t GPIO_samples[num_GPIO]) {
|
|||||||
// TODO: Document how the phasing is done, link to timing diagram
|
// TODO: Document how the phasing is done, link to timing diagram
|
||||||
void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc, bool injected) {
|
void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc, bool injected) {
|
||||||
#define calib_tau 0.2f //@TOTO make more easily configurable
|
#define calib_tau 0.2f //@TOTO make more easily configurable
|
||||||
static const float calib_filter_k = CURRENT_MEAS_PERIOD / calib_tau;
|
constexpr float calib_filter_k = CURRENT_MEAS_PERIOD / calib_tau;
|
||||||
|
|
||||||
// Ensure ADCs are expected ones to simplify the logic below
|
// Ensure ADCs are expected ones to simplify the logic below
|
||||||
if (!(hadc == &hadc2 || hadc == &hadc3)) {
|
if (!(hadc == &hadc2 || hadc == &hadc3)) {
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ void Motor::DRV8301_setup() {
|
|||||||
|
|
||||||
// Solve for exact gain, then snap down to have equal or larger range as requested
|
// Solve for exact gain, then snap down to have equal or larger range as requested
|
||||||
// or largest possible range otherwise
|
// or largest possible range otherwise
|
||||||
static const float kMargin = 0.90f;
|
constexpr float kMargin = 0.90f;
|
||||||
static const float kTripMargin = 1.0f; // Trip level is at edge of linear range of amplifer
|
constexpr float kTripMargin = 1.0f; // Trip level is at edge of linear range of amplifer
|
||||||
static const float max_output_swing = 1.35f; // [V] out of amplifier
|
constexpr float max_output_swing = 1.35f; // [V] out of amplifier
|
||||||
float max_unity_gain_current = kMargin * max_output_swing * hw_config_.shunt_conductance; // [A]
|
float max_unity_gain_current = kMargin * max_output_swing * hw_config_.shunt_conductance; // [A]
|
||||||
float requested_gain = max_unity_gain_current / config_.requested_current_range; // [V/V]
|
float requested_gain = max_unity_gain_current / config_.requested_current_range; // [V/V]
|
||||||
|
|
||||||
|
|||||||
@@ -170,7 +170,9 @@ void ASCII_protocol_process_line(const uint8_t* buffer, size_t len, StreamSink&
|
|||||||
} else {
|
} else {
|
||||||
Axis* axis = axes[motor_number];
|
Axis* axis = axes[motor_number];
|
||||||
axis->controller_.config_.input_mode = Controller::INPUT_MODE_TRAP_TRAJ;
|
axis->controller_.config_.input_mode = Controller::INPUT_MODE_TRAP_TRAJ;
|
||||||
axis->controller_.move_to_pos(goal_point);
|
axis->controller_.config_.control_mode = Controller::CTRL_MODE_POSITION_CONTROL;
|
||||||
|
axis->controller_.input_pos_ = goal_point;
|
||||||
|
axis->controller_.input_pos_updated();
|
||||||
axis->watchdog_feed();
|
axis->watchdog_feed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
static const uint8_t NUM_NODE_ID_BITS = 6;
|
static constexpr uint8_t NUM_NODE_ID_BITS = 6;
|
||||||
static constexpr uint8_t NUM_CMD_ID_BITS = 11 - NUM_NODE_ID_BITS;
|
static constexpr uint8_t NUM_CMD_ID_BITS = 11 - NUM_NODE_ID_BITS;
|
||||||
|
|
||||||
void CANSimple::handle_can_message(can_Message_t& msg) {
|
void CANSimple::handle_can_message(can_Message_t& msg) {
|
||||||
|
|||||||
@@ -591,7 +591,17 @@ static bool to_string(const T& value, char * buffer, size_t length, ...) {
|
|||||||
|
|
||||||
template<typename T, typename = typename format_traits_t<T>::type>
|
template<typename T, typename = typename format_traits_t<T>::type>
|
||||||
static bool from_string(const char * buffer, size_t length, T* property, int) {
|
static bool from_string(const char * buffer, size_t length, T* property, int) {
|
||||||
return sscanf(buffer, format_traits_t<T>::fmt, property) == 1;
|
// Note for T == uint8_t: Even though we supposedly use the correct format
|
||||||
|
// string sscanf treats our pointer as pointer-to-int instead of
|
||||||
|
// pointer-to-uint8_t. To avoid an unexpected memory access we first read
|
||||||
|
// into a union.
|
||||||
|
union { T t; int i; } val;
|
||||||
|
if (sscanf(buffer, format_traits_t<T>::fmt, &val.t) == 1) {
|
||||||
|
*property = val.t;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Special case for float because printf promotes float to double, and we get warnings
|
// Special case for float because printf promotes float to double, and we get warnings
|
||||||
template<typename T = float>
|
template<typename T = float>
|
||||||
|
|||||||
+1
-1
@@ -96,7 +96,7 @@ Name | Type | Default
|
|||||||
--- | -- | --
|
--- | -- | --
|
||||||
homing_speed | float | 2000.0f
|
homing_speed | float | 2000.0f
|
||||||
|
|
||||||
`homing_speed` is the axis travel speed during homing, in counts/second.
|
`homing_speed` is the axis travel speed during homing, in counts/second. If you are using SPI based encoders and the axis is homing in the wrong direction, you can enter a negative value for the homing speed and a negative value for the minimum endstop offset.
|
||||||
|
|
||||||
|
|
||||||
### Performing the Homing Sequence
|
### Performing the Homing Sequence
|
||||||
|
|||||||
+2
-2
@@ -51,7 +51,7 @@ Ramps a velocity command from the current value to the target value.
|
|||||||
## INPUT_MODE_POS_FILTER
|
## INPUT_MODE_POS_FILTER
|
||||||
Implements a 2nd order position tracking filter. Inteded for use with step/dir interface, but can also be used with position-only commands.
|
Implements a 2nd order position tracking filter. Inteded for use with step/dir interface, but can also be used with position-only commands.
|
||||||
|
|
||||||

|

|
||||||
Result of a step command from 1000 to 0
|
Result of a step command from 1000 to 0
|
||||||
|
|
||||||
### Configuration Values:
|
### Configuration Values:
|
||||||
@@ -71,7 +71,7 @@ Not Implemented.
|
|||||||
## INPUT_MODE_TRAP_TRAJ
|
## INPUT_MODE_TRAP_TRAJ
|
||||||
Implementes an online trapezoidal trajectory planner.
|
Implementes an online trapezoidal trajectory planner.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Configuration Values:
|
### Configuration Values:
|
||||||
* `<axis>.trap_traj.config.vel_limit`
|
* `<axis>.trap_traj.config.vel_limit`
|
||||||
|
|||||||
Reference in New Issue
Block a user