M0o+ Hungry Cattle

How M0o+ solves Hungry Cattle

Hungry Cattle is probably the easiest of the three main Pi Wars challenges to do autonomously and so is the one I chose to tackle first.

The basic premise is delivering “cattle feed” (rice) to three troughs, placed at known positions within the arena.

The first thing that becomes apparent is that a full run of the challenge requires a lot of rice. Each trough is nominally 100x100x50 mm, and they must be half-filled to count as done. That’s a minimum of 750 cubic centimetres of rice, close to a kilogram!

3 trough’s worth of rice

Apple for scale. We didn’t have any bananas.


Originally I thought I might have 3 separate rice dispensers, each holding enough for one trough, filling them all up at the start of each round. This would mean visiting all 3 troughs in a row, so I made some very early tests using just the robot’s IMU and a single rear-facing distance sensor to navigate between the tree troughs.

  1. Turn to face North
  2. Drive “North” until 375 mm from South wall
  3. Turn to face East
  4. Drive “East” until 1010 mm from West wall
  5. Turn to face North
  6. Drive “North” until 875 mm from South wall
  7. Turn to face West
  8. Drive “West” until 1010 mm from East wall
  9. Turn to face North
  10. Drive “North” until 1250 mm from South wall
  11. Turn to face East
  12. Drive “East” until 1010 mm from West wall

The long route

The course diagrams are taken from the challenge page on piwars.org

Surprisingly this really simple single-distance-sensor approach worked fairly well. You can tell that my simple “proportional-only” heading controller was badly tuned, with all the wiggling the robot does.

However, after briefly experimenting with 40 mm PVC pipe, I realised that carrying the full amount of grain would be prohibitively bulky and heavy, so I started over.

Bottle dispenser

The new plan: Carry enough grain for one trough at a time, returning to the barn for refilling between each trough. This is likely more driving than doing all three in a single run, but much more practical in terms of size and weight of the grain hopper.

I settled on using a section of a 2L Pepsi bottle, screwed into a 3D printed holder with a flap opened by a servo. The cross section of the flap is small so it’s not under much pressure, and the servo doesn’t have any trouble opening it when it’s full of grain.

With this new one-trough-at-a-time approach I need a new navigation scheme.

Now the robot will visit each trough in a kind-of “star” pattern.

Star route

I assume that the robot starts somewhere close to the middle of the barn, and from there it determines what direction it needs to face to point towards the next trough.

It points in approximately the right direction then uses the camera to find the trough in its field of view, and drives towards it, using the camera to refine its heading to keep the trough in the middle of the camera view.

Using the camera means that even if the starting position isn’t exactly where the code thinks it is, the robot will correct for it as long as it can “see” the trough. This uses the “find the red blob” routine from the previous post.

It uses a combination of the camera and the front laser distance sensor to gauge the distance to the trough, and when it gets close it stops and uses the boom arm to position the dispenser over the trough.

Once the trough is emptied (just a simple timer to wait for a few seconds) the robot reverses back in the direction of the barn. It knows where the trough is, and it knows that it’s next to the trough, so it can make a good guess at what direction the barn is.

The rear distance sensor is used to stop when it gets close to the wall, then it pauses for a couple of seconds to get refilled and moves on.

Here’s a shaky-cam video from when I’d just got it working:

This works well enough to get reliable runs, so I’m happy!

Of course, it doesn’t always go to plan…