I’ve recently managed to 3D print an apriltag with the help of folks on slack. Since there was some interest in how it worked, I wrote what I did here.
Apriltags consist of two colors, black and white. So I need the printer to be able to do that (it needs to have two heads). The printer I have access to is the
Ultimaker 3 extended. It needs two separate
stl files, one for each color. The two files are then merged in the slicer program (
Cura in my case). So first I needed to create these
Here I save two stl files, one for each color, and plot the result just to be sure it looks right. To create the apriltag itself I use the excellent AprilTags.jl package made by the good folks at
JuliaRobotics. They have been instrumental in this whole (and more) process! Huge thanks to them!!! For building the meshes and plotting them I used Makie, so convenient.
using GLMakie, AprilTags, GeometryBasics function get_meshes(tag, color, scale) meshes = GeometryBasics.Mesh for (xy, c) in pairs(IndexCartesian(), tag) if c == color # include only white pixels x, y = Tuple(xy) cube = Rect3D(Vec3f0(scale*x, scale*y, 0), Vec3f0(scale)) push!(meshes, triangle_mesh(cube)) end end merge(meshes) end fig = Figure() id = 9 tag = getAprilTagImage(id) # a 10×10 grayscale image of the tag colors = Dict("black" => zero(tag), "white" => one(tag)) for (i, (k, c)) in enumerate(colors) merged = get_meshes(tag, c, 2) ax = Axis3(fig[i, 1], aspect = :data, title = k) mesh!(ax, merged, color = c) save("$id $k.stl", merged) # "worked" without MeshIO? end
I then tested the printed result by photographing the tag with my cellphone. Again using
using AprilTags, FileIO img = load("img.jpg") detector = AprilTagDetector() tags = detector(img) freeDetector!(detector) tag = only(tags) drawTagBox!(img, tag)
Which looks like this (you’ll have to really zoom in on the tag to see the superimposed tag-box drawn on it):
So this whole thing worked really well. We’ll be printing these tags to mount on dung beetles for pose tracking.