When to put generated code under version control

29. June, 2022

Many people think that when a computer generates code, there is no point to put it under version control. In a nutshell: If you generate the code once with a tool that you’re confident with, there is no point to put under version control. If you need to tweak a lot, version control will make your life so much easier.

Decision tree:

  • Do you need to tweak the options the code generator until everything works? If so, then yes.
  • How confident are you with using the code generator? If not very, then yes.
  • Is the code generator mature? Then not.

Some background: Let’s compare a home-grown code generator which is still evolving with, say, the Java Compiler (which generates byte code). The latter is developed by experienced people, tested by big companies and used by thousands of people every day. If there is a problem, it was already fixed. The output is stable, well understood and on the low end of the “surprise” scale. It has only a few options that you can tweak and most of them, you’ll never even need to know about. No need to put that under version control.

The home grown thing is much more messy. New, big features are added all the time. Stuff that worked yesterday breaks today. No one has time for writing proper tests. In this kind of situation, you will often need to compare today’s output with a “known good state”. There is a dozen of roughly understood config options for many things that might make sense if you were insane. Putting the generated code under version control in this situation is a must have since it will make your life easier.

The next level is that the code generator itself is mature bit it offers a ton of config options. Hypothetically, you will know the correct ones to use before you use the generator for the first and only time. Stop laughing. In practice, your understanding of config options will evolve. As you encounter bugs and solutions, you will need to know what else a config change breaks. Make your life easy and use version control: Config change, regenerate, look at diff, try again.

In a similar fashion, learning to use the code generator in an efficient and useful way will take time. You will make mistakes and learn from them. That won’t stop a co-worker from making the same mistakes or other ones. Everyone in the team has to learn to use the tool. Version control will prevent from one person breaking things for others.

How

Write a parameterized unit test which generates the code in a temporary folder. In the end, each file should be a single test which compares the freshly generated version with the one in the source tree.

Add one test at the end which checks that the list of files in both folders is the same (to catch newly generated files and files which have to be deleted).

Add a command line option which overwrites the source files with the ones created by the test. That way, you can both catch unexpected changes in your CI builds and efficiently update thousands of files when you want.

The logic in the test should be:

expected = content freshly generated file
actual = content  of the file in the source tree 
      or just the file name if the file doesn't exist (makes it
      easier to find the file when the test itself is broken).

if expected != actual, then
    if (overwrite) then copy expected to actual
    assert expected == actual

Use a version of the assert that shows a diff in your IDE. That way, you can open the file in your IDE and use copy&paste out of the diff window to fix small changes to get a feeling how they work.

Or you can edit the sources until they look the way they should and then tweak config options until the tests confirm that the code generator now produces the exact desired result.

Bonus: You can tweak the generated code in your unit test. It’s as simple as applying patches in the “read content of the freshly generated file” step. One way you can use this is to fix all the IDE warnings in the generated code to get a clean workplace. But you can also patch any bugs that the code generator guys don’t want to fix.

Workaround

If you don’t want to put all generated code under version control, you can create a spike project to explore all the important features. In this spike, you create an example for every feature you need and put the output under version control. That way, you don’t have to put millions of lines under version control.

The drawback is that you need a team of disciplined individuals who stick to the plan. In most teams, this kind of discipline is shot in the back by the daily business. If you find yourself in a mess after a few weeks: Put everything under version control. It’s a bit of wasted disk space. Say, $10. If you have talk about it with the team for more than five minutes, that’s already more expensive.


Children can become anything they want

26. June, 2022

The difference is that some people think “they” means “the children” while other people think it means themselves.


Another Reason to Avoid Comments

16. April, 2022

There is this old saying that if you feel you have to write a comment to explain what your code does, you should rather improve your code.

In the talk above, I heard another one:

A common fallacy is to assume authors of incomprehensible code will somehow be able to express themselves lucidly and clearly in comments.
– Kevlin Henney


Dark Forest is a Fairy Tale

16. December, 2021

The Dark Forest, an idea developed by Liu Cixin for his Remembrance of Earth’s Past series (also known for the first book “The Three-Body Problem” is just a fairy tale: Interesting to think about, there is a morale but it’s not based on reality.

Proof: We are still here.

The Dark Forest fairy tale is a solution to the Fermi paradox: If there are billions of planets like earth out there, where is everyone? The Dark Forest claims that every civilization that is foolish enough to expose itself gets gets wiped out.

Fact: We have exposed ourselves for millions of years now. Out planet has sent signals “lots of biological life here” for about 500 million years to anyone who cares.

Assuming that the Milky Way has a size of 100’000 light years, this means every civilization out there know about Earth for at least 499.9 million years. If they were out to kill us, we would be long gone by now. Why wait until we can send rockets to space if they are so afraid of any competition?

How would they know about us? We can already detect planets in other star systems (the current count at the writing of this article is 4604, see http://www.openexoplanetcatalogue.com/). In a few years, we’ll be able to tell all the planets close to us which can carry life, for values of close around 100 light years. A decade later, I expect that to work for any star system 1’000 light years around us. In a 100 years, I’ll expect scientists to come up with a trick to scan every star in our galaxy. An easy (if slow) way would be to send probes up and down out of the disk to get a better overview. Conclusion: We know a way to see every star system in the galaxy today. It’s only going to get better.

Some people worry that the technical signals we send could trigger an attack but those signals get lost in the background noise fairly quickly (much less that 100 light years). This is not the case for the most prominent signal: The amount of oxygen in Earth’s atmosphere. If you’re close to the plane of the ecliptic (i.e. when you look at the sun, the Earth will pass between you and the sun), you can see the Oxygen line in the star’s spectrum for thousands of light years. Everyone else has to wait until Earth moves in front of some background object.

There is no useful way to hide this signal. We could burn the oxygen, making Earth inhospitable. Or we could cover the planet with a rock layer; also not great unless you can live from a rock and salt water diet.

For an economical argument: When Ruanda invaded the Democratic Republic of Congo to get control of Coltan mining, they made roughtly $240 million/yr from selling the ore. China makes that much money by selling smart phones and electronics to other states every day (source: Home Deus by Yuval Harari). My take: killing other civilizations is a form of economical suicide.

Conclusion: The Dark Forest is an interesting thought experiment. As a solution for the Fermi paradox, I find it implausible.


What are Software Developers Doing All Day?

6. November, 2021

Translate.

Mathematics? Nope. I use the trigonometric functions like sin(x) to draw nice graphics in my spare time but I never use them at work. I used logarithmic last year to round a number but that’s about it. Add, multiply, subtract and divide is all the math that I ever do and most of that is “x = x + 1”. If I have to do statistics, I use a library. No need to find the maximum of a list of values myself.

So what do we do? Really?

We translate mumble into Programming Language of the Year(TM).

Or more diplomatic: We try to translate the raw and unpolished rambling of clients into the strict and unforgiving rules of a programming language.

We’re translators. Like those people who translate between human languages. We know all the little tricks how to express ourselves and what you can and can’t easily express. After a while, we can distinguish between badly written code and the other kind, just like an experienced journalist.


#TeamSeas

2. November, 2021

Upset by all the plastic in the oceans?

https://teamseas.org/

Check https://teamseas.org/ for details.


When stupidity meets cleverness

31. October, 2021

we get a potency of impossibilities.


FreeCAD Tutorial Office Chair Part 4: Five Struts and One Receptacle

25. July, 2019

Here is part 1: FreeCAD Tutorial Office Chair Part 1: Setup and Constraints

Or go to the previous part.

While You Were Away …

I fixed the transparency and the hard edges of the joint plus renamed a few nodes:

Here is the file: Office Chair Tutorial Part 04 Start

The Base

The base of our chair should have five struts and hole to support the gas spring:

Struts

Create a new body, call it “Strut”.

Create a sketch, use the same plane as the joint (YZ Plane).

You should end up with this:

Draw a corner around the vertical joint axis:

For the arching strut, we’re going to use two B-splines with control points. For each arch, create three control points (so the whole spline should have 5 points):

Those “fans” look weird, right?

Those visualize how “bent” the spline is (= speed of change of direction, longer lines = faster change). If you have nicks in those curves (like above), it can mean trouble. Let’s ignore those fans for now.

Note how I created a sharper bend by moving two control points closer together (lower spline, two control points to the left).

Make sure that the left end points of both arches are constrained to the end points of the corner.

Keeping Stuff in Place

One thing I would like to do is to constrain the “joint end” of the strut to the “Vertical Rotation Center” which we created in the joint. That way, the strut will keep it’s position relative to the axis of the joint. The problem is that this datum line is part of the “Rotating Joint” body.

To change this:

  1. Close the (incomplete) sketch.
  2. Right-click the node “Vertical Rotation Center” (below “Rotating Joint”)
  3. Select “Copy”
  4. In the dialog “Object dependencies”, chose “No” (don’t copy the “Vertical Joint Axis”, too)
  5. Right-click “Strut”
  6. Select “Paste”
  7. Rename the new node to “Vertical Rotation Center Copy”

Double click “Sketch006” to continue working on it.

Try to apply a horizontal constraint between the bottom left edge and the datum line.

Turns out, we can’t select the datum line … now what?

Let’s try a “local coordinate system”.

  1. Close the sketch
  2. Make sure “Strut” is active
  3. Select “Office Chair Tutorial Part 04” in the tree
  4. Create a local coordinate system
  5. Select the ring we used as base for the datum line (where the axis and the joint meet)

Hm …. I would prefer the Z axis to go “up”. To achieve this, check “Flip sides”:

Nice. Click “OK” to create the coordinate system.

You’ll get this dialog:

Remember we selected the circle? It’s part of the joint body. FreeCAD now wonders how we want to handle this situation. Do we want to create something which will stay put when we change the joint? Or maybe we just want to use the new coordinate system in the body it references (dependent copy)? Or should changes to the joint move the coordinate system?

We want to last of the options since one end of the arch should stay where the joint is. Select “Create cross-reference” and “OK”.

Hm … there doesn’t seem to be a way to use the new coordinate system in the existing sketch.

I also can’t find a way to use it in a new sketch.

The sketch always asks for a plane. The toolbar offers a datum plane, let’s try that.

I again select the circle, attachment mode is “Concentric” but the new plane is coplanar (= in the same plane) with the circle. We need something that is perpendicular to the circle. Flip sides won’t help this time, set “Roll” to “90 °”:

The orientation looks good but what about the origin? From the preview, the plane seems to be way to far up/right. Let’s hope for the best. OK, “Create cross-reference”, OK.

Create a new sketch and now ,we can select our now DatumPlane:

Hm. Why is everything upside down?

3D is annoying. I bet this is because of our 90 ° roll. Edit the plane, select “Flip sides”. If we create a new sketch, this looks much better:

What about our existing geometry? I couldn’t find a way to copy the elements and constraints over, so they are lost. Just make the old sketch visible and draw something similar.

Now for the big moment: Will the constraints use the new origin?

Yes!

Working from left to right, I get this fully constrained sketch:

The blue distance at the bottom is a constraint in “reference mode” which basically means it just shows a value but doesn’t take part of the solution process:

  1. Toggle to reference mode. Some constraints will turn blue.
  2. Take the blue “Horizontal distance” tool and select points at the ends of the strut.

Close the sketch and pad it, 10 mm, symmetric to plane plus some fillets gives me:

Socket for Gas Spring

For the central socket, we need another datum plane at the far end of the strut. Otherwise, attaching the chair to the base would be complicated.

Note: Another solution would be to join all parts in a compound and then move the compound around until the upper end of the strut is near the origin (right now, it’s just the other way around).

Note 2: Before you design something complicated, you may want to figure out a good place for your origin. Our situation happened because I chose to build the first foot around the origin.

The new datum plane is parallel to the first one but shifted to the right (= positive along the X axis)

I tried several ways to achieve this but I have a feeling that creating work / datum planes is not designed very well at the moment. There are lots of complicated options but nothing that really works well.

In the end, I used this complicated mess:

I selected “Plane face” as mode, then clicked on the yellow face. I created a sketch based on this plane. Jumping back and forth between the sketch and the plane, I played with the attachment offsets until it was kind of where I wanted it:

One revolve and a few fillets later, I had this:

Getting Five Struts From One

The last step is to make five copies of the strut plus foot.

While I could use copy & paste, the copies would be independent. So no change I made to the original would propagate. To solve this, there is a Array tool. This tool can create copies and arrange them, too.

As rotation axis, we need a datum line. Select one of the circles around the socket:

Click OK.

Since we want to copy three bodies (wheels, joint and strut), we first need to combine them into one body.

  1. Switch to “Part” workbench
  2. Select “Dual Wheel” and “Rotating Joint” in the tree
  3. Click “Make Compound”
  4. Rename the new node to “Joint with wheels”
  5. Select “Joint with wheels” and “Strut”
  6. Click “Make Compound”
  7. Rename the new node to “Strut with foot”

Your tree should now look like so:

To create five copies:

  1. Switch to “Draft” workbench.
  2. Select the node “Strut with foot”
  3. Click the menu “Draft” / “Array”

At least in my version of FreeCAD, this didn’t have a dialog or panel to configure the array. Instead, you get this:

Change these values:

  • Put “polar” into “Array Type”
  • Put “1” into “Number X” and “Number Y”
  • Put “5” into “Number Polar”

You’ll get this:

Remember when I said that it’s important to decide where to put the origin? That’s why.

Also, there is no way to select a rotation axis (the datum line from above).

How to fix this?

One way is to move the “Strut with foot” so that it’s other end is near the origin. This can be done by changing the “Position”. On my case, the y value:

Okay … better … I guess. What’s with the wheel at the center? Doesn’t want to play with the rest?

Enough for today. Here is the file if you want to fix it yourself: Office Chair Tutorial Part 04


FreeCAD Tutorial: Office Chair

24. July, 2019

This is a multi-part tutorial how to create an office chair with FreeCAD (documentation).

FreeCAD is a parametric 3D CAD software. This means it remembers all the operations you did to come up with a shape. Some of these operations can be modified later, for example if you create a line which is 1 cm apart from another, you can change the distance to 1.5 cm. FreeCAD will then redo everything that happened afterwards to give you the new result.

As we’ll see, this means you’ll have to give precise instructions (even when you don’t know, yet) that you can amend later.


FreeCAD Tutorial Office Chair Part 3: Mirrors and Holes

24. July, 2019

Here is part 1: FreeCAD Tutorial Office Chair Part 1: Setup and Constraints

Or go to the previous part.

Rotating Joint

To attach the wheels to the chair’s base, we need a rotating joint like so:

As usual, create a new body, add a sketch. This time, I’m going to use the YZ plane because that will feel most natural when padding (extruding) it:

You can click on the name on the left or the rendering of the plane in the 3D view. In this case, it’s easier to do in the 3D plane since that gives you an immediate idea where you’ll work.

Note that I keep the wheel visible this time so I can see that everything lines up properly.

Hm. I can’t see what I’m doing … That’s the problem with 3D. Now I could make the wheel invisible but I don’t want to (see above). If only I could turn this around … and I can. Notice the white stuff in the top right corner with the word “Right” on it? That means we’re in the “Right Side view”. We want the opposite, the “Left Side view”. You can go there with the items in the menu “View” / “Standard Views” / “Left” or by pressing the “6” key or by using the icons in the toolbar:

… Okay, where is everything???? Probably somewhere outside of the visible volume. How to fix? Menu “Views” / “Standard Views” / “Fit all” or by clicking the toolbar button. The shortcut “V, F” didn’t work for me (it activates the fillet tool).

Much better.

Design this outline:

When I was at this stage, I had a weird bug: I couldn’t select points anymore. If you look closely, you can see that the “lines” are rendered over the “points”:

It’s this “feature”: https://forum.freecadweb.org/viewtopic.php?t=36202

To fix, go to the “Model” tab, select the sketch and change the value for “Map Reversed” to “true”:

This is an instance where you notice that you’re in a 3D world. If lines and points were at the same “depth”, it would be hard to distinguish between them. That’s why the software draws points “above” the lines which literally translates to a different Z position. If you look at this from behind, it will look the other way around: The line will be “before” or “above” the point.

The view should now look like this:

or rather:

sigh Instead of just switching the depth of lines and points in the outline, they flipped the whole thing.

Oh well. Here is the fully constrained outline:

Some pointers:

  • The two starting points of the arcs at the top are horizontally constrained to the Y axis with a distance of 0 mm.
  • I’ve constrained the outer arc to 88 ° (always 90 ° is so boring). To make the inner arc do the same, I’ve constrained the closing line to be perpendicular to the outer arc.
  • All endpoints are constrained to another

Close the sketch when you’re happy and go back to the “Part Design”. With the “Rotating Joint” active, click “Pad a selected sketch” to get this:

There are a couple of minor and major problems with this. First, lot of hard edges. But more importantly, the lower part stands out:

Open the sketch again and add a fillet by selecting the corner and clicking the icon:

This gives us 2 degrees of freedom.

One because we lost a constraint (25 mm distance from origin for the left side) and the other one is the radius of the fillet.

Constraining the center of the fillet to the X axis gives a nice smooth transition from the vertical shaft to the axis. Close the sketch to get this:

Not bad. A couple more fillets:

This brought up a problem: I can’t apply a fillet to the inside of the “cover” because the software gets confused when two 1 mm fillets are applied to material that is 2 mm thick.

To fix this, go back to the sketch, change the thickness to 2.2 mm:

and try again:

Much better.

As can see, having to set up all those constraints is a pain in the beginning. But later on, when you find out you have to go back and fix something, it’s a huge time saver. Since you’ll always find mistakes late in the design, this really helps.

Rotate it around in the 3D view. Looks good, doesn’t it?

But it’s not finished. We’re missing an axis, the opposite wheel and a hole for the axis.

To drill a hole (or any shape) through a volume, create another outline inside of the same body (“Rotating Joint” is still active) and then use the use the “Hole” tool.

Now, the “Fillet004” (in my case) is in the way. We can’t see anything. Toggle it’s visibility. Again, go to the “Left” view and set “Map Reversed” of the new sketch to “true”.

Pick the circle tool, make sure you click on the origin (it will light up) and pull out the circle.

Select the circle and constrain the diameter (not the radius!) to 3 mm. It should now look like this:

Close, select the sketch and click the “Hole” tool to get this:

Mother of all scary dialogs, creating nothing from something is darn complicated … ahem

Here is the whole documentation for this monster: https://www.freecadweb.org/wiki/PartDesign_Hole

Why is it so complicated? Well, in the real world, holes can be drilled (metal) or formed (plastic when it’s pressed into a form). When drilling, the tip of the hole isn’t straight unless you use a special drill or maybe a mill. Also, some holes go all the way through while other are just depressions.

What’s worse, there is no hole. I’ve toggled visibility of the wheel and made the joint partly transparent (Right click on “Rotating Joint” / “Appearance…” / Transparency: 40). I see the circle but not hole:

So what’s going on here? Remember the “Map Reversed”? Yes, it’s interfering right now. Basically, the hole is there but it points away from the joint (into the wheel). It’s not cutting the wheel since the wheel is a different body and there is no connection between the two. That’s why the hole has no visible effect.

If we select the sketch, switch “Map Reversed” back to “false” and then click somewhere (if you’re using the keyboard: Press TAB once), we get our hole:

But there is something odd. When rotating the view around (I’ve colored the wheel blueisch and the joint yellow), the holes don’t line up properly:

It looks as if the two holes have different diameters. Why? In the wheel sketch, we used the formula to get 3/2 mm. In the outline for the hole, we used 3 mm diameter. So what is the problem?

Answer:

Why do we have to give a diameter here when we have a profile? Leave a comment when you find out.

Here is the solution:

  1. Switch “Depth” to “Through all” to avoid other nasty surprises
  2. Set “Diameter” to “3 mm”

Come to think of it, 3 mm axis for a chair seems kind of … thin. But I don’t want to change it since it’s in several places already. This isn’t good. What if someone wants to replace the axis with a weaker material and we suddenly need 0.1 mm more? As we’ll see, there is a solution for that as well. For now, let’s stick with the 3 mm axis.

All right. We have a wheel, we have a joint and a hole. Time for the second (mirror) wheel.

Select the “Half Wheel”, chose the mirror tool, select the feature “Wheel Revolution” and … ???

The orientation looks wrong but why is it yellow?

Five minutes later Okay, none of the planes work. What’s going on here?

Hint: Go back to “Model”:

That looks wrong. Mirrored should be part of “Half Wheel”, not the joint. What happened? Well, “Rotating Joint” is active (= bold), therefore the operation is added to it.

Undo. Double click “Half Wheel”. Mirror. Um … better?

But when you click around, you quickly get an error “Transformation failed” and “One transformed shape does not intersect support”. In a nutshell: The “Part Design” workbench can only create connected parts. In our case, there is a gap between the two wheels. They will eventually be connected by a metal axis but that’s not really part of the wheel.

What now?

We need a different workbench: “Part”. It has another mirror tool which doesn’t work in features but parts:

If you think about it, it makes sense: When the wheel is assembled, you will get two plastic wheels per foot.

Let’s try again. Click the tool, select the “Half Wheel”, the correct (YZ) plane (which is the one in which we designed the joint sketch):

Click OK to get:

The color looks good and all the fillets are there (they were gone when we used the feature mirror tool). But it’s inside the joint. What’s wrong, now?

If you remember in part 2, we designed the wheel outline to be 1 mm away from the Y axis:

When we mirror that on the Y axis, we get something which is again only 1 mm away from it. But we need 10 mm for the joint.

There are several solutions:

  1. We could offset the mirror copy by 1 cm using “Placement”
  2. We could move the original “Half Wheel” (not the outline) 5 mm away from the origin using “Placement”

Let’s try the second solution:

  1. Select “Half Wheel”
  2. Open “Placement”
  3. Open “Position”
  4. Change the “x” value to “5 mm”
  5. Click somewhere or TAB out of the field

Already much better. Both wheels moved away from the origin by changing only a single value. Neat.

That leaves us with centering the joint.

Open “Rotating Joint”, double click “Pad”

 

Check “Symmetric to plane”

 

to get:

Nice. From the top:

No contacts all the way through. But we have an ugly hole when looking at it from the right:

That asks for a bigger fillet. Try 5 mm:

Last step: The rotation axis of the joint (at the top).

  1. Double click “Rotating Joint” to activate it
  2. Create sketch
  3. Use the XY plane
  4. Make sure you’re in the “Top” view
  5. Hide the “Hole”
  6. Draw a circle near the top between the two wheels
  7. Constrain to Y axis (0 mm distance)
  8. Constrain vertically to X axis (18 mm)
  9. Diameter: 6 mm

The result should look like this:

Pad to 45 mm:

Change the node name to “Vertical Joint Axis”

Select the top circle and click the “Chamfer” too to get:

Finally, let’s cut a ring into the vertical axis so we can use a spring to keep it in the socket.

  1. Create a new sketch
  2. Use the “YZ” plane
  3. Use polyline to draw a triangle which bites into the axis near the end

Rename it to “Groove Outline”

Next, I need to rotate this “Groove Outline” around the center axis of the cylinder. There is no such axis but we can create one. In the “Part Design” workbench is a tool “Datum line” for this purpose.

Click on the circle where the cylinder and the joint meet (1) to get a faint yellow line (2):

This gives us the rotation axis that we need. Click OK to save the new “DatumLine”. Rename it to “Vertical Rotation Center”

  1. Select “Groove Outline”
  2. Click the “Groove a selected sketch” in the toolbar (1)
  3. Chose “Select reference…” for “Axis” (2)
  4. Click on the datum line (3)

and you should already see the groove. Click OK and we’re done:

Here is the file so far: Office Chair Tutorial Part 03

Next part: FreeCAD Tutorial Office Chair Part 4: Five Struts and One Receptacle


%d bloggers like this: