Cowshed configuration optimization simulation

cowsim

You know when you have a traditional barn full of cows, and the modern age forces you to make the choose whether to switch career or to invest in a milking robot? That feeling. Making the jump to a milking robot system requires you to redesign your cowshed from a static stall based model to a dynamically free range model. In the former, the milking equipment moves from cow to cow, but in the latter, the cows need to move to the equipment.

So not everyone have faced this problem, but I kinda did, and I immediately though it sounded like a fun project to simulate! Not that it would be of any help, but I would be fun!

DeLaval VMS Source: DeLaval Voluntary Milking System™

There are a handful of products on the marked to solve this problem, but most of they require you to buy and install a gigantic milking robot in a fixed location in you barn and start pushing cows through it. News at eleven; cows are not smart. They don't understand that they need to be milked, and nonetheless how. Instead, what you do is redesign your barn to incentivized cows to move a lot, and when they pass – what we call – «the smart gate», they are diverted into the milking robot.

The cows actively wants a couple of things, food (in some different flavors) and sleep, and the system takes advantage of that. Most of all they want concentrate, it's like candy for them. You design the system so that you get the perfect balance of physical movement between these activities, and – if a cow has not been milked the last 12 hours or so – you divert it into the milking robot. It will be feed concentrate there as well, so the cow is happy either way.

I build this so it would be possible to run it as a genetic algorithm, where each cowshed configuration would equal a possible solution, and the production of milk (and maybe number of dead cows x_x) would act as the heuristics function. I never got that far. Neither did I get to the point to add the actual milking robot. But I had fun.

So what are we looking at here? Here is some early testing in a poor screengrab.

cowsim

So is obviously a cow. is basically a water tray, is where grass is severed, and is a concentrate feeder. Less interesting is which is a wall. But more interesting is which is a one way gate and the which is a cow bed(!) - the cow's preferred chilling area.

# Create a random cowshed configuration
place_random_agents("wall", groups=50, max_agents=10, min_agents=3)
place_random_agents("onewaygate", groups=25, max_agents=1)
place_random_agents("grass", groups=5, max_agents=5)
place_random_agents("water", groups=5, max_agents=3)
place_random_agents("feeder", groups=5, max_agents=2)
place_random_agents("bed", groups=5, max_agents=20, min_agents=20, cluster=True)

# Place some cows
for cow in self.cows:
x, y = None, None
while True:
    x, y = self.random_pos()
    if self.barn.is_cell_empty((x, y)):
        break
self.barn.place_agent(cow, (x, y))

# Run it!
for s in range(self.config["steps"]):
self.step = s
for cow in self.cows:
    if cow.alive:
        cow.step()

# For each step, have the cow figure out what it want the most and have it
# move towards that objective
def step(self):
    self._update_state()
    new_objective = self._calc_objective()
    if new_objective != self.current_objective:
        self._update_target(new_objective)
    # move toward current target
    self.move()

Using the settings above as the initial random borad, you get solutions like this. cowsim

Without the heatmap, here is a simulation at full speed. cowsim

Some bonus images where things are running a little bit slower. cowsim cowsim

Horrendous code quality, but it is available at https://github.com/torvald/cowsim.