Cheap caterpillar robot platform restrained at custom office

I have done >200 China orders (mostly aliexpress.com, sometimes banggood.com) in the last two years, mostly with free shipping. I ordered microcontrollers, motors, electronic components, ... and all (but two) arrived without issues at my home. They contained a stamp "freed from customs clearance" because they were too cheap.

Last week I got mail notification that one of my orders was restrained at Heidelberg custom office. They did not believe the value mentioned on the parcel (8$), and the size of the parcel got their attention. On the phone they explained that often plagiarising products are sent this way from China, and those are prohibited.

They were right with the value, the caterpillar robot platform did cost 22.90$ (only), but that was less than the value where I would have to pay German VAT.

I should bring my bill with details and open the parcel in order to decide how to proceed.

On Friday morning I took train to Heidelberg, presented the detailed bill, opened the parcel, and had to pay nothing, but could just take the parcel home. Reason was it was no plagiarism, and below the VAT threshold, any VAT below 5€ will not be taken. In Germany we have 19% VAT, which means that any product cheaper than 25.31€ or 28.08$ does not need VAT to be paid.

So I went back home with train, adding 14.30$ train tickets to the 22.90$. I have many different robot platforms at home, but this was my first caterpillar one.

A first functional test without microprocessor with 4V turning on same location went well:

Today I did a second "straight" test, again with only 4V of a single 25C LiPo (motors can take 3-9V):

Counting the tiles and single steping youtube video time showed 1.05m/s with only 4V:

$ bc -lq
sqrt(9^2+1.25^2)*0.315/(38/14)
1.05449957813359675047

Hermann.

Hi Hermann,
Very nice but how and why are you using one of MY videos, of MY Pololu tracked bot!!

This one: https://www.youtube.com/edit?video_id=9Ygm0Oxhf8c That used a PIC in the days before I got in to the Arduino...

OK so I can help if you need it, perhaps.
Regards

Mel.

Hi,

I corrected immediately after posting, both links above are correct since then.

I did add a 2nd Lipo and measured straight speed with 7.5V.
Single stepping youtube video shows 9 frames per second.
Here you can see that caterpillar robot does more than 2 tiles in 2 frames.

This shows that robot speed is greater than 2.8m/s or 10km/h:

$ bc -ql
sqrt(2^2+(1/8)^2)*0.315/(2/9)
2.84053171257711009556
sqrt(2^2+(1/8)^2)*0.315/(2/9)*3.6
10.22591416527759634401

The wall crash less than a second later should make me rethink whether to do more of these ...

Hermann.

P.S:
Doing 640x480@90fps slowmo video with Raspberry camera would reveal more details.

OK, I added an Arduino Uno with motorshield v1 to caterpillar robot platform. A first test did work, but the 7.5V from two Lipos in battery compartment got reduced too much (5.19V/5.36V from 7.5V by Arduino Uno and motor shield's L293D motor controller) for good speed.

I added a third Lipo, but battery compartment was already full by the other (bigger) Lipos. So I just piggybacked the 3rd Lipo:

There is still voltage reduction, down from 11.22 to 8.84V/8.70V for one of the motors (forward/backward). Not sure yet why the robot got slower at the end. Voltage dropped from 11.22V to 10.80V.

Hermann.

Yesterday I wanted to follow up on the slowdown at the end of the video.
I replaced the three lipos used with a single 900mAh 3S/11.1V 10.0Wh 25C lipo.

Again, after 20 seconds or so, caterpillars did not want to move.
I noticed that the L293D used for M3 and M4 got very hot.
Measurements showed that while 3S lipo had >12V, the motors got less than 1V at maximum.

So the motorshield v1 seems to be incapable of driving the platform motors, because it can deliver 600mA maximal per motor.

The caterpillar robot platform description does not say much on the motors (Motor model: 260). I found many "260" motor datasheets, and many may be the ones of that platform. A week ago I opened the platform and extracted one of the motors, but there is nothing printed on it that would identify the motor:

But all the different possible motor models have one feature in common, 1A or higher at maximum efficiency.

Will try motor shield v2 next, it has TB6612 MOSFET drivers with 1.2A per channel, and if that does not suffice, try the other 3 or 4 motor controller types I have at home.

Hermann.

P.S:
Good that I have L298N from image with caterpilar robot platform at home:

Its datasheet says that 2A can be delivered for DC operation (absolute maximum ratings).

OK, motorshield v2 with 1.2A per motor was good enough.
Unlike with motor controllers before, this time caterpillar robot did easily start even on carpet.

Here is youtube video of the complete run:

And this is 4 times slowed down animation of lipo loss, which terminated the run:

Now on speed, there are 8 frames per second, and before loosing lipo 3 frames make a complete round.
This is the robot size: 7cm high 15.5cm wide 21cm long.

This is slowest speed for middlepoints of caterpillars first (in m/s and km/h, 4*a(1) is π):

$ bc -ql
0.155*4*a(1)
.48694686130641795195
0.155*4*a(1)/(3/8)
1.29852496348378120520
0.155*4*a(1)/(3/8)*3.6
4.67468986854161233872

And this is fastest speed, eg. at front point of left caterpillar:

sqrt(0.155^2+0.21^2)*4*a(1)
.81997975574047714161
sqrt(0.155^2+0.21^2)*4*a(1)/(3/8)
2.18661268197460571096
sqrt(0.155^2+0.21^2)*4*a(1)/(3/8)*3.6
7.87180565510858055945

OK, time for better mounting of 82g lipo, and then new runs ...

Hermann.

I did fixate the Lipo and did the runs again. Now the robot did loose a caterpillar tread:

I looked into why that happened on every run yesterday, today. And it turned out that the right motor fixing was broken. I did fix that temporarily by inserting a lego brick between motor and upper holes plate.

The small screw you can see above the lego brick was part of lipo fixation.
Here is the video, one pirouette is comprised of roughly 11 full rotations (=> single step video):

The 2s pauses between alternating direction pirouettes are for me, to be able to intervene if things go wrong. Surprisingly, how near the robot stays even after 1min and 8 pirouettes (less than 20cm apart from start, the motors and caterpillar systems must be nearly equal).

Hermann.

I tried to let robot run forward, then backward.Unfortunately the robot does not run straight from start.

Youtube video "No more caterpillar robot runs without sensors ..." says it all, lost motor cable in that run:

Before that run I did record video with old Andoid smartphone, from our living room catwalk 2m above ground. That way the video capture a goode area of floor. Playing video in mplayer it says 15fps, and these are 5 single frame steps from initial frame (top rght), all copied into the first frame image:

These 5 frames allow to compute the speed as 3.3m/s or 11.85km/h (floor tile width is 31.5cm):

$ bc -ql
sqrt((3.25*0.315)^2+(1.25*0.315)^2)/(5/15)
3.29058173048474819373
sqrt((3.25*0.315)^2+(1.25*0.315)^2)/(5/15)*3.6
11.84609422974509349742

So next step is to keep motorshield v2, but switch it to 3.3V logic.
And to exchange Arduino Uno with Arduino Due.
And and use sensors:

Details on the setup were posted here.

Hermann.

In order to allow sideward sensors to see the wall and not the caterpillar tread, the Arduino Due had to be mounted on the upper hole plate. For fixing Due with screws the motor shield had to be removed, and therefore the sensors as well. This photo nicely shows the superglued sensors:

Next the sensors got tested along a test wall, and I did move the robot manually along that "wall" while recording all 3 sensor's data:

The diagram shows that only the front sensor sometimes gives "unexpected" readings (mostly because of 15° sensor angle). Definitely not a single reading is from the real wall (that is more than 2m away initially):

But the two sideward sensor measurements look really smooth, exactly what is needed.
(x-axis is samples taken, y-axis is distance in mm)

Hermann.

I wanted to complete the assembly, but a motor cable broke. There were three cables that were badly soldered, I tried to do better and all cable connections feel firm. Soldering was easier with left motor unmounted and on a higher level. I was not able to remove the right motor, since I resolved the broken motor fixing by superglueing it with robot platform:

This is the end result, motors and sensors connected, the big 3S 11.1V Lipo did fit diagonally:

In previous posting I said "No more caterpillar robot runs without sensors ..." meaning "sensor control". I did another run with sensors mounted, but not used:

What surprised me is the power of caterpillar robot (hear the sound in youtube video) although the sketch max speed is 100 and not 255. The only small departure from ideal programmed movement allowed to capture quite some for and back moves. The whole robot does weigh 587g in total.

Now its definitely time to make use of the sensor readings ...

Hermann.

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
Adafruit_DCMotor *myMotor = AFMS.getMotor(4);
Adafruit_DCMotor *myMotor2 = AFMS.getMotor(3);

void setup() {
  AFMS.begin();  // create with the default frequency 1.6KHz

  myMotor->setSpeed(150);
  myMotor->run(FORWARD);
  myMotor->run(RELEASE);

  myMotor2->setSpeed(150);
  myMotor2->run(FORWARD);
  myMotor2->run(RELEASE);
}

void loop() {
  uint8_t i, m=100;

  myMotor->run(FORWARD);
  myMotor2->run(FORWARD);
  for (i=0; i<m; i++) {
    myMotor->setSpeed(i);  
    myMotor2->setSpeed(i);  
    delay(1);
  }
  delay(500);
  for (i=m; i!=0; i--) {
    myMotor->setSpeed(i);  
    myMotor2->setSpeed(i);  
    delay(1);
  }
  
  delay(200);

  myMotor->run(BACKWARD);
  myMotor2->run(BACKWARD);
  for (i=0; i<m; i++) {
    myMotor->setSpeed(i);  
    myMotor2->setSpeed(i);  
    delay(1);
  }
  delay(500);
  for (i=m; i!=0; i--) {
    myMotor->setSpeed(i);  
    myMotor2->setSpeed(i);  
    delay(1);
  }

//  myMotor->run(RELEASE);
//  myMotor2->run(RELEASE);
  delay(200);
}

Yesterday I learned how to do front ultrasonic range sensor measurements interrupt driven, which allows for some kind of multitasking (wall collision avoidance and at the same time navigation):
http://forum.arduino.cc/index.php?topic=469281.msg3213465#msg3213465

The first experiments with that code into robot driving at full speed look good, but robot did two wall crashes at full speed in between. One of the crashes even broke the ultrasonic range sensors superglue connections. After superglueing again, and resoldering two battery connector cables (that broke during the crashes), all is fine.

First I did "myMotor->run(RELEASE)" to stop, but realized that the robot did slide quite some distance by that method. Then I did "myMotor->setSpeed(0)" instead, which corresponds to a full break. This is a youtube video I made of such full stop runs, and a .gif animation showing the back wheelie at the end:

Hermann.

P.S:
I searched on whether battle tanks show similar full stop behavior, and they do :wink:

P.P.S:
Same caterpillar back wheelie as above, but slowed down by factor of 15:

I did remove (temporarily) the 3 ultrasonic distance sensors for doing some sensorless high speed (PWM=200) U-turn experiments:

  • it was fun
  • I learned quite something
  • I really need to go on with sensors

The high speed (PWM=200) U-turn was done by flipping direction of one motor while keeping speed. This would turn in place for stand still robot. But with high speed the direction flipped motor caterpillar has to brake first. The turn phase delay was slightly too high, so that the robot did more than 180° turn.

In a second run (with same sketch as before) the robot keeps doing pirouettes without stop. Arduino Due does definitely generate the needed PWM signals, but the sketch code is not followed anymore:

What is this state of Arduino Due? Crashed? If so, how get the PWM signals still generated? By timers?

Finally I got this video that I could not have planned for (the 587g robot did backward roll 10cm above ground!):

This animation shows the last 20 frames, slowed down by factor of 4 with backward roll at the end:

After overshooted U-turn, Robot first shooted over laptop power supply, then clashed vertically against plastic box, then kept driving upwards (front 30cm above ground, back 10cm above ground) and finally lost grip to plastic box and did (incomplete) backward roll.

This is the relevant part of the sketch:

...
  myMotor->run(FORWARD);
  myMotor2->run(FORWARD);

  for(i=20; i<m; ++i) {
    myMotor->setSpeed(i);
    myMotor2->setSpeed(i);
    delay(8);
  }
  myMotor->setSpeed(m);
  myMotor2->setSpeed(m);

  myMotor2->run(BACKWARD);
  delay(210);

  myMotor2->run(FORWARD);
  delay(1200);

  myMotor->setSpeed(0);
  myMotor2->setSpeed(0);
...

Hermann.

Currently I am having stability problems with the robot/Due/motor shield, the robot may have crashed too often with high speed into walls or other obstacles. I replaced the Due, and replaced the motor shield, but still only 1 of 6 times the sketch executes at all and completes ... more debugging needed.

What I did before that happened was to get a 90fps slowmo video (640x480 with Raspberry camera) of caterpillar robot high speed (PWM=200) overshooted U-turn. The youtube video shows up 3.6(=90/2) times slowed down, so even if you set youtube player speed factor to 2 that is 1.8 times slower then originally. In case you set youtube player factor to 0.25 you can see the video slowed down by factor of 14.4. That allows you to see how exactly the high speed U-turn by just reversing direction of one motor while keeping the speed (for some time) works -- I love that U-turn:

Here are seconds 11-16 of youtube video (3.06s - 4.44s at original speed) extracted by makeagif.com. The whole U-turn takes 47 frames or 0.52s at original speed (counted by single frame stepping the youtube video, with '.' and ',' keys):

And here is the simple sketch:

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
Adafruit_DCMotor *myMotor = AFMS.getMotor(4);
Adafruit_DCMotor *myMotor2 = AFMS.getMotor(3);

void setup() {
  int i, m=200;
  
  AFMS.begin();

  myMotor->run(FORWARD);
  myMotor2->run(FORWARD);
  
  for(i=20; i<m; ++i) {
    myMotor->setSpeed(i);  
    myMotor2->setSpeed(i); 
    delay(8);
  }
  myMotor->setSpeed(m);  
  myMotor2->setSpeed(m);  

  myMotor2->run(BACKWARD);
  delay(210);

  myMotor2->run(FORWARD);
  delay(600);
  
  myMotor->setSpeed(0);  
  myMotor2->setSpeed(0); 
}

void loop() {
}

Hermann.

P.S:
Positions at start of U-turn, at 90° at 180° and final point of turn before going straight again. Initial speed before starting U-turn is 21cm in 9 frames @90fps, or 2.1m/s:

In order to further debug the stability issues this time I switched the robot platform as well. I used the left of these two Arduebots:

Here is a 90fps slowmo video I did of a U-turn run with Raspberry camera, with PWM=150. No overshooting of U-turn this time, most likely because speed is not high:

Even with PWM=150 the stability issue occurs, and after I increased to PWM=200 nearly every run is a problem and does not end as the sketch requires (crashes into wall, start with some slow speed and then keep that forever, does not react on Due Reset button press, Due power needs to be disconnected).

Summary:
Switching Due, motorshield v2 and robot platform did not remove the stability issues. Issue occur much more often with PWM=200 compared to PWM=150. Good news seems to be that both robot platforms are OK. It seems that motorshield v2 becomes instable with higher motor voltages. I even removed the power jumper with the caterpillar motor shied and powered motors with 3S lipo 12V, and the Due wia USB; even with that setup the instability issues occured. So it seems both motorshield v2 I tested have a problem.

Action:
Replace the motorshield (I like the form factor) by two IRF520 Mosfet motor controllers -- they have no problems and an ATTiny85 can reliably drive 20.6V (5 Lipos):

Hermann.

Instead of IRF520 Mosfet motor controllers I used the prototype shield with TB6612FNG motor controller from the right Arduebot in previous posting photo. Although the motor shield v2 is based on the exact same motor controller, the stability issues are completely gone after getting rid of the motorshield v2! And my shield has two goodies that come in handy: a self-made display comnnector (which I use for a 320x240 TFT display) and a SD card reader from that display that becomes usable for Due data reading and writing. Here is today's "self-reflection" photo of my "Arduecat" (Arduino Due Caterpillar robot), click for details (the image gets read from the SD card):

I did choose "Arduecat" as name after Google search for it resulted in a single hit (example for a Caesar cipher).

Currently there is only one hardware problem, the right side motor does not run for PWM<128, while the left runs for much lower values. I tried some more medium speed U-turn runs, but a delay is not reliable for turning by a fixed degree. So I made use of the ultrasonic distance sideways sensors to make a 180° U-Turn when driving parallel to a wall by turning until both sideways sensors show same distance. This did not work as expected, so next step is to add scrolling text output with measured data on TFT display in order to see latest measurements and get an understanding of what measurements resulted in robot stop.

Hermann.

P.S:
Perhaps Arduecat will run in kitchen arena next, like 10 years ago Asuro robots:

The bigger Asuro robot did make 1.8m/s on the straight parts, Arduecat should be able to do much quicker.

P.P.S:
D14-D21 is not inline with D9-D13 on Arduino Uno proto shield used on top of Due, but superglueing front sideways ultrasonic distance sensor onto back sideways sensor worked:

A lot of "#define"s for naming connections:

#define TFT_RST 40 // uncomment if you have ILI9340
#define TFT_DC 42 // Command/Data for LCD
#define TFT_CS 44 // Chip Select for LCD
#define SD_CS 3 // Chip Select for SD card

#define VCC0 19
#define trigPin0 18
#define echoPin0 17
#define GND0a 16
#define GND0b 15
#define VCC1 9
#define trigPin1 10
#define echoPin1 11
#define GND1a 12
#define GND1b 13
#define VCC2 38
#define trigPin2 36
#define echoPin2 34
#define GND2a 32
#define GND2b 30

#define PWMB 4
#define BIN2 5
#define BIN1 6
#define STBY 7
#define AIN1 24
#define AIN2 26
#define PWMA 28

Today I received another caterpillar robot platform, this time without problems with custom office:

I do want to place a Raspberry Pi Zero with camera onto Arduecat, later for line following, now for evaluation on how 90fps on robot video looks like, whether vibrations in high speed runs are a problem, ... . But the current Arduecat is quite full already (today I added mini digital voltmeter that runs completely independent of Arduecat's Due):

I knew that motorshield v2 had problems, so I tried with an Arduino Uno and a motorshield v1. Because of high speed and trying to avoid any power spike issues, I decided to control the platform with x/y joystick and long cable (self-made, 4×2m copper cable, taped together):

On the plus side, it really works, and controlling the robot is quite intuitive (at least to me) given the sketch I wrote:

#include <AFMotor.h>

AF_DCMotor ml(4); AF_DCMotor mr(3);

int x = 0, y = 0, y0 = 506, x0 = 490, Y, X;

void setup() {
  Serial.begin(57600);

  ml.setSpeed(0);  mr.setSpeed(0);
  ml.run(RELEASE); mr.run(RELEASE);
}

void loop() {
  x = analogRead(A0); y = analogRead(A5);
  
  if (y < y0) {
    Y = map(y0 - y, 0, y0, 0, 255);
    ml.run(BACKWARD); mr.run(BACKWARD);
  } else {
    Y = map(y, y0, 1023, 0, 255);
    ml.run(FORWARD);  mr.run(FORWARD);
  }

  if (x < x0) {
    X = map(x0 - x, 0, x0, Y, 0);
    ml.setSpeed(X); mr.setSpeed(Y);  
  } else {
    X = map(x, x0, 1023, Y, 0);
    ml.setSpeed(Y); mr.setSpeed(X);  
  }

#if 0
  Serial.print("Y = " );   Serial.print(Y);
  Serial.print("\t X = "); Serial.println(X);
#endif

  delay(2); 
}

Here is a youtube video of a demo I did with Android camera lying on catwalk in our living room, 2m above ground:

On the bad side, after some time the robot did not move nice, and later it stopped to move at all. It turned out that two of the three L239D motor controllers of v1 shield get very hot. Definitely too much current.

But after some phase of no activity (just release joystick into center position, the robot stands still without motor movement) all works fine again (the L293Ds have become cold again then)- So for the camera test drives the current solution seems to be good enough.

Hermann.

P.S:
The patform battery box was too small for new 3S 1000mAh Lipo, but unlike Arduecat I did not want to waste much platform space for the Lipo. Therefore I drilled a "small" hole into battery box top and did cut out some of the yellow platform. That allowed to put the 3S Lipo (vertically) into battery box – well, 70% of it :wink:

The robot platform sometime did funny things, here it took (joystick) control away from me :wink:

Next I found out how to mount tilt system with Raspberry camera, and the Raspberry Pi Zero itself on two long spacers, so that the flexible camera cable has pace below Pi Zero to move fore and back. I learned that the Pi Zero could not be powered by Arduino Uno GND/5V – it works for some time, but whenever Arduino Uno makes camera servo move, the Pi Zero did reset. So I did power Pi Zero wth 5V from LM2596:

Experiments revealed that camera inclination of 35° was good to see ground in front from 8cm up to 1m ahead:

I have always done 90fps slowmo videos with 640x480 resolution, because I could. In between I realized that 320x240 @90fps might be sufficient as well, at least the lower right 320x240 photo looks not worse than total 640x480 photo:

For some reason the video taking only works when USB to ethernet adapter was "onboard"?!?

I bought a Pi Zero W when it was first available, and it worked really nice. I killed it after one week, most likely by 5V cable unplanned contact with Zero W pins. I am waiting for my 2nd Pi Zero W to arrive next week -- that way I will definitely not need an onboard ethernet anymore (and streaming video for 1st person view will become possible).

This is first "fast" driving 90fps slowmo video taken by the onboard Raspberry Pi Zero and camera. It is surprisingly "stable", I was not sure what the high speed caterpillar platform movement would do to the video. Remember that the video gets played slowed down by factor 90/25=3.6:

I am not sure whether there was a wall crash at the end of first fast forward phase, or whether robot stopped just before the wall. If, then it was the camera tilt system.

Speeds (determined by counting frames bewteen the tape stripes on ground 50 apart):

  • 1.40m/s from 0-50cm (32 frames)
  • 1.87m/s from 50-100cm (24 frames)
  • 2.14m/s from 100-200cm (2×21 frames)

I use the Pi Zero in "slave" mode, and the Uno signals when a video should be taken. Therefore a 5V/3.3V level shifter was necessary. I do use Servo2 pins for controlling the camera servo. But Servo1 pins (D10/5V/GND)were available. I did solder female headers below the level shifter and was able to just put the level shifter onto Servo1 pins:

Finally I added a soldered LED/1kΩ pair to Pi Zero, that is turned on by Pi while raspivid runs:

I changed the previous sketch for robot platform joystick control only slightly. The triggering is done in "setup()", so that the request for taking a video is done by pressing reset key:

#include <AFMotor.h>
#include <Servo.h> 

Servo myservo;

AF_DCMotor ml(4); AF_DCMotor mr(3);

int x = 0, y = 0, y0 = 506, x0 = 490, Y, X;

void setup() {
  Serial.begin(57600);

  ml.setSpeed(0);  mr.setSpeed(0);
  ml.run(RELEASE); mr.run(RELEASE);
  
  myservo.attach(9);
  myservo.write(60);

  // signal Raspbery Pi zerop to start camera (raspivid ...)
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  delay(2000);
  digitalWrite(10, LOW);
}

void loop() {
  x = analogRead(A0); y = analogRead(A5);
  
  if (y < y0) {
    Y = map(y0 - y, 0, y0, 0, 255);
    ml.run(BACKWARD); mr.run(BACKWARD);
  } else {
    Y = map(y, y0, 1023, 0, 255);
    ml.run(FORWARD);  mr.run(FORWARD);
  }

  if (x < x0) {
    X = map(x0 - x, 0, x0, Y, 0);
    ml.setSpeed(X); mr.setSpeed(Y);  
  } else {
    X = map(x, x0, 1023, Y, 0);
    ml.setSpeed(Y); mr.setSpeed(X);  
  }

#if 0
  Serial.print("Y = " );   Serial.print(Y);
  Serial.print("\t X = "); Serial.println(X);
#endif

  delay(2); 
}

On the Raspberry side this is the "camera_slave" bash script that does what is needed, and it gets started in .bashrc after reboot:

pi@raspberrypi02:~ $ tail -3 .bashrc
# ~/clkl

./camera_slave
pi@raspberrypi02:~ $ cat camera_slave 
#!/bin/bash

while (true)
do
  if ((`gpio read 0`)) 
  then
    while ((`gpio read 0`)) 
    do
      sleep 1
    done

    f=`date +%Y-%m-%d_%X`.h264
    gpio write 11 1
    raspivid -w 640 -h 480 -fps 90 -t 5000 -o "$f"
    gpio write 11 0
  else
    sleep 1
  fi
done
pi@raspberrypi02:~ $

Hermann.

Today I let the robot run on living room floor tiles.
2.36m/s (8.5km/h) onboard video is surprisingly stable on floor tiles.
90fps slowmo video played slowed down by factor of 90/25=3.6:

Speed on the first 10 floor tiles (determined by youtube video single frame counting):

0.315/(20/90)   = 1.42 m/s
0.315/(16/90)   = 1.77 m/s
0.315/(14/90)   = 2.03 m/s
0.315*2/(26/90) = 2.18 m/s
0.315*2/(25/90) = 2.27 m/s
0.315/(12/90)   = 2.36 m/s
0.315/(12/90)   = 2.36 m/s
0.315/(15/90)   = 1.89 m/s

By a previous wall crash the camera tilt system got changed, now camera inclination is 45° (just realized that), and camare cannot see farther than 50cm ahead (instead of 1m ahead before). This is a reason why tilt servo might remain permanently on robot platform: on startup Arduino and Pi Zero can determine the inclination to be used by some sample photos instead of a fixed servo value. That way crashes would not change the camera inclination on startup. Another option would be to move camera back onto robot so far, that a wall crash would hit the front wheels instead of the camera. SInce 35° inclination did not show the 8cm before front wheels this may even positively affect the video.

Hermann.

Outdoor was never an option for my wheel type robots.
Just gave caterpillar robot some outdoor activity.
Worked fine until robot drove too fast for me and I tramped on joystick cable, soldering needed.

This is the first outdoor run 90fps slowmo video, uphill with incline of 5°:

This is downhill, remember that youtube video as well as animated .gif show video slowed down by factor 90/25=3.6:

Maybe (in far future) caterpillar robot will drive autonomously my 900m "around house" track. A 5:19min video of that track can be found here (German language page).

Hermann.