Open ArcEye opened 6 years ago
Comment by mhaberler Fri Dec 4 09:41:15 2015
good start! and I am happy you start looking at the canon layer - it seriously needs refactoring and the more folks we have which are up to speed on canon the easier it will be
to the task at hand - before jumping into the cause, lets discuss options a bit:
it might help to get a grasp on how the offsets (g5x,g92) are handled in canon - because the points where those are applied are likely the ones where the transform kicks in
I am not totally sure on the geometry transforms - I think they must be applied past transform to machine coordinates (applying offsets, xy rotation, unit conversion) - I will mail Joseph Coffland for advice, must be somewhere in here: https://github.com/CauldronDevelopmentLLC/CAMotics/tree/master/src
my suggestion would be first to check the feasibility of the idea - with a simple, maybe even hardcoded transform function on the endpoints of moves (in total it'd be feed/traverse line, arc, nurbs, probe move, probably some I forgot - you need to read up on canon.hh and flag the ones which need treatment)
Comment by mhaberler Fri Dec 4 09:48:19 2015
thinking a bit more about it, can I suggest this - since before changing anything, one better knows what the basis is:
it would be valueable to have a short writup - maybe just a few slides - which we can use for a hangout or as fragment of documentation - what the key functions of emccanon are (offsets, rotation, NCD, (I think) optional block handling, unit conversion), how that plays together with motion, and in which order they are applied (forward -> interp towards motion, and backwards - machine status -> sync(( input)
for instance, one would need to check wether motion is always machine coordinates or if it follows the interpreter's G90/G91 setting
Comment by einstine909 Fri Dec 4 17:52:40 2015
I was mulling over how to apply offsets in the code, and I came to the realization that the solution is not just simply endpoint transforms. We also need to take into account the possible change in the offset along a path. For example this could change a straight feed into a nurbs path, altering the intent of the cannon command. If we assume the offset does not change along the line, then we would not be following the offset surface faithfully. Any input on these thoughts would be appreciated.
I will start documenting the roles of the cannon layer. For betterment of my understanding and as a guideline for any changes that I make.
Comment by mhaberler Fri Dec 4 18:34:41 2015
good point.
back at the time I thought we'd operate in infinitesimal territory anyway und just skip that question ;) but that clearly is not the case. For an arbitrarily shaped surface the general case is a shape-changing transform. Hm.
But then you could play this stunt: break up the path into short segments and apply the surface transform on each of them. Technically that is not much different than what a Naive CAM package is doing. With some luck the NCD layer will recombine those into longer segments if moving in planar regions.
now that said, even a generalized planar transform would be already an improvement over the strange special casing of the xy rotation transform which I'd happily drop in exchange (I am not fully up to speed on the math but I think I remember a quaternion applied in Joseph's code)
whatever we do, I think it is becoming clear we need to move the standalone output option under the emccanon stack. Otherwise this will be flying blind.. no way to regression test the output.
Thinking of it, pushing the canon output stage through a Python callback looks interesting too since one could generate arbitrary output there, sai, or a display list or some graphics file format to view results.
Some of the decisions taken back then were just rather simple-minded it seems.
Comment by einstine909 Fri Dec 4 20:06:03 2015
Thinking of it, pushing the canon output stage through a Python callback looks interesting too since one could generate arbitrary output there, sai, or a display list or some graphics file format to view results.
I agree with this. Do you think it would be outlandish if I replaced all cannon calls (STRAIGHT_FEED, STRAIGHT_FEED, ARC_FEED, etc...) with python callbacks and turned the cannon layer into a plugin based subsystem?
Comment by mhaberler Sat Dec 5 07:07:29 2015
no, that is not outlandish at all
to the contrary, we could even think a bit more radical - rip out c++ altogether right below the canon API and make it all Python. The only problem I'd see is with preview performance with huge CAM-generated files; with manually generated G-code there is not much happening in canon anyway.
(if we did that - writing up a documentation would actually become the spec for doing anything in Python lateron here)
but that is really a performance engineering question and not a functional issue. And the hot path will basically only one: short line segments - so if push comes to shove, one could optimize this path pretty well; either by leaving it c++ or going for cython which has near c++ performance if done right. It just happens that boost.python has better documented ways of doing embedded python relative to cython. But that is a secondary question right now.
I like the idea the more I think about it - and the upside is huge! it would actually be phantastic to have for me and Alex because it would ease migration to zeroMQ/protobuf big time.
one thing we should do is do a bit of performance analysis: take a few say OpenSCAD/slicer generated monster g-codes and run them on a rs274/emccanon stack (maybe just with disabled NML output) so we see where this is spending its time; plus compare that to using 'import preview'. My prediction/gut feel: very isolated.
let's talk this through - see private mail.
Comment by mhaberler Sun Dec 6 16:14:39 2015
for other readers - Seth and me hashed it out via skype
the idea is to create a C++-callable canon layer through cython which can either call into embedded python as needed, or even continue to use C++ fragments (eg NCD for now)
while I've never used cython to embed Python in C/C++ it seems reasonaby straightforward
example test.pyx:
# cython: language_level=3
cdef public float foo(float f):
print("%f" % f)
return f * f
def bar(f):
print("%f" % float(f))
return f * 2
running this through 'cython test.pyx' will create test.c - that has a C-callable entry point of the signature
float foo(float __pyx_v_f) {
so this would be directly callable from C (note C++ signature mapping needs to be added, eg through adding static inlines which redirect the C++-signatured calls to the C entry points)
test.c also exports
#if PY_MAJOR_VERSION < 3
PyMODINIT_FUNC inittest(void); /*proto*/
PyMODINIT_FUNC inittest(void)
#else
PyMODINIT_FUNC PyInit_test(void); /*proto*/
PyMODINIT_FUNC PyInit_test(void)
#endif
those functions are the module init methods which would export test.bar
at the Python level once called
so one can actually export C entry points as well as a Python module for extensions right through the same pyx file
Comment by mhaberler Mon Dec 7 11:15:12 2015
@einstine909 - created an example repo which should cover all the codepaths: https://github.com/mhaberler/embedded-cython
Issue by einstine909 Thu Dec 3 16:43:48 2015 Originally opened as https://github.com/machinekit/machinekit/issues/816
Cannon currently cannot apply transforms to the requested moves. @mhaberler suggested a python plugin interface here similar to the gcode remapping facility. Previous discussion on this issue was here: https://groups.google.com/forum/#!topic/machinekit/mhfg2pzXZbk