Experiments with new all-in-one motor/motor controller/encoder

DF Robot has an interesting new robotics motor ($19), which has both the motor controller and the encoder integrated into the body. That means that you can drive it straight from an Arduino, with no separate motor controller required. That’s pretty cool and leads the way to very simple rover setups.

The motor is 12v (good choice for a 3-cell, 11.1v lipo battery), geared to max 159 rpm. It’s smaller than the usual robot motors, but has enough power for a small rover.

Because it’s so well integrated with controller and encoder, it’s a good way to demonstrate proper PID motor control. So here’s a demo! The code is here:

Connect it to an Arduino like this (the wire colors will probably be different; pay them no mind. Just keep the red and black right and connect the others in the following order). Important: you must also connect the Arduino ground to the 12v power supply ground as shown):

Full details are in the DF Robot wiki

Now try it with a PID controller, which will maintain a desired RPM within a reasonable range (80-140 rpm). Here’s some Arduino code that will do that.

Try playing around with the Kp (proportional), Ki (integral) and Kd (derivative) terms in this code and see what happens when you enter a different speed (80, 100, 120, etc). With the stock settings below, the Ki term will slowly build up so the RPMs approach the desired speed. A higher Kp term will speed up that convergence, but too high will overshoot. Here’s a short video that gives the basics, but the key points is that it uses feedback.

You want the speed of the motor to be a certain value, but just commanding it to go to a certain power doesn’t mean that it will get to exactly the desired speed (because of variation in battery voltage, etc). So rather than just sending a command and hoping for the best, you measure the actual speed the motor is turning with the encoder. Then just keep changing the motor control inputs until the motor speed output is close to the desired one — that’s what a PID controller does. All the various settings (P. I. D.) are just to tune it so it does that well.

// Make sure you've added the official Arduino PID library to your libraries
 // https://playground.arduino.cc/Code/PIDLibrary/
 include 
 int i = 0;
 int rpm;
 unsigned long time = 0;
 bool direction = HIGH;
 int speed;
 double Setpoint, Input, Output;  // Setpoint is going to be the desired speed. Input will be encoder reading. Output will be motor command
 double Kp = 0.5; 
 double Ki = 3;
 double Kd = 0;
 //Specify the links and initial tuning parameters
 PID myPID(&Input, &Output, &Setpoint,Kp,Ki,Kd, REVERSE);
 void setup() {
   Serial.begin(115200);
   pinMode(10, OUTPUT); //PWM PIN 10  with PWM wire
   pinMode(11, OUTPUT);//direction control PIN 11 with direction wire
   digitalWrite(10, direction);
   Setpoint = 100;
   Input = 100;
   myPID.SetMode(AUTOMATIC);
 } 
 void loop() {
   if (Serial.available())  {
     speed = Serial.parseInt();
     speed = 255 - speed;
     delay(200); 
   }
   for(int j = 0;j<8;j++)  {     i += pulseIn(9, HIGH, 500000);         //SIGNAL OUTPUT PIN 9 with  white line,cycle = 2i,1s = 1000000us,Signal cycle pulse number:272   }   i = i >> 3;
   rpm = 111111 / i;   //speed   r/min  (601000000/(4562i))
   i = 0;
 //  Serial.print(rpm);                      
 //  Serial.println("  r/min");
 Setpoint = 255-speed;
   Input = rpm;
   myPID.Compute();                       // calculate the right motor control to make rpm equal desired speed
   if (Output > 220) {Output = 220;}
   if (Output < 20) {Output = 20;}
   Serial.print("Setpoint, Input, Output: ");
   Serial.print(Setpoint);
   Serial.print("  ");
   Serial.print(Input);
   Serial.print("  ");
   Serial.println(Output);
   analogWrite(11, Output);
 }

If you enter a desired RPM between 80 and 130 in the Arduino Serial Terminal it will try to hit that number. Output should look something like this (“Setpoint” is PID-talk for “desired speed”. “Input” is the reported speed from the motor encoder. “Output” is the motor control signal [0-255] that the code sends the motor):

Official Oakland Race Rules (2019 edition)

Now that the DIY Robocars quarterly races in Oakland have gotten big and the cars fast, it’s time to evolve the rules to reflect our learnings over the past two years.

As of the Sept 21 2019 race, these are the new rules:

There are two tracks, one for beginners and a main one for returning racers:

  • There are 12″ orange cones on the inside of every curve, as shown above.
  • There will be one “obstacle cone” placed at a random location (changed with every race) inside the track.
  • The Beginners Track has the same shape, but is about 25% smaller

If this is your first race or your car’s first race, you must start on the Beginners Track. There will be one judge on that track to schedule official runs. If you can successfully complete a lap in under 40 seconds, you may advance to the Main Track and place your team name on the lineup board (example from a recent race shown below).

Main Track Rules:

Cars:

  • Cars must start with a single binary interaction. This could be a button on the car, on a controller, a key on a keyboard or equivalent. No other intervention can happen until after the race is over; otherwise the car gets a “did not finish” (DNF). An emergency stop button is recommended but not required. Deadman’s switch is also acceptable where button is pushed and held for the duration of the race.
  • There are no rules governing where the computing needs to take place.  Cars may have onboard computing, trackside computing or leverage remote or cloud resources.  
  • GPS and other similar positioning systems are not allowed except for specified outdoor races. 
  • The desire is that this is an open source league and that all designs are put on github and are readily copyable after the conclusion of every race.  If you are prevented from open-sourcing designs or prefer not to, there is no obligation to do so.

There are two categories of racers: Stock and Unlimited

1) Stock:

  • This includes all the standard platforms: DonkeyCar, JetRacer, DeepRacer as well as any custom vehicles that satisfy the below criteria
  • Cars are 1/16th scale or smaller: No more than a 7.5″ (190mm) wheelbase, axle to axle.
  • Cost no more than $400 all told (car, computer, sensors, etc)
  • Batteries must be firmly attached with velcro or other straps so they can’t come loose during the race

2) Unlimited:

  • This is for cars larger and/or more expensive than Stock
  • Cars may be up to two feet long and may weigh up to 10lbs
  • No limit on cost (although we do encourage DIY economics — if you’ve spent $10,000 on a Lidar sensor, this may not be the right event for you. Not only is it out of reach for others to follow, but in the obligatory Demolition Derby at the end it may very well get damaged)
  • Batteries must be firmly attached with velcro or other straps so they can’t come loose during the race

Races:

  • There are three heats, followed by a “ladder” race-off of the top six cars, paired by closest times, ending with a final race between the top two cars for the winning trophy (not actually a trophy!).
  • All races will be “wheel-to-wheel” with two cars on the track at the same time
  • Every car will have at least three opportunities to race. Only those in the top six will move on to the ladder.
  • The first heat pairings are random, within the class they have entered. After that, the second and third heat pairings are based on matching closest times within their class in the first heat.
  • Racers may choose to agree on track starting position (inside or outside lane). If they do not agree, the judge will flip a coin to decide.
  • The final race is an all-cars Demolition Derby. If you brought a car, even if it didn’t qualify for the Main Track or even if it doesn’t even work autonomously, you will race. There will be crashes. It will be fun. It’s the best 30 seconds of mayhem of the day.

Scoring:

  • Each heat is three laps. Both the first lap and the three-lap times will be recorded for each car, but only the first-lap time will determine ranking for the next heat (or ladder position)
  • Passing any “curve cone” on the inside is immediate disqualification for that heat
  • There is no penalty for going outside the white lines, as long as you don’t violate the cone rule above
  • The random “obstacle cone” may be passed on either side. Hitting the obstacle cone imposes a two-second penalty
  • Touching any other cone is a one-second penalty

Adding challenges to DIY Robocars tracks

Now that our computer and software platforms have improved to the point that we’re reaching the maximum physical speed of cars on regular “kidney-shaped” track without resorting to crazy tires and motors, it’s time to slow things by adding more challenge on the CV/AI side.

There are three standard ways to do this:

1) Always race with at least one other car (“wheel-to-wheel” racing). These “moving obstacles” introduce both randomness as well as the need for smart race tactics to win. Those include:

  • Spotting other cars
  • Deciding to pass on the inside or outside
  • Picking the right time to pass (straightaway, before a curve, after a curve)
  • Using AprilTags or other standard computer-readable markers on the back of each car to make them easier to identify

2: Place a cone or other obstacle in the track at some random location before each race. This introduces the following challenges:

  • It breaks naive “cone trackers” that assume that cones are stationary and always at the outside of the track
  • Requires car to differentiate between “outside” cones (which mark the outside of the curves and must always be passed inside and not touched) and “inside” cones (which can be passed on either side)
  • Requires cars to do more than just track the road lines

3: Static obstacles, such as gates, ramps or simulated pedestrians (like the above, from the Sparkfun AVC 2018). This can introduce a number of unique challenges and fun scoring opportunities:

  • Having to differentiate by kind of obstacle, such as “pass to right of blue cone but to left of red cone”, or “some blue ramps add points if jumped, but others have spikes and will stop your car”.
  • Offer extra points (or subtracted seconds) if the car successfully passes through a hoop or between two markers in tight bottleneck
  • More advanced path-finding and decision-making, such as “stop for two seconds if a stop sign is detected” or “stop for detected pedestrians but just steer away from other obstacles”

Starting with the September 21 race in Oakland we’ll do at least #1 and #2; #3 may come later.