Problem spotted, described in a helpful manner and over-fixed
by @zungmann. This fix picks up his basic idea and implements it
with already existing state properties.
Instead of just two columns (x and y) in the trace file, treat
every column as a function and calculate the first derivative
of it without regard for its supposed "meaning". In addition
to getting more data from this, it also allows us to calculate
the 2nd derivative easily by running the script again on the
resulting data.
Also convert time in column 1 from microseconds to seconds.
Simulator assumes a basic set of config pins. Most it ignores
and redefines. But the INVERT_DIR pins it did not, and these
could be useful to simulate. So teach Simulator to respect them.
Move builds for non-avr target (simulator) into a $(BUILD_FLAVOR)
build subdir (build/sim) to isolate it more completely and
cleanly from the AVR builds. This allows AVR and SIM to use common
build rules again.
Move newly bits out of Makefile-{SIM,AVR} and into Makefile-common.
Test code which wants to customize config.h can do so without
touching config.h itself by wrapping config.h in a macro variable
which is passed in to the compiler. It defaults to "config.h" if
no override is provided.
This change would break makefile dependency checking since the selection
of a different header file on the command line is not noticed by make
as a build-trigger. To solve this, we add a layer to the BUILDDIR path
so build products are now specific to the USER_CONFIG choice if it is
not "config.h".
There's no apparent documentation for this on the AVR variant of GCC.
Likely it means to optimize "more aggressively". Uhm, is gcc
intentionally wasting cycles otherwise? Likely not.
Also, the compilation result is exactly the same size with or
without this attribute.
This macro is pretty expensive (700 bytes, well, stuff is now
calculated at runtime), so there's no chance to use it in multiple
places and we likely also need this in dda_lookahead.c to achieve
full 4 axis compatibility there.
For now this is for the initial rampup calculation, only, notably
for moving the Z axis (which else gets far to few rampup steps on
a typical mendel-like printer).
The used macro was verified with this test code (in mendel.c):
[...]
int main (void) {
init();
uint32_t speed, spm;
char string[128];
for (spm = 2000; spm < 4099000; spm <<= 1) {
for (speed = 11; speed < 65536; speed *= 8) {
sersendf_P(PSTR("spm = %lu speed %lu ==> macro %lu "),
spm, speed, ACCELERATE_RAMP_LEN_SPM(speed, spm));
delay_ms(10);
sprintf(string, "double %f\n",
(double)speed * (double)speed / ((double)7200000 * (double)ACCELERATION / (double)spm));
serial_writestr((uint8_t *)string);
delay_ms(10);
}
}
[...]
Note: to link the test code, this linker flag is required to add
the full printf library (which does print doubles):
LDFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm
Keeping the hack causes the previous move to decelerate, which isn't
intended when movements are joined with lookahead.
Removing only the hack breaks endstop handling on those axes which
set a huuuge number of acceleration steps for the lack of a proper
calculation algorithm. We have this algorithm now, so we can stop
using this kludge.
Solves part 1 of issue #68.
Previously, ramps were calculated with the combined speed,
which can differ from the speed of the fast axis by factor 2.
This solves part 2 of issue #68.
This is a preparation towards going through the existing movement
queue backwards with dda_join_moves() to allow higher feedrates
for lots of short movements.
There are three locations in the code that repeat a pattern of
"If z=0 then use 2d-approx(dx,dy), else if x==0 && y==0 then use dz,
else use 3d-approx".
Teach approx_distance_3 to detect these conditions for us and apply
the same logic. Replace the three call locations with a simple call
to approx_distance_3.
Binary size for the LOOKAHEAD case drops by almost 400 bytes:
old: FLASH : 21242 bytes 149% 70% 34% 17%
new: FLASH : 20844 bytes 146% 68% 33% 17%
The size for non-LOOKAHEAD drops by 40 bytes:
old: FLASH : 16592 bytes 116% 55% 27% 13%
new: FLASH : 16552 bytes 116% 54% 27% 13%
We can actually do a little better if we consider the zero-ness of all
three axes, but this does make the code a little bit bigger. Another
change will consider that option. This change simply tries to mimic
the existing functionality.
The new one solely looks at speed differences of individual axes.
This means individual jerks for each axis (good!) and relative
simple maths (also good!).
For details and maths, see comments in the code and
https://github.com/Traumflug/Teacup_Firmware/issues/45 .
This is mostly a preparation for reverse walks through the movement queue,
where crossing speed calculation is done only once, while actually used
speeds can be raised successively with repeated walks.
Add a tool (tools/velocity_plot.sh) to read in a simulator trace
file, calculate the velocity of the X and Y axes, and show a plot
of these velocities against time along with the X and Y positions.
The nice thing about these save files is, they provide a display
for the data, so you simply load a .vcd, additionally read a
save file and you're ready to investigate your movement data.
- comment on why the case exists,
- add an M2 at the end to later allow automatic simulation stop,
- move comments to the end to avoid filling the serial buffer with
stuff unrelated to movements,
- make sure there's a line ending at the end of the file and
- use Windows line endings (they're more difficult to handle).
Moves which have no movement intention, e.g. pure feedrate changes,
and moves too small to cause a single step, are a bit tricky to
handle with lookahead. Essentially, they should be joined with the
next movement, without queueing them up.