Dual X Axis improvements
hi there,
i was working again on my dual x carriage machine and i went and tried out marlin's handling of the dual x carriage.
i must say that it is actually pretty neat, particularly an interesting behaviour you can achieve with it and i thought it would be nice to have the same kind of functionality in repetier-fw
in short:
marlin has 2 modes (hot-switchable too) for dual x: full control (basically the firmware does no parking-unparking on toolchange) and autopark (which is similar to what repetier does)
however, the difference is that marlin has 2 additional values: X2_MIN_POS and X2_MAX_POS, and here's the neat behaviour:
this is neat for a number of reasons: first, it almost eliminates the need for LAZY_DUAL_X (which is kind of clunky), second it allows nice stuff to be done in the park area of each extruder, third it simplifies setup A LOT.
so i wanted to give a shot at implementing that in repetier-fw, but i have few questions:
i was working again on my dual x carriage machine and i went and tried out marlin's handling of the dual x carriage.
i must say that it is actually pretty neat, particularly an interesting behaviour you can achieve with it and i thought it would be nice to have the same kind of functionality in repetier-fw
in short:
marlin has 2 modes (hot-switchable too) for dual x: full control (basically the firmware does no parking-unparking on toolchange) and autopark (which is similar to what repetier does)
however, the difference is that marlin has 2 additional values: X2_MIN_POS and X2_MAX_POS, and here's the neat behaviour:
- if the current extruder is unparked, (basically over the bed area) it will park the old and unpark the new
- if the current extruder is parked, it will NOT unpark the new (because the x coordinate is out of reach for the other carriage), it will instead change the current X coordinate of the machine
this is neat for a number of reasons: first, it almost eliminates the need for LAZY_DUAL_X (which is kind of clunky), second it allows nice stuff to be done in the park area of each extruder, third it simplifies setup A LOT.
so i wanted to give a shot at implementing that in repetier-fw, but i have few questions:
- any chance it would be merged in 1.0?
- how portable would it be to v2?
- a quick look at the code makes me think the less intrusive way to implement that would be to have Printer::xMin and Printer::xLength swapped with X2 values in the toolchange function, having 2 new eeprom values. am i in the right direction?
- it would be extremely neat to have a custom gcode for parking the current extruder (eliminating the need to hardcode coordinates in the slicer gcode). would that be ok?
Comments
the good news is that your implementation in V2 seems to basically implement already what i am talking about here, as i see there are min and length defined for every axis.
this kind of makes those 2 values pointless (correct me if i'm wrong, these are taken from the sample config) provided each extruder (or rather, tool) gets to keep xyz offsets
all in all, i really look forward V2, but i might still work on v1 in the meantime
I guess you are also right that the DUAL_X_LEFT_OFFSET are not used. Offsets are now set in printer definition. Many configs will expire in old configuration.h and it really needs a cleanup once I'm done.
Regarding V1 I plan no deep changes to concentrate on V2 my self, but if you manage a good working solution as pull request on dev branch that is superior to old implementation I see no reason to not merge it. Maybe to make old config still possible it should be a different setup, lets say the lazy macro has 1 for current lazy version and 2 for the new one. If you introduce new eeprom values that might be a problem with vendors using old system as customers would loose settings on update.
But I do not think you need extra parameter. I think you can compute area from the 2 offsets which are the extreme. Normally 0 is x2 min and x length would then be limit for x1 max. So you do not need to introduce new config values.
one question tho: i'd like to implement a custom M code to just move the current carriage to park position. Any preference on where to put it in the M numbers range?
I saw on https://reprap.org/wiki/G-code#M605:_Set_dual_x-carriage_movement_mode that 605 sets dual x modes for marlin, so M604 would be a nice number. I think I will also implement this in V2. Should be quite simple. Maybe I call this park extruder and if there is no park position it is just ignored. So I can also have this on other printer types. On deltas I could just move to top for example at end of print. Like the idea.
basically, the carriage will be parked/unparked normally, except for when the current carriage is already in parked position. then the new will not be unparked because it would never be able to reach that coordinate.
for example: left carriage is @ -30mm when homed. if switching to right carriage, it will not unpark because it can't get to -30.00mm X coordinate.
having useable space outside the bed area is made possible by assuming fixed 0 xOffset for left carriage and a negative xMin number, and for right carriage assuming xMin = 0 and xLength = xOffset.
this is basically how marlin operates under their Auto-park mode.
new mode is working fine. testing it right now. i added M606 (M603 was already taken) to move to a position relative to the current carriage X park coordinate. it's very useful to put into the slicer's toolchange custom g-code.
the new mode is not compatible with LAZY_DUAL_X. i either gotta write that in the documentation or just make them mutually exclusive, possibly without making a mess with #ifs and whatnot.
anyway, my personal opinion is that LAZY_DUAL_X will be superseded by this. the only purpose of it was to make purging possible before the extruder gets positioned in the bed area, something that has to be done inside the custom toolchange g-code.
with the new system, not only it is possible to purge, but to move, and half of the printing space lost (if any) due to the dual carriage is gained back in single printing mode.
I will have a look at your changes when you are ready and do a pull request. I will then decide how to handle it. I guess I still do not get it fully. Maybe because I normally never use dual x in action. Having laze dual x removed would be fine for me, but I know users wanted this so I need to see it in action. The reason for lazy change was mainly to reduce movements until print. E.g. left was at x=100 and extruder switched. Next extrusion was at x=150. Without it would go to 100 and then 150 oozing. In lazy mode it directly goes to x=150 reducing move by 100mm. In my eyes that is the only advantage.
i'll make a video showing you the various modes and it'll be clear
here's the video. i hope it's sufficient to show the working of the various modes. will make more if needed
That all makes completely sense and I'd change the non lazy mode to this behaviour. The only difference for users having that mode currently is that after homing z is not 0 but the park position. Any moves will none the less be executed correctly.
for v2 i suggest this mode only. then users can get the old behaviour if they really want by just playing with offsets and custom g-code on toolchange
The only 2 problems I see so far is that now heads can crash into each other. Need to see how that can now be prevented. Your bigger x range allows it to move left extruder into right one parking position. I think each extruders opposite limit should be reduced by -extruder 0 offset x. Assuming position 0 is reachable from extruder 1.
Second thing is homing with second extruder being active does home it to x=0 and not to park position.
Both should be easy to fix. Apart from this I like the new mode. Already adapted it a bit in V2 but need to test this as well.
homing with extruder 2 should work fine. infact, it is what you see in the video (i have ext1 as right. but tested both ways). if it doesn't, i might have introduced a regression while cleaning up the code. will check.
also, keep in mind that extruder 1 does not mean left or right. it depends on the X_HOME_DIR.
so, if you have X_HOME_DIR = -1 then Ext0 is left, if you have X_HOME_DIR = 1 Ext0 is right.
example of my config right now:
#define X_HOME_DIR -1
#define X_MIN_POS -31 <-this is what you would have put in the left XOffset, but in mm
#define X_MAX_LENGTH 248 <-this is how far the left carriage can travel from home to right without crashing into the other
ext0 XOffset = 0 <-this MUST be 0
ext1 XOffset = 24966
That is xoffset right - xoffset left which is what I used.
Now you say
#define X_MAX_LENGTH 248 <-this is how far the left carriage can travel from home to right without crashing into the other
which is wat I interpreted minus crash distance. Will test that tomorrow and modify the description to be more clear. But I guess that will be my error here.
left extruder XOffset must be 0, and right extruder XMin is assumed 0
I have uploaded github with some tiny changes to remove compiler warning and also to compile with old config without error. Will soon also adjust the config tool to contain the new version.
After some tests of critical conditions all worked on the safe side, so really a good implementation. Thanks for the work.