Holey Triangular Calibration

I’ve lost track of what setting is being discussed, but if the setting is Advanced/PositionError, keep in mind that when changing that setting from within GC, you’re supposed to quit and restart after changing it. I’ve wasted much time forgetting this - the warning is there in the setting description tact, but why would I read the instructions :crazy_face:?

The PositionError is used to warn if the a chain’s expected position is too far different from the chain’s real position. That difference is calculated every 10mS, a difference of more than PositionError for either chain triggers the alarm. This is a measurement of the movement of the chains - not movement of the sled. A vertical movement of the sled needs very little movement of the chains but a horizontal sled movement amount is closer to the chain movement amount. Check this for yourself by using the arrows, see that moving up or down is more forgiving that moving right or left. The arrows use the Advanced/maxFeedrate. Use this to watch the error values during the moves:

tail -f log.txt | grep "\[PE"

in macOS that would be

tail -f /Applications/groundcontrol.app/Contents/Resources/yourapp/log.txt  | grep "\[PE"

I find that longer horizontal moves at high feed rates accumulate enough error to trigger the alarm, and that the higher up the workarea you are the more this is emphasized. Something to keep that in mind when tuning the PositionError value.

I explored all this by setting Advanced/maxFeedrate to 1250 and Advanced/positionErrorLimit to 20.0 and restarted GC. Using the arrows, I ran horizontal 16" moves back and forth across the workarea every 4 inches above the center until I got to the top, all the while while watching the “[PE:…” position error. It stayed below 2.0 for both chains.:+1:
When I upped the maxFeedrate to 1350, the error climbed beyond 20mm error and the alarm triggered; it looks to me like there would need to be some PID tuning to get above a 1250 feedrate without going over 2mm of error. Under 1250, it looks like a 2.0mm limit might be reasonable. Turning the random 10% error in FAKE_SERVO off didn’t change this, the 2.0mm value still seems to work at the top of the sheet as well as everywhere else.
I’m just tuning the ‘best case’ of the alarm setting here, on the bench with no motors or chains attached. This doesn’t improve the machine’s accuracy and it doesn’t take the physical realities of the motors into account. If the power supply can’t provide enough current, or the driver board has a weakened chip, or the chain binds and keeps the sprocket from turning freely, the 2.0mm alarm might well trip. That is a different chapter.

and for the record, I am wrong about this due to the randomness that’s been
added in. sorry.

David Lang

1 Like

I am trying to verify the firmware implementation of the modified triangularInverse function that implements the catenary and chain elasticity calculations. I uploaded the modified function into the arduino, and it did not validate. I printed out a number of the machine parameters to try understand the difference. I found that the variable. sysSettings.leftChainTolerance is 63.5. It is clearly set to 0 in GC. I have tried changing the value from GC and re-connecting to the Arduino, but nothing seems to change the 63.5 value. I am trying to understand why this is happening. Does anyone have any ideas?

A change was made to the method chain tolerance was used. What version of GC and firmware are you using?

1 Like

That should have been obvious. I am using an older version. I will go ahead and update and try again.

Hi everyone,
So I was working on that “list of Sources of Errors” thread. And I realized that some parameter adjustments are probably important and missing in the firmware inverse() functions.

Specifically, it appears like the Geometry calibration efforts would be limited mainly by missing “top beam flex” and “chain stretch” correction parameters.

It appears too that some parameters (like the motor distance) can partly cover this like if they are set to wrong values.


1 Like

I really appreciate your ideas here. Good work on the sources of errors thread. Some parameters are so sensitive that you really shouldn’t calibrate them. For example, if I include sled weight as a parameter, a measurement error of 1 mm results in a doubling of sled weight. It probably introduced more variation than it eliminates. My recommend for these kinds of variables is to set them to the best estimated value and leave it.

I went ahead and updated to 1.25 of GC and the Firmware. I re-tried connecting to the arduino. When I first connected, the result was the same, Left and Right Chain Tolerance values were 63.5, even though they were changed in GC, and both GC and the Firmware were updated.

After I disconnected and re-connected, this was fixed. Both chain tolerances returned to 0.

1 Like

:+1: :beers:

After updating to 1.25 GC and Firmware, no z-axis installed, the program freezes for z-axis movements. It used to pop up a window that said something like “Move Z-Position to XXX”, and I would have to manually move the z-axis, then confirm the movement in the popup. Does anyone have any thoughts on this? Is this an unanticipated change for 1.25?


Actualy, after looking at the file, I am thinking it might have something to do with a message that was reported in the command prompt. Below is text shown in the command prompt.

