Just wish I could find it. Nothing is making sense. The fact that an axis.read happens after the singleAxisMove reports a value less than the target distance but one that happens a little later (when you go to automatically reset the sprockets) reports a distance that is greater than the target … and representative of actually where the sprocket is.
I would say it doesn’t matter since the controller truly knows how long the chain is and that’s what matters. But if there’s a glitch here, I just get worried there’s a glitch somewhere else that results in overshooting the target during a cut (out of round circles, for instance). I’d say it might be because the distance moved is so high (2032 mm) in the singleAxisMove, but issuing a B09 for the same distance works fine… It’s baffling.
I guess one question I have is this isolated to something in my setup?
Here’s the logs. First I did an set zero on the sprockets (I had already did auto adjustment to 12 o’clock), followed by an adjust left chain. The brackets variables indicate the print statements I added to report the variables of singleAxisMove.
Sent: B06 L0 R0
B06 L0 R0
Setting Chain Lengths To:
Sent: B02 L1 R0
B02 L1 R0
Measuring out left chain
2030.67mm [value reported from axis.read at end of calibrate chain lengths]
Then I did another automatic and set zero. The error from 12 o’clock was 1.17 mm
Sent: B10 L
Sent: B10 R
Sent: B09 L-1.17
Sent: B09 R-0.0
Sent: B06 L0 R0
B06 L0 R0
Setting Chain Lengths To:
Message: Notice: Exiting the calibration process early may result in incorrect calibration.Sent: ~
I wonder if the issue that is seen with the B02 command is somehow related to the issue we see with Maslow measuring distance between motors.
Right now, GC issues a B11 S255 T3 L command to pull tight the left chain for three seconds. It’s immediately followed by a B10 L command. In the firmware, if I understand it correctly, there’s no pausing between gcodes. As soon as the B11 command is completed, it executes the B10 command. What if we need to give it a short period of time to “stablize” or whatever and do then do the read? Or should we do the reads during the loop where the directWrite to the gearbox encoder is happening and some how take the most stable reading during that period? Just some thoughts…
This runs the ‘L’ left motor at ‘S’ speed for ‘T’ seconds, and the next line isn’t executed until that is finished. I think the assumption is that will tension the chain and the gearing will prevent rebound. If rebound is a problem, wouldn’t waiting make it worse? Rebound probably isn’t happening though, aren’t we finding that the B10 value comes back short rather than long?
The theory is that it’s more of an reading problem than a physical problem. Maybe just reading something so soon after an event causes an issue. For example, when the B02 command is run and immediately read afterwards, the value is too low. Reading it sometime later provides the correct value.
Interesting… my B02 came up 01.17 mm long but reported to be 1.33 mm short at the conclusion of the singleAxisMove routine and later reported 01.17 mm long when the position was read a few seconds later.
These commands all send a chain length destination in millimeters to Motion:singleAxisMove() which accounts for the current position and calculates the step distance to move per PID loop (stepSizeMM) and the number of loops the movement should take (finalNumberOfSteps). Then it loops, commanding the axis is to move a step distance each time through, until the calculated number of steps have completed.
Axis uses _mmPerRotation to calculate movement from encoder changes, and _mmPerRotation comes from the pitch defined by sysSettings.distPerRotLeftChainTolerance or sysSettings.distPerRotRightChainTolerance, which come from GC $40 and $41 and/or groundcontrol.ini distperrotleftchaintolerance and distperrotrightchaintolerance.
main.py:computeSettings() calculates those distPerRotXXXXChainTolerance values from chain tolerance, chain pitch and gear teeth for each side.
Those types of correction parameters don’t affect it. Those parameters determine the target chain lengths for certain gcode commands. When you issue a B02, you just telling the controller to turn the sprocket a specific amount of times based upon the number of teeth of the sprocket and the pitch of the chain.
Sorry @blurfl, I started this, got distracted, you responded, and I hit Save
I just ran into this myself today. Surprised this has been an issue for two years. It was very disturbing when I saw it, I was concerned that our encoder counts could have gotten messed up again. But I was relieved to find this thread.
The issue wasn’t really software, but more of a controls issue. The difference between B02 and B09 is that B02 directly called axis.detach() when it was done. This is a no-no. The PID controls should handle detaching the axes directly, and nothing else except maybe an E-Stop.
What was happening, was that the final position call was made to endMove, and then before that could be completed, B02 would get the axis position and print it. This is why it reported being less than the commanded length. Then it would call detach() before endMove() could finish its job. When the axis is detached while moving it has some momentum so it would carry on past the desired location. endMove drives the axis to a stop by reversing to brake at the proper location.
I guess that’s as good of a place as any. I’m not really sure how to manage the webcontrol releases. I used to build everything on a set of VMs and an RPI, but with the move over to the new repo and other people working on it, not really sure where we stand with it.
Nonetheless, great sloothing. That problem bothered me for a very long time and I never could figure it out.