Dogbot – Post 6 – Back on (PID) track

Exactly a year has passed since my last post on the Dogbot. I ended up getting very frustrated with my inability to get sensible odometry out of the Pololu Encoders using the Orangutan SVP auxiliary processor, and needed to put the project aside for a while.

I believe that I spend a good few weeks digging into the code, to see why I wasn’t getting sensible readings from either, or at times both, of the sensors. Then I gave up, and took up an easier challenge being learning PWM control, and started building the Retrograde Clock.

Recently, I picked up the Dogbot again, and determined that I would make it work. I worked out that one of the Encoders was not right, using my excellent new Seeedstudio DSO Nano. So, then I ordered a new Encoder. At the same time I ordered a new chassis for Dogbot, as the old one was damaged by my cleaner, and decided to replace the medium capacity Liquidware Backpack, used for driving the motors, with a high capacity variety.

I took the opportunity to rebuild the dogbot onto the new chassis, and to simplify the system to make it more robust. One construction change was to use the Wall Plugs as a flexible structure, and screw into their ends, rather than using them as a spacer with a bolt through the middle. This allowed me to use the ends of the wall plugs as mounting points, because they could be fastened tight. Previously, because of the angles, they had needed to remain relatively loose.

Dsc04118Dsc04119

I have removed the rear mounted PIR sensor at this stage. It is easy to add again, at the appropriate time.

Dsc04116Dsc04117

Following reconstruction, I found that the Encoders continued to give unusual (wrong) results. Finally, I looked into the details of the encoder outputs again, using the DSO, and realised that their outputs really NEED to be exactly tuned, using the tiny pots, to 50% duty square waves, otherwise the Orangutan SVP cannot get an accurate count. With this fixed, then the Odometry was built up accurately, measuring the count to travel a fixed distance. With this figure, the actual diameter of each wheel can be calculated, and hence the travel required to go in a straight line.

It is important to note, that Dogbot doesn’t go in anything like a straight line, with full power applied to each motor. The friction, and wheel size differ enough to make it curve quickly from the straight and narrow. So PID is absolutely necessary to keep it running straight. With PID implemented properly then, finally, Dogbot runs straight.

These photographs are taken with the display indicating two items. On the top line, the target distance, represented in x and y distance to travel, is noted. Also the deviation from correct heading to target. The instruction is requesting Dogbot to travel 50cm along what it has been told is the x dimension. The instruction is also implying that the Dogbot is initially facing in y direction, and needs to rotate its poise 90deg clockwise to face along x, before it begins its travels.

Dsc04125

The code is set up to all allow specification of an initial poise, and a final poise, as well as x and y distances to travel, for the Transport Task to undertake.

The bottom row of the display shows the distance reading indicated by each of the three sensors across the front of Dogbot. Central indication being the I2C ultrasonic sensor, which is very accurate, but not at all directional. Left being the long range IR sensor, and Right being the medium range IR sensor. These sensors are very directional and can differentiate a thin rod or edge of a hand placed in front of them. Combination of these sensors will enable Dogbot to travel safely in a forward direction.

Not displayed is the output from the I2C thermal sensor. It has been tilted back, so that its vertical array of 8 pixels is looking up from +5deg to +70deg. It can see very small differences in temperature from ambient, which it also reports.

At this stage my work continues to get the Dogbot to consistently travel from one location/poise to another location/poise. Whilst I have the code in a state that it can achieve this, it doesn’t yet do it consistently, because of variables in the drive system that need to be properly tuned. And, I could improve the code a lot too. The code is a bit amateurish.

Notes to photographs

Dsc04122Dsc04121Dsc04124Dsc04123Dsc04127

Liquidware battery packs have a on/charge switch that effectively isolates the battery. This has proven useful, as I can turn the motors off, whilst still programming the Orangutan SVP. Not designed, but in hindsight very useful.

To counter sagging voltages, and noise on the supply lines, I have fitted 1uF Tantalum capacitors on all of the sensors. This helps to ensure that they are getting a good supply when they are firing.

Both Thermal array sensor, and Ultrasonic distance sensor are canted up to get their cone of vision away from the floor. I have left the IR distance sensors facing parallel with the floor, as they don’t get false readings from the floor (assuming it is flat), and I don’t want to miss low objects that might interfere with the Dogbot.

I added the fishing weights to the rear of Dogbot to ensure it had good balance. It has sufficient weight to rear from the batteries to stand up properly, but when braking it is quite top-heavy. So, the low heavy weight at the rear helps to ensure that it doesn’t tip over.

Although there are no other items on the motor circuit, I have added some 1nF bypass capacitors on the motors. Can’t hurt.

It is alive. Here the IR glow from the sensors has been captured by the camera. Perhaps Skynet lives?

Dsc04130

My next steps are to finish the Transport Task so that it can reliably go from point to point. Then, I’ll integrate more information into the Transport task from the accelerometer sensors, to improve directional accuracy. Then to build some mapping code to allow obstacles to be located and avoided.

DogBot – Post 5

So some time has passed and I’ve had some success with different aspects of my robot.

For simplicity, I’m using a test bed based on an Arduino Duemilianova connected to a Nerdkits sourced display. I’ve hooked the display up as if it was a Pololu Orangutan SV-328 and am using Pololu libraries to write to it. Also, I’ve been working on the actual SVP based robot, so both of which are working well.

The processor 328p is used for the Duemilianova and requires the use of the Timer0, which implies no Pololu motor library code is possible without conflicts. However this is not an issue, as the Duemilianova doesn’t have motor drives anyway. The actual DogBot has the 1284p which is used in the SVP and uses Timer3, which has no limitations on any known libraries to my knowledge.

The freeRTOS code is posted on the Pololu Forum, mostly just back-up as the application code is very immature.

At  this stage I’ve got all of the I2C bus based sensors working, based on code developed by Fleury. So, I can read the thermal sensor for its 8 pixels, and equally importantly, I can read the SRT10 Ultrasonic Sensor for distance in cm. One issue with the ultrasonic sensor is that its field of vision is so great that it basically detects anything “in front” of it. Good to not run into things, but pretty useless as a fine directional capability. It seems lucky that the Sharp IR distance sensors are very directional, and sufficiently accurate as a complement. The analog sensor readings are working well too, though I still have to create a ADC to cm regression.

From the point of view of sensing, it looks like the Sharp IR sensors will be the reference. With the SRT10 sonar being most relevant to create a “zone of safety” where I can be assured that the nearest object in a cone of 120deg is measured, but can’t be sure exactly which direction the object is. On the thermal side, I will get a vector (direction and temperature) from the sensing location, but no distance. But, that I knew and expected.

Putting some effort into designing the motor control, or Transport Task, has taken up my thoughts recently. I don’t want to link the odometry available from the quadrature encoders back into the mapping or routing task. Similarly, I don’t want to link the intertial navigation available from yaw and linear acceleration sensors into the motor task.

I think the transport task should simply take a vector,  relative to the the current pose of the robot, and execute these translation commands subject to feedback from odometry, leaving the inertial navigation to another task.

This fits well into the design of the hardware, as odometry can can be queried from the Pololu SVP ancillary processor, without blocking, and the motor PWM drivers can be also managed without blocking other tasks. This creates a self contained task that does not need to share resources with other tasks.

However, the inertial sensors are analogue readings and the ADC will need to be shared with the Sharp IR distances sensors. Creating the need for a semaphore, and blocking based on the availability of the ADC.

Because of the battery issues described in Post 4, I’ve had to remove the servo neck of the DogBot. Therefore, I will implement the option for motion to be along circular paths, as well as along a straight line. Motion along a straight line, with stationary rotations to create the correct pose prior to departure, are the best paths to arrive at the destination with the lowest risk and shortest path. However, with a fixed sensor head, straight lines don’t fill the map with information as they leave the sensors always pointing in the same direction.

If the DogBot proceeds from A to B via a circular route (if this is requested by the mapping or logistics task), then the sensors will be pointed at all directions from +90 to -90 degrees along the path to the destination. Allowing the travel time to be used effectively for data acquisition.

If I’m feeling smart, then I can create any number of route subdivisions, and force DogBot to describe a path of smooth semicircles to the destination, gathering sensor data along the route.

The inertial sensors can be run in a parallel task (using the ADC along with the Sharp IR sensors), with the odometry (from the ancillary processor) to cross check that the expected distances and directions are traveled. Whilst I think the odometry is more likely to be accurate, the map will be updated constantly so some inaccuracy should be expected and tolerated by the code.

My next step is to design this transport task. This task should take distance, bearing and path description (straight line, circle, sinusoidal, etc) and carry it out to the best of its ability (odometry PID data only). I expect resolving this effort will take the next few weeks, and perhaps longer.

Later work is to develop the logistics and routing task that will issue the navigation requests to the transport task.

Continued with Post 6 (one year later).

Dogbot – Post 4 – Hardware & freeRTOS Complete

Ok so some time later, I’ve finished building up the hardware.

It is basically a 4 level stack, with the two Li batteries on the bottom, followed by a proto board which carries the acceleration sensors, and distributes power and signal lines.

The top level is the Pololu SVP and its daughter display card (level 5).

25742_419162736067_610931067_5621385_2222535_n
25742_419162646067_610931067_5621384_4844593_n
25742_419162756067_610931067_5621386_5021337_n
25742_419162776067_610931067_5621388_4697390_n
25742_419162806067_610931067_5621389_6666628_n
25742_419162876067_610931067_5621390_4382446_n

What issues are there?

Well electrically none. All the signals are working perfectly, as demonstrated by the Pololu Analogue and Digital code, together with their motor and servo code. All the hardware seems to be functioning perfectly.

But, there are some problems.

The Li battery packs are incapable of providing enough current. I should have done a power budget before building. Everything works pretty well, although there is some voltage droop to 4.5V, until I turn on the neck servo. Then Vcc drops to 3.5V and the DogBot dies.

So the choices are to remove the servo, and program the scanning function using the body, or build a new boost power supply. At this stage I’m tending to think it would be better to just remove the neck servo, and use the chassis for scanning.

Also finished is the freeRTOS port, using Timer3 from the Atmel MegaAT1284, which is not found on other devices of this type. This allows me to have no conflicts with previously written code (using Timer0, Timer1, or Timer2). However, I will still need to go through all libraries to ensure that they don’t cause problems by being interrupted by the RTOS.

So now onto some heavy system design to work out exactly how to implement the mapping and searching functions, and how to drive in a straight line.

Wifi Dogbot – Post 3 – Pin Outs

Changed the processor to Pololu Orangutan SVP

*** PIN OUTS DEFINED

For the Orangutan SVP from http://www.pololu.com

Port Pin Orangutan (Alternate Functions) Function Notes

  • PA0 (ADC0) IR Analogue Distance Sensor GP2Y0A02YK0F (20cm-150cm) to ~2.8V – ORANGE
  • PA1 (ADC1) IR Analogue Distance Sensor GP2Y0A21YK0F (10-80cm) to ~2.8V – WHITE
  • PA2 (ADC2) LISY GIRO Z Axis Analogue Sensor to 3.3V – PURPLE
  • PA3 (ADC3) MMA7260QT Three Axis Accelerometer – X Axis Analogue to 3.3V – YELLOW
  • PA4 (ADC4) MMA7260QT Three Axis Accelerometer – Y Axis Analogue to 3.3V – BROWN
  • PA5 (ADC5) MMA7260QT Three Axis Accelerometer – Z Axis Analogue to 3.3V – GREEN
  • PA6 (ADC6) Motor1 Current sense – WHITE
  • PA7 (ADC7) Motor2 Current sense – WHITE
  • PB0 (T0) LCD control line RS Timer/Counter 0
  • PB1 (T1, CLKO) LCD control line R/W
  • PB2 (AIN0, INT2) LCD control line E
  • PB3 (AIN1, OC0A) Timer0 PWM output A? PIR (Digital LOW) – YELLOW (& RED & GREY)
  • PB4 (SPI_SS, OC0B *) Timer0 PWM output B
  • PB5 (SPI_MOSI) auxiliary processor control
  • PB6 (SPI_MISO) auxiliary processor control
  • PB7 (SPI_SCK)? auxiliary processor control
  • PC0 (I2C_SCL) Ultrasonic Ranger SRF10 Addr 0xE0 & Thermopile Addr 0xD2 – BROWN
  • PC1 (I2C_SDA) Ultrasonic Ranger SRF10 Addr 0xE0 & Thermopile Addr 0xD2 – ORANGE
  • PC2 LCD data line DB4 – user pushbutton (pressing pulls low)
  • PC3 LCD data line DB5 – user pushbutton (pressing pulls low)
  • PC4 LCD data line DB6 – green user LED (high turns LED on)
  • PC5 LCD data line DB7 – user pushbutton (pressing pulls low)
  • PC6 Motor2 direction control line – LEFT MOTOR
  • PC7 Motor1 direction control line – RIGHT MOTOR
  • PD0 (USART0_RXD0)
  • PD1 (USART0_TXD0) digital I/O red user LED (low turns LED on)
  • PD2 (USART1_RXD1, INT0)
  • PD3 (USART1_TXD1, INT1)
  • PD4 (OC1B) Timer1 PWM output B – Buzzer
  • PD5 (OC1A) Timer1 PWM output A – I/O servo SPWM? – Neck Servo
  • PD6 (OC2B) Timer2 PWM output B – Motor2 speed control line
  • PD7 (OC2A) Timer2 PWM output A – Motor1 speed control line
  • AREF VCC 3.3V Battery Supply

IN PHYSICAL ORDER

TOP RIGHT TO LEFT

  • PD5 (OC1A) Timer1 PWM output A – I/O servo SPWM – Neck Servo
  • Quadrature Sensor D – YELLOW (LEFT 2nd)
  • Quadrature Sensor C – WHITE (LEFT 1st)
  • Quadrature Sensor B – BLUE (RIGHT 2nd)
  • Quadrature Sensor A – BROWN (RIGHT 1st)
  • GND

BOTTOM RIGHT TO LEFT

  • VIN
  • GND
  • M1 OUT B – PURPLE (RIGHT)
  • M1 OUT A – GREY (RIGHT)
  • M2 OUT B – ORANGE (LEFT)
  • M2 OUT A – GREEN (LEFT)=
  • PD3 (USART1_TXD1, INT1)
  • PD2 (USART1_RXD1, INT0)
  • PD1 (USART0_TXD0) digital I/O red user LED (low turns LED on) blank
  • PD0 (USART0_RXD0) blank – reserved
  • PC1 (I2C_SDA) Ultrasonic Ranger SRF10 Addr 0xE0 & Thermopile Addr 0xD2 – ORANGE
  • PC0 (I2C_SCL) Ultrasonic Ranger SRF10 Addr 0xE0 & Thermopile Addr 0xD2 – BROWN
  • PB4 (SPI_SS, OC0B *) Timer0 PWM output B
  • PB3 (AIN1, OC0A)???? Timer0 PWM output A PIR (Digital LOW) – YELLOW (& RED & GREY)
  • PA0 (ADC0) IR Analogue Distance Sensor GP2Y0A02YK0F (20cm-150cm) to ~2.8V – ORANGE
  • PA1 (ADC1) IR Analogue Distance Sensor GP2Y0A21YK0F (10-80cm) to ~2.8V – WHITE
  • PA2 (ADC2) LISY GIRO Z Axis Analogue Sensor to 3.3V – PURPLE
  • PA3 (ADC3) MMA7260QT Three Axis Accelerometer – X Axis Analogue Sensor to 3.3V – YELLOW
  • PA4 (ADC4) MMA7260QT Three Axis Accelerometer – Y Axis Analogue Sensor to 3.3V – BROWN
  • PA5 (ADC5) MMA7260QT Three Axis Accelerometer – Z Axis Analogue Sensor to 3.3V – GREEN
  • PA6 (ADC6) Motor1 Current sense – WHITE – RIGHT MOTOR
  • PA7 (ADC7) Motor2 Current sense – WHITE – LEFT MOTOR
  • AREF VCC 3.3V Battery Supply (to centre board) – BLUE