One Machine Position Report Command Misread
Machine Position Report Command Misread Happened Once
One Machine Position Report Command Misread

1 Like

I am having a difficult time understanding this. I have updated firmware and GC to 1.25. I have B10L and B10R commands in the calibration G-code. However, when it plays on the machine, the B10L and B10R lines look like they are read as B09 commands, which make the machine fed out a certain length of chain. The G-code that is printed back to GC doesn’t read B10L and B10R. Instead, it reads B09L-0 and B09R-??, where ?? is not a consistent number. The B09 commands are in addition to a G91 and a G90 command. When I delete the B10L and B10R commands, the B09 commands go away. Does anyone have any thoughts on this?

I don’t think there have been any significant changes to the stock gc or firmware that would result in this. Is your code up on github? I could look at it and see if I spot something if you’d like.

This is the simplest file with B10 commands that caused the behavior.B10_Commands.nc (52 Bytes)

I didn’t realize you were trying to use this in a gcode file. Is this something you load using the ground control’s open gcode file routine or is this something you load within the code you added?

This is loaded using the GC open gcode file routine.

When you issue a B10 command, it tells the firmware to return the length of a particular chain. When GC receives this, it executes a call back function. My suspicion is that since you are running this via gcode file, you haven’t set a call back to be executed. Therefore, the last call back that was set is getting executed… and if you were previously setting your sprockets vertical, it could be the callback associated with the ‘set sprockets automatic’ command.

My question is why are you issuing B10 commands in a gcode file? :slight_smile:

Good question. It is ultimately unnecessary. I was able to delete the lines and I was able to move forward without issue. However, I thought this was a bug. It appeared as strange behavior to me.

So, whenever GC receives something back on the serial port, and it is playing a gcode file, it executes a callback function. Is that correct? I do not understand the logic behind this. It would seem like there should be some intentional callback command that would be unique from chainlengths.

It only executes a call back function upon receiving a chain length measurement from the controller and the controller only sends one when GC sends a B10 command.

I want to provide an update on my progress from this last weekend. This is going to be a partial update, and I will have to edit this post in the near future, because I don’t have all the files and information available right now.

This is a summary of what has been done so-far.

  • The kinematics are updated to include chain tension, the catenary equations, and chain-stretch
  • The updated kinematics equations were updated in the firmware to mirror the updates in Ground Control
  • The calculations were validated between GC and the firmware
  • A calibration routine was developed which leverages curve-fitting routines from scipy.
  • The holey calibration test-cut pattern was updated to include a sixth point at the top-center of the workpiece
  • Several simulated calibrations were done to ensure the curve-fitting routine worked correctly.
  • The GC 1.25 updates were merged in
  • The updated calibration was run on the physical machine
  • The physical machine calibration resulted in the maximum error of the 12 measurements of around 1.3 mm.

At some point, I would like this to become a pull-request. I cannot think of any reason these updates shouldn’t be part of the standard installation. Maybe everyone isn’t aligned on that, so at least we will have to have a discussion. I think that is the purpose of the pull-request.

There are still a few things that need to be done before this could be merged into the main branch.

  • There are a few parameters that are hard-coded into firmware, kinematics.cpp: the chain-stretch coefficient and the chain-weight. These should be moved into a System Settings location.
    • I am still not familiar with the architecture of the firmware, so I could use some guidance and help on where to put them.
  • This calibration module would need to be integrated into GC as part of the GUI.
    • I have no prior knowledge of GC or Kivy, so I could use some guidance and help regarding how to implement that.

Here is the output of the calibration. The leading whitespace did not work out, so it is difficult to read.

Each Index corresponds with one measurement in the map.


I’ll look to incorporate it into webcontrol when you push it to your repo, but I notice you have a requirement of scipy… is it possible to use numpy instead? The reason I ask was that it takes ages (over an hour) to build on a raspberry pi. Every now and then I end up having rebuild the thing and I’ve found I could use numpy for my curve-fitting instead of scipy… and numpy builds much, much quicker. It’s not the end of the world if I need to put scipy back in… but I spent a while getting it out :slight_smile:

I suggest that before spending a bunch of time making a PR for it, we should find a way to determine whether or not “everyone is aligned” on incorporating it. I’d hate for you to spend time and energy on getting a GC PR together and it not be incorporated. I’m tagging @bar in hopes he has an idea on how we can collectively greenlight something for inclusion prior to developing the PR. Maybe have a list of requirements that can be agreed upon so you know what needs to be done.