Add a comment to the datalog output showing how it can be viewed with
gnuplot. It would be trivial to add this as a .plot script, but it's
even easier in the datalog output.
This script also asks SimulAVR to generate pin traces of the X
and Y axis and even processes this data into a data file with
time, position and current speed of each axis.
Missing:
- Acceleration calculation.
- LOTS of polish.
This shouldn't change the running binary at all, so it shouldn't
harm. However, it allows to run Teacup inside SimulAVR and accessing
Teacups' serial line through the console/terminal.
For detailed instructions, see http://reprap.org/wiki/SimulAVR .
Including a semicolon in a macro function causes problems
when the "function" is called inside an if statement. Fix
four cases in pinio.h where this error exists but currently
is not harming the code.
Teach simulator several command line options to control console output
of info messages, gcode traces, data_recorder output, etc.
Also move gcode output to sim_gcode instead of sending directly to
datarecorder.
If the recorder is initialized with a filename, write trace data
to that file. But if it is not initialized, don't complain and
don't write the data anywhere.
The simulator runs as a device simulator complete with serial port
so it can communicate with printer software like pronterface. But
often we just want to stream it a file of gcode commands and get
some output. Teach the simulator to take a regular file as input
and process it as a file of gcode commands if it is not a device.
In AVR the labs() function takes a 32-bit signed int parameter. On
the PC it's at least 64-bits and maybe more. When we have a 32-bit
unsigned value we're taking the labs() of, coercing it to 32-bits
first turns our high-bit into a sign, but coercing it to 64-bits
does not. This causes all our negative values to appear to be
really big positive ones.
Create a new function abs32() which always coerces its argument to
a int32_t first before return the abs value. Use that function
whereved needed in dda.c.
This fixes a problem on the simulator which caused negative
direction movements to "never" end.
research/datalog.plot is a gnuplot script to plot pin outputs like
a logic analyzer and x/y/z positions as well. It's quite rudimentary
but it does recognize some keyboard commands to pan and zoom.
Be careful with keyboard repeat getting too far ahead of you.
Reduce the simulated timer to 1/10 actual time. There is no need
for the simulator to run at full speed for now, and some PCs may
not be able to attain real-time speed anyway due to PC clock
speed, scheduler slack or OS differences.
Maybe the simulated timer interrupt is not needed at all and some
cooperative timer interrupt could be used instead. Such a setup
may even run faster as it could also run >1.0x time when there is
nothing to do. This bears investigation later. For now, the
simulated timer interrupt seems more realistic and possibly valuable.
Cleanup datalog output a bit.
* Add close/flush on exit in case we have pending data
* Use hash for comment characters to be compatible with gnuplot
* Report x/y/z/e position in array
Dependency automation seems a bit confused in these makefiles.
Clean it up following ancient sage wisdom here:
http://mad-scientist.net/make/autodep.html
In short, use -MMD to generate dependency files for each .o target,
and then use a sed script to extend that to avoiding "missing file"
dependencies when headers are renamed/removed.
Also, make everything dependent on makefiles other than our
autodependency (*.P) makefiles.
Make the BUILDDIR an order-only prerequisite for our targets so any
changed file therein does not cause all other files to appear to be
out of date.
Also, some makefile cleanup:
- Remove obsolete 'depend' target.
- Move AVR-specific targets to AVR makefile.
- Add TARGET variable to identify target to make and to clean.
- Tidy up dependency make.
Next-interrupt-time calculations were made in 16-bit registers but
moved to 32-bit ones for convenience. But they forgot to round off
at 16-bits. Force the round-off so we do not wait forever.
Record simulation run-time data in file 'datalog.out' so it
can be analyzed after-the-fact or during the run.
This feature is evolving. Eventually it should be compatible with
some logic analyzer GUIs such as gtkwave or even gnuplot.
This code was accidentally removed long ago in a botched merge. This
patch recovers it and makes it build again. I've done minimal testing
and some necessary cleanup. It compiles and runs, but it probably still
has a few dust bunnies here and there.
I added registers and pin definitions to simulator.h and
simulator/simulator.c which I needed to match my Gen7-based config.
Other configs or non-AVR ports will need to define more or different
registers. Some registers are 16-bits, some are 8-bit, and some are just
constant values (enums). A more clever solution would read in the
chip-specific header and produce saner definitions which covered all
GPIOs. But this commit just takes the quick and easy path to support my
own hardware.
Most of this code originated in these commits:
commit cbf41dd4ad
Author: Stephan Walter <stephan@walter.name>
Date: Mon Oct 18 20:28:08 2010 +0200
document simulation
commit 3028b297f3
Author: Stephan Walter <stephan@walter.name>
Date: Mon Oct 18 20:15:59 2010 +0200
Add simulation code: use "make sim"
Additional tweaks:
Revert va_args processing for AVR, but keep 'int' generalization
for simulation. gcc wasn't lying. The sim really aborts without this.
Remove delay(us) from simulator (obsolete).
Improve the README.sim to demonstrate working pronterface connection
to sim. Also fix the build instructions.
Appease all stock configs.
Stub out intercom and shush usb_serial when building simulator.
Pretend to be all chip-types for config appeasement.
Replace sim_timer with AVR-simulator timer:
The original sim_timer and sim_clock provided direct replacements
for timer/clock.c in the main code. But when the main code changed,
simcode did not. The main clock.c was dropped and merged into timer.c.
Also, the timer.c now has movement calculation code in it in some
cases (ACCELERATION_TEMPORAL) and it would be wrong to teach the
simulator to do the same thing. Instead, teach the simulator to
emulate the AVR Timer1 functionality, reacting to values written to
OCR1A and OCR1B timer comparison registers.
Whenever OCR1A/B are changed, the sim_setTimer function needs to be
called. It is called automatically after a timer event, so changes
within the timer ISRs do not need to bother with this.
A C++ class could make this requirement go away by noticing the
assignment. On the other hand, a chip-agnostic timer.c would help
make the main code more portable. The latter cleanup is probably
better for us in the long run.
This is a preparation for starting a move from non-zero speeds,
which is needed for look-ahead. Keeping both variables in
move_state and doing the calculations in dda_start() is possible
in principle, but might not fit the tight time budget we have when
going from one movement to the next at high step rates.
To deal with this, we have to pre-calculate n and c, so we have
to move it back into the DDA structure. It was there a year ago
already, but moved into move_state to save RAM (move_state exists
only once, dda as often as there are movement queue entries).
His implementation was done on every step and as it turns out,
the very same maths works just fine in the clock interrupt.
Reason for the clock interrupt is: it allows about 3 times
higher step rates.
This strategy is not only substantially faster, but also
a bit smaller.
One funny anecdote: the acceleration initialisation value, C0,
was taken from elsewhere in the code as-is. Still it had to be
adjusted by a factor of sqrt(2) to now(!) match the physics
formulas and to get ramps reasonably matching the prediction
(and my pocket calculator). Apparently the code before
accumulated enough rounding errors to compensate for the
wrong formula.