Avoid runtime conversions of floats in UnloadToFinda
Introduce axisUnitToTruncatedUnit to convert from an AxisUnit (now conveniently returned from Motion::CurPosition) to a physical unit *but* directly into a truncated integer type, avoiding conversions to long double types at runtime. The related function truncatedUnit perform the same truncation of a constant unit, so that the result of axisUnitToTruncatedUnit and truncatedUnit(unit) result in the same type for clarity. Both functions accept a pre-multiplier, which is applied at compile time for constant values when optimizations are enabled.pull/150/head
parent
86d5e87a09
commit
53d285280d
|
|
@ -24,7 +24,7 @@ void UnloadToFinda::Reset(uint8_t maxTries) {
|
||||||
|
|
||||||
// @@TODO this may end up somewhere else as more code may need to check the distance traveled by the filament
|
// @@TODO this may end up somewhere else as more code may need to check the distance traveled by the filament
|
||||||
int32_t CurrentPositionPulley_mm() {
|
int32_t CurrentPositionPulley_mm() {
|
||||||
return mm::stepsToUnit<mm::P_pos_t>(mm::P_pos_t({ mm::motion.CurPosition(mm::Pulley) }));
|
return mm::axisUnitToTruncatedUnit<config::U_mm>(mm::motion.CurPosition<mm::Pulley>());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UnloadToFinda::Step() {
|
bool UnloadToFinda::Step() {
|
||||||
|
|
@ -48,7 +48,7 @@ bool UnloadToFinda::Step() {
|
||||||
return false;
|
return false;
|
||||||
case WaitingForFINDA: {
|
case WaitingForFINDA: {
|
||||||
int32_t currentPulley_mm = CurrentPositionPulley_mm();
|
int32_t currentPulley_mm = CurrentPositionPulley_mm();
|
||||||
if ((abs(unloadStart_mm - currentPulley_mm) > config::fsensorUnloadCheckDistance.v) && mfs::fsensor.Pressed()) {
|
if ((abs(unloadStart_mm - currentPulley_mm) > mm::truncatedUnit(config::fsensorUnloadCheckDistance)) && mfs::fsensor.Pressed()) {
|
||||||
// fsensor didn't trigger within the first fsensorUnloadCheckDistance mm -> stop pulling, something failed, report an error
|
// fsensor didn't trigger within the first fsensorUnloadCheckDistance mm -> stop pulling, something failed, report an error
|
||||||
// This scenario should not be tried again - repeating it may cause more damage to filament + potentially more collateral damage
|
// This scenario should not be tried again - repeating it may cause more damage to filament + potentially more collateral damage
|
||||||
state = FailedFSensor;
|
state = FailedFSensor;
|
||||||
|
|
|
||||||
|
|
@ -112,14 +112,30 @@ static constexpr AU unitToAxisUnit(U v) {
|
||||||
return { (typename AU::type_t)(v.v * axisScale[AU::axis].stepsPerUnit) };
|
return { (typename AU::type_t)(v.v * axisScale[AU::axis].stepsPerUnit) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert an AxisUnit to unit::Unit.
|
/// Convert an AxisUnit to a physical unit with a truncated integer type (normally int32_t).
|
||||||
/// The scaling factor is stored with the pair config::AxisConfig::uSteps and
|
/// Inverse of unitToAxisUnit, with the additional constraint that type casts are
|
||||||
/// config::AxisConfig::stepsPerUnit (one per-axis).
|
/// performed earlier so that no floating point computation is required at runtime.
|
||||||
template <typename U, typename AU>
|
/// @param U Base unit type (normally U_mm)
|
||||||
static constexpr typename U::type_t axisUnitToUnit(AU v) {
|
/// @param AU AxisUnit type (implicit)
|
||||||
|
/// @param T Resulting integer type
|
||||||
|
/// @param v Value to truncate
|
||||||
|
/// @param mul Optional pre-multiplier
|
||||||
|
/// @returns Truncated unit (v * mul)
|
||||||
|
/// @see unitToAxisUnit
|
||||||
|
template <typename U, typename AU, typename T = int32_t>
|
||||||
|
static constexpr T axisUnitToTruncatedUnit(AU v, long double mul = 1.) {
|
||||||
static_assert(AU::unit == U::unit, "incorrect unit type conversion");
|
static_assert(AU::unit == U::unit, "incorrect unit type conversion");
|
||||||
//static_assert(U::base == axisScale[AU::axis].base, "incorrect unit base conversion");
|
static_assert(U::base == axisScale[AU::axis].base, "incorrect unit base conversion");
|
||||||
return { (typename U::type_t)(v.v / axisScale[AU::axis].stepsPerUnit) };
|
return { ((T)v.v / (T)(axisScale[AU::axis].stepsPerUnit / mul)) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Truncate an Unit type to an integer (normally int32_t)
|
||||||
|
/// @param v Value to truncate
|
||||||
|
/// @param mul Optional pre-multiplier
|
||||||
|
/// @returns Truncated unit (v * mul)
|
||||||
|
template <typename U, typename T = int32_t>
|
||||||
|
static constexpr T truncatedUnit(U v, long double mul = 1.) {
|
||||||
|
return (T)(v.v * mul);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a unit::Unit to a steps type (pos_t or steps_t).
|
/// Convert a unit::Unit to a steps type (pos_t or steps_t).
|
||||||
|
|
@ -129,13 +145,6 @@ static constexpr typename AU::type_t unitToSteps(U v) {
|
||||||
return unitToAxisUnit<AU>(v).v;
|
return unitToAxisUnit<AU>(v).v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a steps type (pos_t or steps_t) to a unit::Unit.
|
|
||||||
/// Extract the raw step count from an AxisUnit with type checking.
|
|
||||||
template <typename U, typename AU>
|
|
||||||
static constexpr typename U::type_t stepsToUnit(AU pos) {
|
|
||||||
return axisUnitToUnit<U, AU>(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pulley
|
// Pulley
|
||||||
typedef AxisUnit<pos_t, Pulley, Lenght> P_pos_t; ///< Pulley position type (steps)
|
typedef AxisUnit<pos_t, Pulley, Lenght> P_pos_t; ///< Pulley position type (steps)
|
||||||
typedef AxisUnit<steps_t, Pulley, Speed> P_speed_t; ///< Pulley speed type (steps/s)
|
typedef AxisUnit<steps_t, Pulley, Speed> P_speed_t; ///< Pulley speed type (steps/s)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue