Mythos, the cat.

Dogs have been my favorite pets since I was very young — I had a female Basenji for many years in childhood — but life in a compact apartment can be hard for them. Furthermore, they require a lot of attention, which can be hard for us busy humans. Cats, however, do not pose such problems. These felines are known to be a highly independent and live perfectly well in relatively limited environments. Hence, when my girlfriend and I decided to have a new pet recently, we made a logical decision: we bought a Ragdoll cat. Perhaps to compensate for this cold rational calculation, we named her Mythos. In the few weeks since she arrived I have learned to appreciate cats’ many other virtues, such as cleanliness, curiosity and a certain untamed, elegant, hunting spirit.

People usually have pets for companionship and fun. I’m no different. But as a scientist who studied the computational properties of autonomous agents for years, I simply cannot resist the appeal of having a complex autonomous entity in a controlled physical environment at my disposal. Therefore, as soon as I decided to have a cat, I started conceiving ways to experiment with it.

In relation to our brief existence in this speck of cosmic dust, knowledge at our disposal is simply unbounded. Thus, it is wise to combine interests and opportunities to optimize the amount of beauty we can contemplate and create. For this reason, and also because I happen to be interested in learning more about electronics and robotics, for many months now I’ve been looking for an excuse to build an Arduino-based device. Mythos finally provided me with the motivation I needed.

MES-1 front view. The laser pointer is attached on the left, the infrared sensor is on the center-bottom. The Arduino controller is in a black case on the back. The whole thing stays together through bolts, beams, alligator clips and plastic fasteners.

Cats are hunters which, unlike clumsy dogs, operate with military precision: they enjoy mapping territory, tracking movement, ambushing targets — and finally chasing for the kill. The potential for electronic devices to provide them with relevant interactions is therefore enormous. Surprisingly, most commercial products I managed to find in pet shops are simply not worthy of these noble creatures. So I decided to create my own. The objective at that stage was to build something simple and yet somehow better than what I could purchase, to understand both the electronics and the animal behavior, and in this manner pave the way for more complex future inventions.

My first creation in this respect is the Mythos Enterteinment System 1 (MES-1).  It consists of a laser pointer controlled by a servomotor. An infrared sensor detects nearby movement (e.g., a cat) and an Arduino orchestrates the whole device. The infrared sensor is particularly important: there are laser-based cat toys around, but as far as I know none that can detect the cat; hence, MES-1 has a capability beyond commercial devices, which was one of my design goals.

Simple as this setup is, to make it work soon proved to be harder than I had anticipated, which demanded a number of iterations in the controlling software. A simple electronics project thus became the humble scientific investigation I wished for. Roughly, I had to go through the following four experiments in order to build a working system.

Cats are natural hunters.

Experiment 1

The first software I wrote would: move the laser to random points within the servomotor’s reach (almost always far from each other); as fast as possible; whenever the IR sensor fired.

Experimental hypothesis: I expected Mythos to jump like mad between these points, thereby having great and energetic fun.

Experimental result: Instead, she completely ignored the laser.

Conclusion: Either discontiguous movement, high or constant speed made the toy not fun at all.

Experiment 2

I suspected that the main culprit for the previous failure was the discontiguous laser movement. So I changed the software to pick contiguous points.

Experimental hypothesis:  Smooth, contiguous, laser movement will be enough to elicit Mythos’ hunting behavior.

Experimental result: She notices the laser, but does not chase it.

Conclusion: Contiguous movement seems to help, but in itself is not enough to elicit hunting behavior. And why should it? It is boring as hell.

 

Experiment 3

By then I felt very close to the solution. Perhaps all I needed was to add some randomization to the movement, while still keeping its contiguity. So I programmed the laser to randomly change its direction (i.e., from left to right and vice-versa) and speed.

Experimental hypothesis: Random, but still contiguous, movement will finally elicit Mythos’ hunting behavior.

Experimental result: She notices the laser, but again does not chase it. Indeed, she seems to have some trouble tracking it.

Conclusion: The randomization process induced an excessive speed. Change is good, but must be moderate.

Experiment 4

Finally,while still keeping all other improvements I: reduced the maximum speed the laser could move; and introduced some more generous and random pauses, to allow Mythos some time to focus on the target and prepare an attack.

Experimental hypothesis: Random contiguous movement, including some pauses, bounded by a certain upper velocity, will elicit Mythos’ hunting behavior.

Experimental result: She notices the laser and hunts it! For a few minutes, then she loses interest.

Conclusion: MES-1 works, though for short sessions of fun. This is such a milestone that the toy is now actually called MES-1.1. Mythos now has an annoying friend who, when she gets close, sometimes light her way.

 

There are other details about the final software that can be seen directly in the source program at the end of this text.

What can we learn from this

Mythos is having fun with the simple toy I made her, but I guess I’m the most amused one. A number of lessons can be learned from this exercise in cat entertainment. The most obvious are perhaps those related to cat behavior itself:

  • There is a very specific class of movements that elicits hunting behavior.
  • This class of movements can be decomposed into various aspects, each of which contributes in a different manner to the overall appeal.
  • Although the present class of movement is entertaining, one can expect other relevant components to be found in order to generate even more amusing movements.

Needless to say, these “discoveries” are not really scientific, as they relied on only one cat, in a controlled but still loose environment, with only a rough methodology in place and of vague reproducibility. Proper experimentation would be needed to make these observations really scientific. Nevertheless, what is in fact scientific is the higher-order process that induced all of this. Things that work are the final products of a scientific endeavor, which are often seen as science itself — and MES-1.1 does work. But science is more than that; a lucky idiot is not a scientist. Just like cats, what makes a scientist is not really the final kill, but the curiosity and methodology to get there. Under this light, I think the main lesson that can be taken from this is that it is possible, instructive and fun to incorporate scientific methodology and technology in everyday life. For computer scientists like myself, who normally rely only on software to express themselves, the interesting thing is really how easy it is, these days, to develop electronic devices to extend this vision to the physical environment.

Where to go from here

The Mythos Entertainment System 1.1 can be easily improved in many ways and this is also one of its strength in relation to present commercial offerings. With only a few program lines I can get a better product, whereas if I buy a black box I’m stuck with that, even if I happen to imagine ways to improve it. For example, some of my current ideas for improvements include the following:

  • Add different types of movement patterns and change between them through a Finite State Machine. Currently, state information is limited to a few simple variables that are updated by a single movement function.
  • Add some kind of Reinforcement Learning algorithm so that the toy can learn the cat’s preferences (e.g., of speed).
  • With a extra servomotor, I could also add a new movement axis, hence covering the whole floor.

Moreover, and most important, once I master the basic electronics and animal behavior, I can try bolder things. That’s why the System is numbered — I hope to build MES-2, MES-3, etc. For instance, I could build mobile robots for Mythos to chase around the house and also learn from that. I could build sophisticated experimentation systems to understand and control cat behavior more fully. I could, perhaps, eventually do the same with human behavior. The point is that creativity is self-reinforcing and continually builds the foundations for better things.

Tools for the creative imagination are of a very special kind, they are all ultimately toys, and appeal to the best of us. There are companies, many traditional and also newcomers, who get that. Technology, both in hardware and software, increasingly allow organizations to provide ever more powerful such tools. Indeed, more than ever, it is now a matter of mindset, not of resources. I try to keep mine sharp and I hope everyone else who can also actually does the same.

Specifications and source program

I did not produce schematic diagrams, but I can point out to the main electronic components used:

The program itself is quite small and for the purpose of this simple article there’s little point in uploading it to some source control system. Therefore, I merely copy the present version below. You may use this as you wish, but I’d appreciate proper credit through a citation.

/**
 * Mythos Entertainment System 1.1
 * 
 * Copyright (c) 2017 Paulo Salem. All rights reserved.
 */
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <Servo.h>

#define PIR_MOTION_SENSOR 8 //  to receive the signal from the module 
#define LASER  13 //the laser's pin
#define SERVO  9 // servo motor's pin

const unsigned int BAUD_RATE = 19200; // to use the serial monitor

int pauseEvery = 1000; // Pause every step that is a multiple.
int pauseLength = 10000; // in ms


Servo servo;  // create servo object to control a servo

int steps = 0; // movement steps executed so far

int pos = 0;   // variable to store the servo position

int movementDirection = 1; // 1 or -1, where the servo is moving to (left or right).

int movementDetectedCount = 0;


/**
 * Runs once on system startup.
 */
void setup() {

  servo.attach(SERVO);  // attaches the servo on pin 9 to the servo object

  srand(time(NULL));

  Serial.begin(BAUD_RATE);


  pinMode(PIR_MOTION_SENSOR, INPUT); 
  pinMode(LASER,OUTPUT);

  // Put in initial position;
  servo.write(pos);

  blinkLaser(); // Indicates that the system is starting
  turnLaserOff();

}


/**
 * Main system loop. Runs forever.
 */
void loop() {

  if(movementDetectedByPIR()){
    if(((steps + 1) % pauseEvery) == 0){ // + 1 prevents from pausing in step 0
      Serial.println("Long pause started.");
      turnLaserOff();
      // A pause here allows the cat to rest for some time and reduce
      // the chance it gets bored.
      delay(pauseLength);
    }
    else{
      play();
    }
    
  }

  delay(10);
  // Only turn the laser off if there is no more movement detected
  if(!movementDetectedByPIR()){
    turnLaserOff();
  }

  steps = steps + 1;
}


/**
 * Main function to make the system advance one step.
 */
void play(){
  double r = rand1();

  turnLaserOn();

  moveOnce();
}


/**
 * Defines the smalles movement pattern available, which lasts a finite amount of time.
 */
void moveOnce(){
  
  double r1 = rand1();
  double r2 = rand1();
  double r3 = rand1();
  
  int t = 10;
  int pauseT = 2000;
  
  float pauseProb = 0.01;
  float reverseProb = 0.1;
  
  int delta = 5;
  int minPos = 45;
  int maxPos = 90;

  // Should we pause a little?
  if(r1 < pauseProb){
    delay((int) (rand1() * pauseT));
    Serial.println("Paused.");
  }

  // Should movement direction change? 
  if(r2 < reverseProb){
    movementDirection = -1 * movementDirection;
  }

  // Ensure that the position of the laser is within allowed range.
  if(pos > maxPos){
    pos = maxPos;
    movementDirection = -1;
  }
  else if(pos < minPos){
    pos = minPos;
    movementDirection = 1;
  }

  // The movement magnitude varies randomly up to a maximum value.
  // The larger this is, the faster the total laser movement is.
  delta = movementDirection * ((int) (r3 * delta));
  pos = pos + delta;
  
  servo.write(pos);
  delay(t);
}


/** 
 * Detect whether there is movement in the PIR sensor's detecting range.
 *  
 * Returns: true is movement is detected; false otherwise.
 */
boolean movementDetectedByPIR()
{
  int sensorValue = digitalRead(PIR_MOTION_SENSOR);
  if(sensorValue == HIGH)  //if the sensor value is HIGH?
  {
    // Print in the Serial Monitor (Tools > Serial Monitor)
    Serial.print("Movement ");
    Serial.print(movementDetectedCount);                   
    Serial.println(" ");
      
    movementDetectedCount = movementDetectedCount + 1;
    return true;
  }
  else
  {
    return false;
  }
}


void turnLaserOn(){
  digitalWrite(LASER, HIGH);
}


void turnLaserOff(){
  digitalWrite(LASER, LOW);
}


/**
 * Makes the laser blinks briefly.
 */
void blinkLaser(){
  for(int i = 0; i < 10; i++){
    turnLaserOn();
    delay(200);
    turnLaserOff();
    delay(200);
  }
}


/**
 * Returns a random double between 0.0 and 1.0.
 */
double rand1(){
  //rand () returns a pseudo-random integer between 0 and RAND_MAX
  return (double)rand() / (double)RAND_MAX;
}

Suppliers

Non-exhaustive list of suppliers I relied on for this project: