Optical Calibration Demo and Three Hours Working on a Bug

I still don’t know why it happens but I spent three hours trying to figure out why the controller kept losing usb connection when I put a serial.println statement in a particular spot in a function. I can load up tons of serial.println statements before one certain calculation, but if I put it after that calculation, usb disconnects. I gave up and decided it must be some kind of race condition unique to microcontrollers. Maybe someone smarter than me can give me a clue.

Anyway, I went back to work on optical calibration yesterday and today and have made a whole lot of progress. I would be much further along if I was a good enough programmer that I didn’t have to spend 90% of my time correcting idents, missing colons, missing semicolons, stupid copy-paste typos… sigh.

Using a turned block of wood from @marm, a usb endoscope, and three relatively cheap ARCH E sized blueprint of 1/2-inch squares spaced 3-inches apart, I’ve managed to “calibrate” my center 0,0 position so that it’s truly the middle of the board. That’s a huge step and the next step, actually having calibration points offset the target coordinates, is really, really close (I needed the three ARCH E sheets to cover the whole board). I’ve spent the last 12 hours getting to this point, so it’s time for a break.

I’ve posted a youtube video of ground control running through the process. Basically, it determines the distance from the center of the image to the center of the center square. It then moves up and to the left and then scans left to right each square and calculating their offsets from center (9 squares, basically a 3x3 matrix at this time). Ideally, when it scans the center square again, you’d get the same result, but nothing is perfect in life. Finally, it sends all 31x15 offsets to the controller (only 9 of them have values). At this point, I’m only using the center value to make an adjustment. The controller adjusts the positions of the motors based upon how far off the center square was. In essence, it will raise/lower or shift left/right the motor coordinates used by triangularInverse so 0,0 is 0,0 (or at least pretty close to it). That was step 1.


I’m interested, can I take a look?


Yeah, I’ll mark where it is in the code (it’s in Kinematics::recomputeGeometry())… everything will be up on the holey maslow github repo in a few once I verify, again, it won’t work.

This version, by the way, adds settings, modifies groundcontrol.ini, needs some additional python packages, etc. So handle it with care.

1 Like

Here’s a link to the repo:

if you uncomment line 82 of kinematics.cpp it will disconnect.

Sure enough, anything can print before that line, nothing after. Stack issue?.
The values being computed are public though, so available to print after returning from the recomputeGeometry() call. I see you already added them to the $$ report.

Beats me… I worked around it and found the bug I was chasing. Thanks for verifying.

1 Like

Any chance that print was in interrupt called code?

I don’t know about the interrupt code aspect… whatever it is I’m not stressing about it since I’ve worked around it.

I’ve updated the routine to do interpolation (at least I think I did) on the 3x3 matrix and remeasured the error. It looks like within 3-inches of the center, I’m within about 0.5 mm of where I want to be with all errors being of the same sign. The best way to look at the values is to compare the difference between them. For example, a 6-inch square cut around the center would have the top left corner at -3,+3 and the top right corner at +3, +3. The x and y error difference between those values is 0.294 mm and 0.392 mm, respectively… so the 6-inch square would only be off by ~1/64-inch.

The camera is not perfectly installed in the center and the router housing is not perfectly aligned with the center point of the ring, so that’s something I need to work on.

[xErrors, yError]:

[0.343, -0.539] [0.441, -0.319] [0.637, -0.147]
[0.319, -0.392] [0.490, -0.196] [0.662, -0.049]
[0.319, -0.515] [0.588, -0.392] [0.441, -0.049]

1 Like

It doesn’t seem to be. It’s after four gnarly trig calculations, and you can print what you like after the first three, but after the fourth it’s no go. The order of the four doesn’t matter, you just can’t print after whichever one is fourth.


There’s a few things and issues issues I think I need to figure out and/or overcome:

Commands to move very distance may not actually move the sled

Last night I modified the routine to have the sled “home-in” on the square to get a real error at the target location. So if you tell it to go to +3,+3 and during calibration and it needed to go to +3.01, +2.98 to get there, then it’d have a valid offset value to use. The goal was to get to within 0.250 mm but a concern is whether or not an ever-so-small movement command would actually result in an accurate movement of the sled. For example, if the x,y position error was 0 mm, 0.3 mm, it’d send a command to lower the sled by 0.30 mm… would it really move or move that far? I’m using a ring kit at the moment and different kits may (and likely) behave differently. I have to imagine that downward force of gravity overcomes the static friction between the smooth veneered plywood sled and the calibration pattern (currently paper) but I’m worried that that a very small move may not actually move the sled or move it the correct distance and this will result in an calibration error. How small of an adjustment can we really make and have the sled move?

Position of camera with respect to center of rotation is critical

I made a 3D printed a bushing that fit my 7.3 mm endoscope camera into a 1/2-inch hole in a turned block (after 4 attempts I got one to fit both i.d and o.d.). However, I’m not sure just how accurately the 1/2-inch hole is placed inside the wood block because when I mount it to my drill press (I don’t have a lathe), the block wobbles a bit. Trying to get really, really accurate when the camera’s position is changed as the sled tilts is going to be a challenge. I’m contemplating a laser cut sled (or at least a drilling template) to make sure the router body is positioned where it needs to be and probably a laser cut camera mount that will fit into router body. The better the camera can be centered, the better the calibration. Need to find a laser cutting service I think.

Getting a calibration pattern to cover the entire 4x8 sheet of plywood

Many months ago when I started working on this, I had looked at getting a vinyl banner printed with the calibration pattern but most of them are scrim-vinyl and have a texture which I think will be problematic. However, I found that blueprints work fairly well and are cheap. However, paper is fragile, but I found out that Office Depot will print blueprints and laminate them… even up to ARCH E (36x48) for $12.00 (Add $10 delivery though… can’t pick it up locally)… Instead of covering the whole board, the plan is to do it in quadrants using just one ARCH E sheet. The idea is to find center on the spoilboard, drill a 1/4-inch hole there and insert a dowel. Take one of the sheets (see image) and cut out 1/4-inch holes in the center of two of the squares to use as registration points. With the dowel placed through one of the holes, align the edge of the sheet with the edge of the plywood, clamp/tape/whatever in place and remove the dowel. At that point, it should be level and plumb. I don’t know yet if I need to cover the holes during calibration… will find out. This is what the pattern looks like:

That’s scary. Back when it was my job to worry about these things I’d suspect a memory management issue, try to duplicate it in a stand alone test, and instrument (which also introduces potential problems…) the heck out of it. Then it would be turn out to be something else

Big concern here is where else does it bite us

This bite is pretty obvious - the serial connection drops so the Arduino gets reset. If this were happening elsewhere, we would know…

Just an update…

Laminated calibration pattern is supposed to arrive on the 21st… can’t wait to give it a real test… I’ve torn my blue print three times so far just moving the sled over it. I think it binds up on the paper just from friction/weight and that’s led to some of tears. Fortunately, paper is easily repaired by taping a 8.5x11 sheet of squares on top of the damaged area so I can still work on the software. Still, I think laminated sheet is a better long term solution.

I discovered I hadn’t compensated for the camera being rotated and realized my previous x, y error measurements were wrong. The distance between center of squares was correct, but the x and y components were wrong if the camera wasn’t perfectly aligned so up is up. So I’ve tweaked my testCamera.py app (what I used to experiment with) and was able to rotate the coordinates to result in the square in the image being plumb/level. The routine works along as the camera is less than 45 degrees rotated. Beyond that it can’t figure out what the correct compensation is. If your sled tilts more than 45 degrees when in use, then you have bigger problems to overcome. I’ll move the rotation compensation over to GC soon.

Another discovery was that it is important to keep the clear dust shield on the front of the router attached. While doing an automatic test, I noticed the sled started to move in a freakish manner. Turned out a moth had flown inside the opening and was confusing the software. Instead of trying to calibrate on the square, it was trying to calibrate to the moth… which wasn’t staying still.

Finally, I think I made good progress on the accuracy of the measurement routine and the software now deals with glitches/marks on the pattern as long as they aren’t too big. So if the router slides over a bug and leaves a streak, as long as it’s not bigger than the square, you’d be ok. Also, I’ve managed to adjust the routine to deal with “fuzziness” on the edges of the squares so the results are more consistent.

I still need a solution for getting the camera perfectly centered. I looked at laser printing a camera mount but the overall cost seems rather ridiculously high and I’m not sure if the kerfing won’t result in an issue. I’d like to make a circle to fit in the router body with a hole inside of it (maybe 1/2-inch to 1-inch diameter) and then a series of “bushings” that will allow me to adapt a 7.3 mm (current sized camera) to the hole. I’m looking at trying a different camera (8.5 mm) so it would be nice to have a bushing for that size. I know I can do inside/outside profiles with a router based upon the size of the bit, but my understanding is that laser kerfing is not exactly as precise. Anyone with experience? I’ve never done laser cutting before.


I thought you mentioned you had a 3Dprinter? Couldn’t use that?

Can you send any pics of what you’re doing. Hard to visualize. Thanks.

To make the bushing, yes. I did that for the turned block I have (took 4 attempts to get the scale right… PLA shrinks apparently). But for the part that fits in the router body, my printer isn’t big enough. It’s that cheap small monoprice delta thing. So I was going to get some 3&5/8 inch circles laser cut, but maybe I’ll just build a jig to do it on plywood… or maybe, maybe, I can get the machine calibrated enough with what I have to make the circles :slight_smile:

Which part? the optical calibration or the camera mount?

Both. Sorry.

I will when I get back out the shed. Basically, I have a cylindrical block of wood mounted into the router body (where the actual router would be) with a cheap usb endoscope camera in the middle pointing down at the spoil board. I then have a series of 1/2-inch squares, spaced 3-inches apart, printed on a large sheet of paper attached to the spoil board.

The idea is if the camera is exactly where the router bit would be, then the middle of the camera’s image would be precisely the middle of the router bit. So if the squares are mounted correctly where the center of a square is exactly at the middle of the spoilboard, the camera’s image and the software can determine how far off from actual 0,0 the sled is when told to go to center. The software then tells the sled to move that amount and keeps repeating that until it gets to within 0.250 mm of being perfectly centered. For example, to get to 0,0, the software may have to tell the controller to go to 1.5 , 0.7 for the chain lengths to be correct. When the controller has this value, it knows that when you tell the controller to go to 0,0, it needs to calculate the chain lengths based upon going to, keeping with the example, 1.5, 0.75. This process can be repeated for each square on the board, providing 460 calibration points spaced 3-inches apart. The controller then can use interpolation to determine the offsets for any coordinate and can use extrapolation for the very extreme edges.

The hope is that you could enter in reasonable default values of distance between motors, rotational radius, and chain sag to get close and then let the calibration error matrix make the fine adjustments.

1 Like