AVR: Do not use __builtin_abs() for long types
In AVR __builtin_abs() breaks for non-base types. Provide a generic function and use an overload when it is safe to use instead. This fixes the underlying step count calculation in PlanMove, thus removing the need for the PlanLongMove work-around.pull/136/head
parent
2d81332626
commit
b6a676e093
12
src/cmath.h
12
src/cmath.h
|
|
@ -15,18 +15,22 @@ using std::min;
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline const T min(T a, T b) {
|
static inline const T min(const T a, const T b) {
|
||||||
return a <= b ? a : b;
|
return a <= b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline const T max(T a, T b) {
|
static inline const T max(const T a, const T b) {
|
||||||
return a > b ? a : b;
|
return a > b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline const T abs(T n) {
|
static inline const T abs(const T n) {
|
||||||
// Use builtin function when available
|
return n < 0 ? -n : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const int16_t abs(const int16_t n) {
|
||||||
|
// Use builtin function only when possible
|
||||||
return __builtin_abs((n));
|
return __builtin_abs((n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,6 @@ static constexpr uint16_t maxStepFrequency = 40000;
|
||||||
static constexpr uint16_t minStepRate = 120;
|
static constexpr uint16_t minStepRate = 120;
|
||||||
|
|
||||||
/// Size for the motion planner block buffer size
|
/// Size for the motion planner block buffer size
|
||||||
/// Beware of too low setting (esp. because of Motion::PlanLongMove)
|
|
||||||
static constexpr uint8_t blockBufferSize = 4;
|
static constexpr uint8_t blockBufferSize = 4;
|
||||||
|
|
||||||
/// Step timer frequency divider (F = F_CPU / divider)
|
/// Step timer frequency divider (F = F_CPU / divider)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ bool FeedToBondtech::Step() {
|
||||||
dbg_logic_fP(PSTR("Pulley start steps %u"), mm::motion.CurPosition(mm::Pulley));
|
dbg_logic_fP(PSTR("Pulley start steps %u"), mm::motion.CurPosition(mm::Pulley));
|
||||||
state = PushingFilamentToFSensor;
|
state = PushingFilamentToFSensor;
|
||||||
mm::motion.InitAxis(mm::Pulley);
|
mm::motion.InitAxis(mm::Pulley);
|
||||||
mm::motion.PlanLongMove<mm::Pulley>(config::defaultBowdenLength, config::pulleyFeedrate, config::pulleySlowFeedrate);
|
mm::motion.PlanMove<mm::Pulley>(config::defaultBowdenLength, config::pulleyFeedrate, config::pulleySlowFeedrate);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case PushingFilamentToFSensor:
|
case PushingFilamentToFSensor:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ bool UnloadToFinda::Step() {
|
||||||
if (mi::idler.Engaged()) {
|
if (mi::idler.Engaged()) {
|
||||||
state = WaitingForFINDA;
|
state = WaitingForFINDA;
|
||||||
mg::globals.SetFilamentLoaded(mg::globals.ActiveSlot(), mg::FilamentLoadState::InSelector);
|
mg::globals.SetFilamentLoaded(mg::globals.ActiveSlot(), mg::FilamentLoadState::InSelector);
|
||||||
mm::motion.PlanLongMove<mm::Pulley>(-config::defaultBowdenLength - config::feedToFinda - config::filamentMinLoadedToMMU, config::pulleyFeedrate);
|
mm::motion.PlanMove<mm::Pulley>(-config::defaultBowdenLength - config::feedToFinda - config::filamentMinLoadedToMMU, config::pulleyFeedrate);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case WaitingForFINDA:
|
case WaitingForFINDA:
|
||||||
|
|
|
||||||
|
|
@ -162,37 +162,6 @@ public:
|
||||||
unitToAxisUnit<AxisUnit<steps_t, A, Speed>>(end_rate));
|
unitToAxisUnit<AxisUnit<steps_t, A, Speed>>(end_rate));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function exists solely because of some mysterious overflow bug in planning/stepping
|
|
||||||
/// which occurrs when number of steps exceeds 32K. The bug doesn't even exhibit in unit tests :( .
|
|
||||||
/// Therefore it plans multiple segments in case the desired distance is longer than 32K steps.
|
|
||||||
/// So far this is only used for moving the Pulley...
|
|
||||||
template <Axis A, config::UnitBase B>
|
|
||||||
constexpr void PlanLongMove(config::Unit<long double, B, Lenght> delta,
|
|
||||||
config::Unit<long double, B, Speed> feed_rate, config::Unit<long double, B, Speed> end_rate = { 0 }) {
|
|
||||||
auto steps = unitToAxisUnit<AxisUnit<pos_t, A, Lenght>>(delta);
|
|
||||||
if (steps.v >= 0) {
|
|
||||||
while (steps.v > 32767) {
|
|
||||||
PlanMove<A>(
|
|
||||||
{ 32767 },
|
|
||||||
unitToAxisUnit<AxisUnit<steps_t, A, Speed>>(feed_rate),
|
|
||||||
unitToAxisUnit<AxisUnit<steps_t, A, Speed>>(feed_rate)); // keep the end feedrate the same to continue with the next segment
|
|
||||||
steps.v -= 32767;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (steps.v < -32767) {
|
|
||||||
PlanMove<A>(
|
|
||||||
{ -32767 },
|
|
||||||
unitToAxisUnit<AxisUnit<steps_t, A, Speed>>(feed_rate),
|
|
||||||
unitToAxisUnit<AxisUnit<steps_t, A, Speed>>(feed_rate)); // keep the end feedrate the same to continue with the next segment
|
|
||||||
steps.v += 32767;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PlanMove<A>( // last segment
|
|
||||||
steps,
|
|
||||||
unitToAxisUnit<AxisUnit<steps_t, A, Speed>>(feed_rate),
|
|
||||||
unitToAxisUnit<AxisUnit<steps_t, A, Speed>>(end_rate));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @returns head position of an axis (last enqueued position)
|
/// @returns head position of an axis (last enqueued position)
|
||||||
/// @param axis axis affected
|
/// @param axis axis affected
|
||||||
pos_t Position(Axis axis) const;
|
pos_t Position(Axis axis) const;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue