Closed spumco1234 closed 1 year ago
Update after more testing...
All of the data collected in the previously posted spreadsheet was generated using the jog-fwd/rev inputs to carousel.comp.
Testing tonight by entering pocket values directly instead of jogging. Results are interesting.
With carousel.0.align-dc =0 the same behavior as before was observed (extra counts added at direction changes)
However, when carousel.0.align-dc >0 all movement was accurate - including direction changes to within a couple counts.
Summary
I think, in balance, that I messed up with this. The problem is that the component outputs a constant velocity until the carousel is in position, and then stops, but the stepgen that it doing the motion will take some time to decelerate. It would all work a lot better, I think, if the output was a position and then the stepgen internal position loop would control the motion to the set position. Setting a very slow align-dc with the current logic will almost work, but the align-dc needs to be low enough that the stepgen moves at less than 1 count per servo cycle. I think that the only real answer is to re-work how counts mode operates. Which hopefully I will find time for this week.
Andy - Thanks for looking in to this.
Regarding your speculation about position output vs jogging, I found that commanding a single pocket move works.
i.e. at pocket #1, set destination to #2, and enable carousel = works fine. Yet jogging doesn't work.
I don't understand this because both commands are using a velocity mode stepgen and a timer. Unless the decel is different between destination commands and jog commands...
Regardless, I was fiddling with a workaround and came up with a kludge using .ngc files. Instead of simply setting carousel.N.jog-fwd high, I did some current-pocket + 1 (or -1) math and linked my physical jog buttons to a new M-code. Of course it only worked until current-pocket = #1, and then it failed because my simplistic math didn't take in to account the need to go from #1 to #18 (18 pockets in my case). Carousel didn't like going to pocket #0, of course.
But in theory it seemed to work. Sounds like you've got something similar in mind, but internal to carousel.comp and not in a subroutine - certainly more graceful than my first hacky testing attempt.
(edit - the 'links' at the pocket numbers are some weird thing github is auto-generating. Disregard the links please.)
Andy - any opportunity to give this some thought yet? Velocity counts mode is still not working out for me - periodic misalignment despite using the align-dc feature.
I'm going to have to move away from carousel.comp and treat the ATC as an axis if you don't have time to give positioning-counts a go.
I have had a play around. Here is a new version of the carousel.comp that tries to control a stepgen in position mode (could also work with a PID). Also attached is a test HAL config. You can try setting the pins and positions in halshow and see if the behaviour looks about right. I wouldn't try to move hardware with it yet (or not without great care) Archive 2.zip
First round of testing - promising but first glitch encountered during homing.
halcompiled the new comp and can see the new pins
disconnected all carousel control pins (enable, pocket-number, etc.) so I can control via halshow
carousel & stepgen scale set as before
fwd-dc & rev-dc set very low (10/-10) for testing
At first enable, carousel started rotating correct direction (homing)
Speed was faster than expected, so there must be something different in either the stepgen or carousel scale now that the stepgen is in position mode (vs. vel)
Homed pin went high (and stayed high) when sens-0 passed the proxy, but the carousel didn't stop rotating
Only way to stop it was to unlink stepgen enable and set low. When I re-set it high, carousel immediately started rotating again.
carousel state remained "0" during homing
current-position counted up as expected during homing
I suspect a mismatch between my carousel.scale and stepgen position-scale values as the stepgen position-FB did not match the position-cmd value while rotating (-FB was considerably lower than -cmd).
If you want to check my math/values, here is the configuration: 1.8deg stepper 4500 pulses per motor rev (set in drive) 5:1 reducer 18 pockets = 22500 pulses per rotation = 62.5 pulses per degree = 20 degrees / pocket = 1250 pulses / pocket
So... carousel.0.scale = 1250 stepgen.04.position-scale = 62.5
Or did I mess something up?
Sorry for the lack of docs. duty-cycle in stepgen position mode will have no effect, the speed and accel will be limited by the stepgen maxvel and maxaccel. Also note that the stepgen needs to be switched to position mode.
No need to apologize - docs take time.
I did put the stepgen in position mode (didn't work until I spotted that in your test HAL). I'll adjust speed in the stepgen.
What I'm seeing as it sits there rotating continuously is that counts-target keeps going up even after the home pin is reached. And as I mentioned, the 'homed' pin goes high.
But it's acting like there's no connection between the homed state and a stop signal. Or it's waiting for some state change that doesn't happen or isn't communicated.
Not seeing any difference in behavior after changing every setting I can think of.
I did notice a difference between your sim HAL connections and my mesa-based machine HAL config. Specifcally, you have the following: addf stepgen.make-pulses thread1 addf stepgen.capture-position thread1 addf stepgen.update-freq thread1
and my config doesn't. None of my other stepgens have these pins defined and they seem to work ok... is this a sim-only or sofware-stepgen thing?
I'm attaching my config files in case you want to dig around. Apologies for the file verbosity, but I didn't think it wise to cut-paste sections in case I missed something important.
They're structured such that all 'loadrt' and 'addf' are in 01_PBATC.hal, and the ATC stepgen & carousel connections are in 02_atc.hal
What I'm seeing as it sits there rotating continuously is that counts-target keeps going up even after the home pin is reached. And as I mentioned, the 'homed' pin goes high.
It is commanded to do a move of size scale x pockets so that should only be a singe revolution, even if the home pin detection is not found.
What is your stepgen scale? At the moment it should be 1 so that counts = position (I might revisit that) I think you have setp HMOT.stepgen.04.position-scale 62.5 #[ATC]ATC_STEP_SCALE
But it's acting like there's no connection between the homed state and a stop signal. Or it's waiting for some state change that doesn't happen or isn't communicated.
It works in the sim, in that toggling the index input stops the homing move. I see that your HAL connects input 06 and input 01. Do both toggle on the input?
Yes, stepgen scale is 62.5. I normally have that in INI file, but commented out and stuck it in HAL for testing.
If it should be 1, then I'll work out the math between stepgen and carousel scale. That would explain the discrepancy, and probably the unintended behavior.
input-06 is the index, and input-01 is the pocket-pulse. Both are behaving properly - I can watch the index pulse when it goes 'round and that's what triggers the 'homed' pin to go high.
It just doesn't stop turning when the homed pin is set.
Does it stay in state 11 even after seeing the index pulse?
Changing the stepgen scale resulted in new behavior. I'm having a hard time sorting out what variables affect various outcomes, but here's what I've got so far.
stepgen scale = 1 carousel scale = 1250 carousel width = 5
carousel counts now equals stepgen counts & position-fb... which is what i think you intend.
On enable, carousel starts rotating state = 11 homed goes high at 21250 continues rotating until it reaches 22500 State changes to 0 when the homed pin goes high Current pocket = 2
After that, it doesn't respond to pocket number + enable commands.
I can trigger the position-reset and unhome it, but on enable it doesn't move and is stuck at state = 11.
Minor update...
Once the original enable-homing sequence is done, unhoming has no effect on counts. That is, I can set the unhome pin and state changes to 8, but there is no response to enable.
I was able to get it to respond to pocket-number changes, but it's always off by one pocket number. i.e. after homing it stops at pocket 2. If I command pocket-number = 12, it'll move to pocket 13 and stop.
Off-by-one sounds like a simple arithmetical mistake on my part.
Change line 339
counts_target = mod_pocket * scale + base_counts;
to
counts_target = (mod_pocket - 1) * scale + base_counts;
It's because pockets is 1-based and the offset need to be calculated on a 0-based system.
Thanks. Couple Q's:
I had stepgen max_vel at 50 before - that gave me about 50 degrees/sec. Now (scale = 1) I've had to put it up around 2-3000 to get it moving more than a crawl.
Is this expected behavior? i.e. given the new scale (stepgen = 1, carousel = 1250), I should calculate maxvel as [desired pockets per second x 1250]?
Follow-up question:
Does your intended homing logic act as before, where the platter will spin and stop when it reaches the index pin?
Or is it different, such that the platter is commanded to spin one full turn, and counts value is recorded when the index pin is triggered? Carousel then calculates the current pocket based on the difference between the current counts value and value when index is triggered... but does not move to pocket 1 after calculating current position?
The result being the platter will not end up at pocket 1 as before, unless carousel.N.pocket-number is set to 1 before homing?
If your homing logic is the second, that would help explain the homing behavior I've been witnessing.
- Do I need to edit carousel.comp and run halcompile again?
Yes, exactly that.
Is this expected behavior? i.e. given the new scale (stepgen = 1, carousel = 1250), I should calculate maxvel as [desired pockets per second x 1250]? Yes, it's now a counts/second rather than a tools/second As I hinted, this might want to be reconsidered.
I think that if it is not homed, and you set the pocket to (for example) 8, then set enable, it should home and then go to 8. If the target pocket is zero then it will (I think) just stay at the home pin.
I'm back on this after a few days of under-the-weather brain fog. Sorry for the long post
Observation #1 Editing the comp has eliminated the pocket-number => current-position mismatch by 1
Observation #2 I think that if it is not homed, and you set the pocket to (for example) 8, then set enable, it should home and then go to 8. If the target pocket is zero then it will (I think) just stay at the home pin.
That's not exactly what I observed after editing the comp.
If: Pocket-number is left at 0 during homing, the platter will turn one full revolution and stop (not at home pin, but current-position is tracked appropriately) Pocket-number is set to anything other than 0, platter will turn one full rev, then move to pocket-number
However, if enable is set low during homing, it will stop after one full turn and not move to a particular pocket (this is different behavior than before)
TBH, I liked the previous behavior better where no matter what the settings carousel always stopped at pocket #1 (even if very briefly). I could set enable high without worrying about a pocket-number command and know it was going to stop at pocket 1.
I can edit my homing .ngc file to command a move to pocket 1, of course, but if counts mode homing is different than all the other carousel modes it might get confusing. Unfortunately, I don't have a different encoding scheme to test if homing behavior is the same across all carousel modes.
Observation #3 Current-position is not always updating properly and it's not taking the shortest-path when it should cross lowest pocket to highest (in my case moving from 1 to 18)
After fiddling with the homing (above), I did a simple test. Fresh restart of LCNC, set pocket-number = 1, set enable high. Carousel rotated one full turn then moved to pocket 1.
current-position = 1 pocket-number = 1 set enable low state = 0
Set pocket-number to 6 (CW rotation) Set enable high Carousel moved to pocket 6 set enable low
current-position = 1 (?) pocket-position = 6 state = 0
Set pocket-number to 5 (CCW rotation) Set enable high Carousel moved to pocket 5 Set enable low
current-position = 5 pocket-position = 5 state = 0
Same as above, pocket-number = 18 (should be CCW) Moved the long way around (CW) and stopped at 18, but current-position = 5.
Tried a few more times, but something is wrong with the shortest-path function, as well as current-position not updating on CW moves.
If I command a move which would be CCW (pocket-number < current position), AND it doesn't have to go from 1 to 18, everything stays in sync. In all other cases I've tested reported current-position doesn't update after the move.
As you might expect, I'm confused. It's moving to the correct pocket, but not in a way I'd expect and current-position isn't updating despite stopping at the intended pocket.
I think that the problem with not wrapping correctly is the same as not updating current_position correctly. And the full revolution every time on homing was due to not updating the target position after homing. The second issue should be fixed in this version, but I am not sure about the first, I think I need some real numbers to experiment with. This version has "base_counts" brought out as a parameter, can you move to a few positions and tabulate counts, base_counts, current_position and scale for me?
Of course. Should be done in an hour or so and will get back to you
Homing now works as original: leaving pocket-number = 0 results in carousel moving slightly past pocket 1 then backing up and stopping at 1 Base-counts updates during homing, but doesn't change after that Still not wrapping correctly
Let me know if you have problems opening the LibreOffice spreadsheet 2023-03-09 - Carousel_test 01.ods
What value do you have on the "width" pin? I think that the mathematics is probably correct, but the detection window is too small. So when it updates the position it generally gets the right value, but it rarely updates. Increasing width to 50 or so would probably make it work. Except...
if (c >= (t * scale - w) && c <= (t * scale + w)) {
new_pos = 1 + (t % inst_pockets);
}
I need to look at this carefully with sample code. I have something working in a spreadsheet, but Excel has a different opinion of the meaning of (MOD(-20,18)) to C (-20 % 18), and I need to be sure that nothing bad is going to happen when the carousel rotates into negative counts. See https://torstencurdt.com/tech/posts/modulo-of-negative-numbers/
I had width set to 0, thinking it was for the previous velocity-based mode. Setting it to 50 has cured the pocket-number to current-position mismatch.
I'll have to play with width once I get it moving at the speed/accel I want once the wrapping function is sorted out.
Minor update: setting width down as low as 5 still works fine, with stepgen maxaccel = 80k and maxvel = 11250
Quit working at width=1
Carousel is now amusingly brisk - with a full load of holders - without hammering anything.
Don't commit to anything until we are sure that wrapping anticlockwise past the original home works. ie, try going to 12, 6, 1, 12, 6, 1, 12,6, 1 and check that it doesn't lose a pocket when counts is negative.
Sorry if I wasnt clear, but its still not wrapping. My post was intended to let you know that width cured the pocket number mismatch. All commands which should result in wrapping do not; it always takes the long way around in either direction. 1 to 18 and 18 to 1 are both 17 pocket moves.
Just to get it out of the way, you still have "dir=2" ?
Correct. And it moves CW and CCW. Just won't wrap across the 1/18 'boundary' in either direction.
EDIT - just to be clear, it will cross from 18 to 1 during the homing move. If it is initialized at pocket 2, it will rotate past 18 to 1 and stop. But it will never take a wrapped shortest path during subsequent pocket command moves.
The wrap issue was actually a rather basic failure to properly re-acquaint myself with my own code. I think that I have fixed it now. carousel.comp.zip
Thanks much. I'll start testing now.
EDIT - wrapping works nicely, thanks.
Now I need to figure out why the pockets aren't always lining up despite the counts moved equaling SCALE/ number of pockets moved.
I'm chasing down a pocket alignment problem, and I think what I'm seeing is a cumulative error using your 1-6-12-1-6-12 test.
After the 3rd or 4th complete rotation I can see the pocket is misaligned from the spindle a bit, indicating my scale is off. Happens in both directions.
Is there anything other than carousel.N.scale which will affect how far the platter rotates for a given pocket command?
No, just the scale. It's possible that the error is in the .comp, of course, rather than your scaling. But, what are your gear ratios and microstep settings? 18 pockets and a scaling of 1250 looks a little suspicious.
Drivetrain is as follows
Stepper/drive = 4500ppr (microsteps are software adjustable in drive, not limited to 2x/4x/8x/10x/etc.)
Planetary reducer = 5:1
Pockets = 18
4500 * 5 = 22500 pulses per ATC rev
22500/360 = 62.5 pulses per degree
360 / 18 pockets = 20 degrees/pocket
20 * 62.5 = 1250 pulses/pocket
I adjusted the microsteps in the drive to give a whole(ish) number for an 18-pocket ATC. I also adjusted the following error counts in the drive down to 20 pulses (greater than that and it alarms), so I don't think the 'half a pocket off' is due to drive not going where I've commanded.
With SCALE = 1250, the pockets got misaligned by half a pocket within 1-2 complete turns (1-6-12-1-6-etc). After extensive testing last night (1250 to 1275 in increments of 5), setting SCALE at 1270 gave the best alignment over 4-5 rotations - but still not perfect.
I'll do more testing this evening and see if 1269 improves things unless you have a suggestion or I've made some error in my math.
Addendum - I don't think the error is in the .comp, as the carousel.0.counts is always within one (or zero) of the desired counts for a particular move. That's what threw me off at first - the math was adding up properly, but my pockets were still misaligned after a few moves.
Is there any chance that it is dropped steps? If you go all the way back to the starting position does it align? There is a chance, of course, that the steps will be dropped almost symmetrically so you won't see it. You did characterise the motion as "brisk" so try halving the speed and accel (or maybe divide by 10 to be sure) and see if it changes.
Anything is possible but I don't think it's missed steps:
Yes it's a fast ATC rotation, but the stepper is really only turning about 150rpm. Not like folks who try to run their 5mm pitch ballscrew machines at 1500rpm and wonder why they lose steps on a Z-rapid.
Perhaps the drive is lying to me, or perhaps there's a rounding error somewhere between the drive, my math, and carousel.
But it's behaving like I've got the scale wrong; I just don't understand why the math works out to 1250, but reality indicates 1270 is more accurate.
Maybe the planetary reducer is not exactly 5:1? It is not unusual to deliberately design-in a non-integer ratio: https://www.geartechnology.com/ext/resources/issues/0121x/Hunting-Tooth.pdf Though in a motion-control application like this it would probably be less likely.
It's a Stober PH series reducer. Datasheet says 5:1 and no mention of non-integer ratios.
I've got a different LCNC config with the ATC set up as a B-axis. I'll do a G0 B3600 after homing it and see where it lands.
Another thing to try would be to see if 1, 12, 6, 1 ends up in a different place to 1,18,17,16...1 If it is slip during accel then more accels to the same final endpoint should show more error.
Sorry for the delay, had a lathe run for a customer I had to get out the door last night.
Next round of testing: Changed accel from 100k to 10k, and speed from 11250 to 4000. It's now really lazy.
Last round of testing SCALE = 1270 was as close as I'd got to good alignment; had a slight overtravel misalignment after a few complete turns. Maybe half a toolholder width after 4 turns (~10 degrees).
Tonight, setting it to 1269 should have resulted in slightly less overtravel (or even undertravel). But the overtravel is now much worse than last testing with high accel. Within 1 complete turn it's ~10 degrees off.
Repeated test but commanded 1-2-3-4...18 to see what more accel events did. No change, still about 10 degrees off after one turn.
Reset accel and speed to 100k/11250 and retested still with SCALE = 1269. 1-6-12-1-6-12... resulted in a ~10 degree undertravel after 4 turns. 1-2-3-4...18 resulted in ~20 degrees of undertravel after one turn.
Repeated the SCALE=1270 test from the other night and same results. ~10 degrees overtravel after a few turns.
Final test: Changed accel/speed back to 10k/4k and scale to 1250 (what the math says it should be). Alignment is now really close even after multiple turns doing the 1-6-12 test. Too close to see any mislignment with the naked eye.
So... I'm kind of at a loss. It seems like accel/speed are having a significant affect on how carousel does some math or outputs to the stepgen. I would have thought that carousel would move exactly the correct number of pulses up to the point where the drive alarmed from lost steps.
How can carousel report X number of counts moved, but it's actually moving a variable amount depending on speed/accel?
It's still, to my untrained eye, behaving more like a velocity-mode system than a position-mode arrangement.
Stepgens are a velocity mode system, in that the controller commands a step-rate to get to the final target. There is an internal PID loop that governs the step-rate sent in order to exactly hit the target position. (Actually, with Mesa stepgens is common to run an external PID loop as this gives slightly better resilience to thread timing glitches) If the stepgen counts feedback matches the target counts then we can be confident that the stepgen has sent the correct number of pulses and that the carousel comp has calculated them correctly. If we agree that 1250 is the correct scale (and everything points that way) have you ever seen _over_travel at 1250? I think what you are seeing is that increasing the scale number is imperfectly compensating for an undertravel problem. And when you reduce the accel and speed the too-high scale is then overcompensating.
Does your drive specify a maximum pulse rate? Also, what is your step-time and step-space setting for the stepgen? I think that your pulse rate at 11250 is actually 11250 (because we are working with a scale of 1.00) so that's an 11kHz step rate, which is not particularly high. Try increasing the step-length to 10,000 (nanoseconds). This should still be short enough to reach the maximum required step rate, but should eliminate any chance that the pulses are getting lost at higher step rates.
Drive has the typical 200khz input limit for mid-range stepper drives. Stepgen settings: ATC_DIRSETUP = 10000 ATC_DIRHOLD = 10000 ATC_STEPLEN = 2500 ATC_STEPSPACE = 2500
On the other hand, I've got the same drive on X/Y/X with those settings and they've not given me any issues. Even with higher motor speeds and accel than I've set on the ATC. The ATC probably has higher rotational inertia however.
Unlike the ATC, all three of the axes have the standard PnCconf PID loop connections in my HAL file.
I'll lengthen the step length this evening and have another go.
Tonight's testing:
steplen = 10000 stepspace = 10000 scale = 1250 accel = 100k speed = 11250
Results were the same prior to changing step length/space. Visible under-rotation after 6 or so accel events (both 1-6-12 and 1-2-3...)
accel = 30k speed = 8k scale = 1250
Resulted in no visible misalignment after a few turns. I did not do a long-term test (clicking 3 halshow buttons per movement gets old) but didn't see any issues.
accel = 50k speed = 10k scale = 1250
Also resulted in no visible misalignment.
If it's possible, I'd be happy to try a PID loop similar to the ones connected to my axis drives. However, because those are connected through the joint.N.motor-pos-command and similar joint pins I'm not sure how to connect the PID to the ATC stepgen.
I've attached my main and ATC HAL files in case you think exploring a PID loop is worthwhile and can offer suggestions on connecting one in my atc.hal file.
If you're losing interest the last test seemed fast enough I'm not getting annoyed waiting for the ATC to line up. I can do some more testing at those settings to confirm I won't run in to a tolerance stack-up on a program with many tool changes.
On the other hand, I still don't understand where in LCNC the missing motion happens at higher accel settings.
I tried to set up a PID loop for the carousel stepgen but I wasn't able to figure out how to connect carousel > PID > stepgen and went back to more testing without it.
So far, so good with basic pocket alignment at the lower (50k) accel setting.
New issues after latest round: jog-fwd/rev don't do anything, except get stuck at state=20. No movement, no change in counts or counts-target.
Home-offset is finicky, or at least requires some care. If I set home-offset to something other than 0 and home the ATC (starting at any pocket other than #1) it lines up properly.
But... if I start homing while the ATC is already at pocket 1, carousel sees the index pin is high, and simply moves the offset amount - resulting in misalignment.
I can adjust my sensor position so I don't need a home-offset value, but the above behavior may catch someone out who doesn't have adjustable sensors or flags.
EDIT - another issue for the shopping list:
unhome doesn't work as expected (desired?) in the new counts-target mode. I can trigger unhome and carousel.0.homed goes low, but carousel will not re-home when enable is next triggered.
If I reset the stepgen position-reset the ATC starts moving, but I can't get carousel to re-home with any combination of enable on/off, position-reset, pocket-number. Only thing possible is to restart LCNC.
I think I have fixed the outstanding issues now.
[see LCNC forum post for initial discovery: https://forum.linuxcnc.org/24-hal-components/48045-carousel-comp-counts-mode-bugs-error
This is what I expected to happen:
After first enable and homing to index pin, carousel should move 1250 counts (+/- width) for every pocket change, regardless of direction.
This is what happened instead:
Error #1 - with carousel.0.align-dc set >0 carousel gets stuck at State 20 and becomes unresponsive after first pocket move (or jog-fwd/rev).
Error #2 - with carousel.0.align-dc set = 0, carousel moves an incorrect number of counts at direction changes.
Discussion Multiple tests of the align-dc function (at various values) result in carousel becoming unresponsive. Turning off the function permits more than one pocket move or jog, but counts are off by a significant amount at direction changes.
If carousel.0.fwd-dc (or rev-dc) velocity is raised fairly high, carousel does not stop rotating when searching got index or pocket pins, regardless of carousel.0.width setting.
At extremely slow velocity and accel setting, the deviation from desired pocket counts is less, but it's never close enough for correct pocket aignment.
Spreadsheet attached with testing results. All variables were adjusted one or two at a time, and while the exact count errors changed, the basic problem remains: pockets don't line up when changing direction from FWD>REV, or REV>FWD.
I am happy to do more testing, however I'm not fluent in halscope. If halscope is required for diagnostics to see state changes please help me with the desired halscope settings.
If this is just me not understanding the various carousel settings, forgive me for raising the issue... but maybe additional explanation in the MAN file would be helpful to newer users.
It worked properly before this:
First time testing ATC & carousel after fixing some hardware/electrical issues.
Information about my hardware and software: