User Tools

Site Tools


blog

This is an old revision of the document!


Card sorting machine

Android: Netrunner

My eldest son and I occasionally play a game called Android Netrunner together. It's a 1v1 competitive card game where each player assembles a deck of about 50 cards from a pool of a few hundred. It went out of print a few years ago but then a community group took over designing and making new cards. It's similar to Magic: The Gathering in some ways, but without the scummy expensive blind card pack collectathon. You buy a Netrunner set and you get all the cards.

The game has two main factions, Runner and Corporate. When building a deck you choose cards from your faction. There are rules that define what cards a valid deck can contain, and different deck compositions have different strengths and weaknesses. My eldest plays the Runner faction, and I play Corporate.

A problem arises when you're always playing against the same person: Each player is trapped in a constant cycle of adaptation to their opponent's deck. Exploiting their weaknesses and mitigating your own. This tends towards a see-saw pattern of wins and losses, and involves a lot of deckbuilding which neither of us particularly enjoy.

Solution (?)

I think it would be fun to build a robot that can do deckbuilding for you. The entire card pool is well-documented with online tools like Jinteki.net, and the rules for deck validity are easy to codify. I think it might be fun to have a computer formulate a random-but-valid deck, and to build a robot to physically pluck those cards out of the pool so you can be ready to play.

Motive force

I've used stepper motors in a few projects, recently my sand drawing robot. A stepper motor is able to turn its shaft like a regular motor, but can also move it in tightly-controlled “steps”. Usually 200 steps per revolution, but “microstepping” can divide a step up into sub-steps. 16 or 32 microsteps-per-step are common, giving angular accuracy in the range of 0.1° to 0.01°. You can make a normal motor turn by applying the appropriate voltage. In contrast stepper motors require carefully sequenced pulses to turn.

I've been looking for an excuse to play with closed-loop stepper motors. These have the stepper control circuitry built-in, and a sensor to measure the angle of the shaft. You provide the motor a DC voltage and step/direction signals to make them turn. They also have a serial UART interface, which means you can send them commands from a microcontroller rather than counting out hundreds of step pulses.

Matthias Wandel has an excellent video on them:

A photo of a stepper motor with various colourful wires attached. A small OLED screen on the back of the motor reads "-34.8k° 0.04err <-99Kclk". Some trees are visible through a window in the background.

I settled on a MKS Servo42C because they are cheap, readily-available and have a UART interface.

Diversion into interfacing

I was shocked to learn there was no batteries-included python library for controlling these steppers, so I wrote one and published it on pypi. Now you can control your stepper with code like

from time import sleep
from servo42cUart import Servo42CUart

s = Servo42CUart("/dev/ttyUSB0", 9600)

# Start turning clockwise at full speed
s.set_constant_speed(Servo42CUart.Direction.CLOCKWISE, 127)

# Wait a second
sleep(1)

# Stop turning
s.stop();

# Turn 360 degrees, assuming 16x microstepping, as fast as possible.
s.set_angle(Servo42CUart.Direction.CLOCKWISE, 127, 200 * 16)

Eyes

The robot will need to be able to identify a card for it to be sorted. I plan to do this with a webcam and tesseract-ocr. This is a very powerful text recognition engine that Google publishes open-source. Some early testing has yielded promising results. I set up a HD webcam with a goose-neck worklight, with a white background. The webcam is connected to an old Raspberry Pi Model 3, running Debian 10.

Other similar projects have used more complex machine learning smarts to identify the whole card, graphics and all, rather than just looking at the text. I'm going to see how far the text-only approach takes me, so I can keep all the brains on a single old RPI.

A photo of a netrunner card standing upright against a white background with carpet beneath it. A light is shining at the card from an oblique angle, and a webcam is sitting on a piece of black plastic pointing at the card. The webcam is about 150mm from the card. Other junk is visible in the background. A cobbled-together test rig.

A frame from the webcam showing the NOISE netrunner identity card. The view through the webcam.

tesseract-ocr read:

NOISE

IDENTITY: G-mod

Whenever you install a virus program,
the Corp trashes the top card of
R&D.

“Watch this. It'll be funny,”

Which is pretty impressive for such a bodge-fest.

A frame from the webcam showing the INFILTRATION netrunner event card The view through the webcam.

Result:

INFILTRATION
Gain 29 or expose | card
Bring back any memories, Monica?’
John “Animal” McEvoy
0 2012 oats le Coast LLG, @2012FFG

Next steps

Next up I have some mechanical design work to do. The machine must:

  • Support a stack of cards,
  • Provide outlets through which cards can be fed,
  • A means of transmitting the motor torque into card-sliding action,
  • Supporting lighting,
  • Supporting the camera.

Should be fun! I'm anticipating some challenges:

  • Handling sleeved and unsleeved cards,
  • Glare from the lighting,
  • Camera focus/exposure issues,
  • Ensuring single-card feeding at different stack heights,
  • Keeping the camera view unobstructed by mechanical gubbins,
  • Fuzzy-matching card text against the card database.

2025/05/21 01:08 · tjhowse

Summer 2024-2025

In a gap between two surgeries we rushed out for a quick afternoon sail.

2025-02-01

A photo of Sam on the trampoline of the boat at home

This was our first outing with the new halyards and the gopro. The forecast was for 10-13 knots. It was gusting to about 18-20 when we got there, with a light drizzle. We got out into the water without too much hassle. Michelle narrowly avoided throwing the car keys into the river. I succeeded in throwing my sunglasses into the river, but managed to retrieve them before they sank.

Michelle recorded a brief snippet of footage while we were underway. I need to build a mount to attach it to the end of the boom.

The boltrope on the foot of the mainsail pulled out of the boom again. The outhaul had come loose again. The new halyards worked great. No worries at all. Unfortunately I forgot to record the track of our journey. Next time, for sure.

2025/02/07 05:29 · tjhowse

Spring 2024

Winter's over! Sailing season is here again! We had a brief attack of 35°C weather, then it dropped by 10°C, then it warmed up a bit again.

2024-09-01 Father's day

On Australian father's day I invited my Dad out on the river with the boys and me. This time I decided to take us upriver to check out Newstead. We'd be sailing past HMAS Moreton and a few citycat stops.

A screenshot of a map showing our sailing path up the river and back again.

For this outing I wanted to try a different way of rigging the jib. Our jib is slightly undersized for the boat, so there's a fair length of halyard, about 300mm, between the head of the sail and the pulley on the mast. This means the head can flop about when we're getting close to tacking, spilling wind. This can make it difficult to maintain momentum through a tack. As an experiment I threaded the forestay through the halyard shackle, and secured the jib tack slightly higher up along the forestay, rather than right at the bottom where it usually sits.

We launched from our usual Colmslie recreation reserve boat ramp and headed upriver. There was a nice 10 knot northerly and patchy cloud cover. There were a few citycats cruising around. Sailing downwind of the big apartment blocks on the north shore was a bit annoying as the wind was pretty squirrelly. We tied off to a floating anchor point marked “NOT FOR PUBLIC USE” just off some fancy riverfront houses in Bulimba and broke out the eski for some apple slices, mint slices and zooper doopers. The wind spun us around the buoy a few times as we ate.

After the break we sailed back downriver to the boat ramp. We had some difficulty in tacking once or twice. My new jib rigging didn't seem to have helped much. Both the halyards are quite stretchy. I think it might be worth replacing them.

2024/09/09 04:03 · tjhowse

Winter (??) Sailing

It's starting to get a bit cooler here in Brisbane. By which I mean it gets below 20°C at night. Spare us your scorn, we know we deserve it.

2024-05-06 The river

A screenshot of a map showing our sailing path down the river and back again.

Another trip out onto the Brisbane river from the Colmslie recreation reserve. Not much to report on this one. We had a bit of trouble launching due to dock congestion, but we got out and had a good time. I lectured the kids on the loathsome game of golf and its barren monocultured hellscapes. We had a play around with the boom vang on our downwind run back. Kept the boom much more well-behaved. Lost my sunnies into the river when I was dropping the sails. RIP.

2024-05-19 Wivenhoe Dam

The stars finally aligned! We had a free Sunday coming up and a 8-10 knot forecast. We had a few things to check first. I picked up a new handful of cheap sunnies from the safety shop, and I tightened the loops holding the luff of the jib stretched along its leading edge wire. Hopefully this should keep it happier.

A photo of a join between white tiller handle and an aluminium bar.

I replaced the rivets holding the tiller onto the arm joining both the rudders, they were getting a bit loosey-goosey.

A photo of Sam, wearing a helmet, sitting on the driveway playing with a small anchor.

I showed Sam how to deploy our tiny little anchor. If it looks woefully inadequate: that might be reasonable.

I got the boat all packed up and ready to go on the night before, using a new checklist I put together:

☐ Radio
☐ Bungs
☐ Charts
☐ Water
☐ Food
☐ Sunscreen
☐ Life jackets
☐ Anchor
☐ Sails
☐ Reef shoes
☐ Leatherman
☐ Sail tape
☐ Tape
☐ String
☐ Multigrips
☐ Spare rope
☐ Trailer tires pumped
☐ Gopro
☐ Key floats
☐ Tell someone where we’re going and when we’re getting back

A photo of a pot of porridge on an induction cooktop Getting up at 08:00 on a Sunday, early by our standards, demands a pot of porridge to bribe everyone out of bed. I may have overdone the cinnamon.

A photo of a freezer bag stuffed with food and zooper doopers The traditional sailing lunch bag.

A photo of the boat on the trailer behind our car Mostly packed and ready to roll.

Wivenhoe is about 1.5 hours' drive from our place. I threw an extra ratchet strap around the top of the boat to hold it down to the trailer. This marginally reduced boat-flying-off-trailer anxiety. We decided to put in at the Hays Landing boat ramp.

A screenshot of google maps showing the route to the Hays Landing Boat Ramp.

The drive was uneventful. We listened to a few episodes of Sawbones to keep the kids sane. We got a few spectacular peeks of the lake and the dam itself on the way in. The Hays Landing boat ramp was closed when we got there, so we diverted slightly to the nearby Billie's Bay ramp. By the time we got there the extra strap I put around the boat had worked its way loose and was flopping uselessly. Erk.

A photo of the boat on the trailer with the sails up. Alex and Sam doing pre-launch checks.

The sky was a perfect blue gradient while we rigged up, without the slightest breath of wind. C'mon BoM, don't fail me now. I was given hope by another sailor turning up at about the same time as us. He had an eastern European accent. Czech? Bulgarian? Ukrainian? We had a chat with him about his boat. He had a kind of turbo-kayak, with a sail, retractable outriggers, oars, and a sweet pedal-driven flippy-flappy underwater paddle mechanism. Very cool.

Just as we launched the wind started to pick up enough for us to get underway. Phew.

A photo off the back of our boat, looking back towards the boat ramp about 100m away. The sky is a stunning clear blue.

A photo off the front of the boat.

Our loose goal was to explore around the dam and find interesting stuff. There was plenty of wildlife about, including pelicans and herons/egrets. The kids had been nagging us for ages to let them go for a swim off the boat. We didn't really want to do that in the Brisbane river, as it is pretty scummy. We took advantage of a lull in the wind by throwing in our brand new anchor, followed by the kids.

A photo of Alex smiling in the water, holding onto the boat.

A photo of Sam in the water, very excited. We tied a rope around Sam's life jacket, just in case.

A photo of both the kids holding onto the front of the boat.

Both kids pretty quickly soured on swimming around the boat, possibly due to the extremely reasonable Deep Sea Willies combined with the cold (for us) temperatures. Just after we got them back onboard the wind picked up and we immediately started dragging anchor as if it wasn't there. Lesson learned: Get a bigger anchor, or drop sails at anchor.

A photo of the boat up on a rocky shore.

We pulled up on a clear patch of shore on the far side, about 2.5km straight across from where we started, to have a walk around and stretch our legs. We found a lot of cool rocks. There was a Turdis barely visible on the other side of some scrub. We later learned that slightly further along the shore was a dedicated boating stopping point, with a picnic table, toilets, and a bin. Whoops!

A photo of Michelle a short distance away along rocky ground. Michelle exploring.

After our stop the wind picked up to around 10-15 knots. We zoomed back across the dam to check out a picnic area just north-west of the boat ramp. Michelle lost her hat, as per tradition, but we recovered it without incident.

A screenshot of a track on a map showing a small loop-de-loop. The crossing point shows where the hat landed.

A photo of the boat pulled up into some shore scrub Our second stop, at the Hays landing BBQ spot.

A photo of Michelle and the kids walking to a pagoda

A photo from the pagoda back towards the boat

A photo of Alex and Michelle. Alex is eating a strawberry. Alex and Michelle

I was a little concerned the building wind would carry our boat off the shore, so we had a quick afternoon tea and got back underway quickly. Some people on the shore came to watch us sail off. We were getting some good splashes over the bow and the kids didn't appreciate getting soaked. We decided to head back to the boat ramp, but not before a little extra exploration to see some cows.

A photo of the boat pulled up onto some grass. Alex is standing in the water. Michelle and Sam are watching from the shore. Back at the boat ramp.

A photo of me holding Sam aloft on the shore. Sam and me.

And that's about it! The kids were zonked and fell asleep in the car on the way home. Next time we come out here we're going to be more ambitious and head up to an island we can see on the maps, and maybe visit the stopping point around the corner from where we first stopped.

A screenshot of the a track on a map showing the whole sail. It looks a bit like a dolphin swimming from right to left.

Video

2024/05/21 12:13 · tjhowse

Brisbane River

We went for another couple of sails on the Brisbane river from the Colmslie recreation reserve.

2024-01-14 Mum and Dad

We've managed to avoid any serious sailing mishaps, growing our confidence in our boat and our abilities. I invited my parents to come out with us on a day with some gentle wind. At the ramp I talked my Dad through helping me raise the mast. With him, Alex and Sam onboard we headed upriver a short way and checked out Eat Street from the perspective of the river. We crossed paths with a CityCat, who gave us a friendly toot, then headed back to the dock to swap in my Mum. We had very light, intermittent winds; perfect for leisurely sightseeing. We pootled downriver to the Colmslie Beach reserve for lunch. The tide was 2.8m, of an absolute 2.9m max, so the beach was entirely underwater.

I picked a spot relatively free of swimming kids and cruised up onto shore. I did run straight over someone's fishing line but they didn't seem to mind. I think they were preoccupied with the novelty of a sailboat crashing into the shore. I bush-bashed through some long grass towards a tree to tie off the boat. Something in the brush spiked through my reef shoes into my foot. I'm not sure what it was, but I got a tetanus shot the next day just in case.

A photo of our sail visible through a gap in the trees down a hillside.

Meanwhile Dad had driven from the boat ramp to the beach, going via maccas to pick up some lunch. We managed to beat him there on account of some drive-through misunderstandings. We'd just finished up lunch, including the customary zooper dooper dessert, when an ice cream van drove into the carpark blasting greensleeves. It took a few seconds for them to drown in a tidal wave of kids.

We hopped back on the boat, paddled out out of the shoreline wind shadow and made a straight run back to the dock to disembark. A great time was had by all, except for Sam who said it was “too boring”. I remembered to start a path recording on my phone, but forgot to turn it back on after lunch.

A screenshot of google maps showing the trace of the path described above.

2024-01-27 Windy

We'd planned to head out to Wivenhoe Dam on this public holiday, but we had a bit of a sleepy start to the day and didn't get out the door until about 11:00. Wivenhoe's a little over an hour's drive away, so we opted for another day on the river. The wind forecast was about 10 knots, gusting to 15.

A photo of the boat on the trailer behind our silver corolla under our carport. Sam is sitting on the boat, Michelle is standing to the left and Alex is visible in the background.

There was a good drizzle coming down at the boat ramp, something Michelle felt compelled to note regularly. There was lots of traffic at the boat ramp, many people were putting in jetskis and silently tutting at the softies doing the opposite to get out of the rain. The dock was covered with jetskis and dinghies so we put our boat in and guided it over to a little patch of beach nearby to get the jib rigged. I spent a good while trying to get the top of the jib taut, but our halyards (sail raising ropes) have too much spring in them to get things as tight as I'd like.

Rod, the resident boat ramp bogan, stopped by to compliment us on the tension of our forestay. Had had a mate with us who was very happy to see a caper cat. He reckoned it might date from the 80s. Rod also mentioned that we should have a “boom vang” on our boat for proper sail tension. A few hours after we got home that afternoon I realised why the boom and mast had fixing points spaced about half a meter from where the boom meets the mast (the gooseneck), and why we had an extra jumble of ropes and pulleys (blocks) laying around. I'd thought it was a spare main sheet but it's actually supposed to be used to pull the boom down to give the sail a better aerofoil shape. We'll give that a shot next time.

We headed downriver at a good pace. The wind regularly dipped entirely, but we got a few good zooms in on the way out under the Gateway motorway bridges. They're pretty spectacular constructions. We need to buy a rugged waterproof camera of some form so we can take photos while on the boat. I'm tempted to pick up a second hand gopro or similar. We had a look at a massive superyacht called “Helios”, possibly this one?. Recently sold for AUD$61 million. A cool AUD$380 000 to rent for a week, plus expenses (naturally). Jesus fucking christ.

We headed north across the river to check out a big green crane barge. It was big and green. The wind got pretty spicy around this point, with some solid gusts that launched us through the water. The recording of our path shows we peaked at 9 knots, or 16.6 km/h. There was about half a meter of chop, enough to break over the nose of the boat and soak us all. Sam was beside himself with joy.

We headed back upriver to the boat ramp. The dock was full as we approached, so we landed on the beach to take the sails down while the kids inexplicably filled their jocks with sand and rocks. Getting the boat from the beach to the ramp was a massive pain in the arse. I eventually worked out a system to keep the boat angled into the wind in a way that kept it from bashing into the side of the ramp while gradually working it down to where we could get it onto the trailer. Next time we'll wait for a spot on the dock.

I hung up and hosed down the sails when we got home. They were pretty grotty and covered in salt water spray.

A photo of the boat under our carport with one sail hanging from the rafters and the other draped over the boat.

A screenshot of a map of the above described path.

2024/01/27 06:33 · tjhowse
blog.1644210320.txt.gz · Last modified: 2022/02/07 05:05 by tjhowse