Reader small image

You're reading from  Learn Robotics Programming - Second Edition

Product typeBook
Published inFeb 2021
PublisherPackt
ISBN-139781839218804
Edition2nd Edition
Concepts
Right arrow
Author (1)
Danny Staple
Danny Staple
author image
Danny Staple

Danny Staple builds robots and gadgets as a hobbyist, makes videos about his work with robots, and attends community events such as PiWars and Arduino Day. He has been a professional Python programmer, later moving into DevOps, since 2009, and a software engineer since 2000. He has worked with embedded systems, including embedded Linux systems, throughout the majority of his career. He has been a mentor at a local CoderDojo, where he taught how to code with Python. He has run Lego Robotics clubs with Mindstorms. He has also developed Bounce!, a visual programming language targeted at teaching code using the NodeMCU IoT platform. The robots he has built with his children include TankBot, SkittleBot (now the Pi Wars robot), ArmBot, and SpiderBot.
Read more about Danny Staple

Right arrow

Chapter 11: Programming Encoders with Python

It is useful in robotics to sense the movements of motor shafts and wheels. We drove a robot along a path back in Chapter 7, Drive and Turn – Moving Motors with Python, but it's unlikely that it has stayed on course. Detecting this and traveling a specific distance is useful in creating behaviors. This chapter investigates the choice made by the sensor, as well as how to program the robot to move in a straight line and for a particular distance. We then look at how to make a specific turn. Please note that this chapter does contain math. But don't worry, you'll follow along easily.

In this chapter, you will learn about the following topics:

  • Measuring the distance traveled with encoders
  • Attaching encoders to the robot
  • Detecting the distance traveled in Python
  • Driving in a straight line
  • Driving a specific distance
  • Making a specific turn

Technical requirements

Before we get started, make sure you have the following parts:

  • The Raspberry Pi robot and the code from the previous chapter: https://github.com/PacktPublishing/Learn-Robotics-Programming-Second-Edition/tree/master/chapter10.
  • Two slotted speed sensor encoders. Search for slotted speed sensor, Arduino speed sensor, LM393 speed sensor, or the Photo Interrupter sensor module. Include the term 3.3 V to ensure its compatible. See the The encoders we are using section for images of these.
  • Long male-to-female jumper cables.
  • A ruler to measure the wheels' size on your robot – or better yet, calipers, if you can use them.

The code for this chapter is available on GitHub: https://github.com/PacktPublishing/Learn-Robotics-Programming-Second-Edition/tree/master/chapter11.

Check out the following video to see the Code in Action: https://bit.ly/2XDFae0

Measuring the distance traveled with encoders

Encoders are sensors that change value based on the movement of a part. They detect where the shaft is or how many times an axle has turned. These can be rotating or sensing along a straight-line track.

Sensing how far something has traveled is also known as odometry, and the sensors can also be called tachometers, or tachos for short. The sensors suggested in the Technical requirements section may also show up as Arduino tacho in searches.

Where machines use encoders

Our robots use electronic sensors. Cars and large commercial vehicles use electronic or mechanical sensors for speedometers and tachos.

Printers and scanners combine encoders with DC motors as an alternative to stepper motors. Sensing how much of an arc the robot has turned through is an essential component of servomechanisms, which we saw in Chapter 10, Using Python to Control Servo Motors. High-end audio or electrical test/measurement systems use these in control...

Attaching encoders to the robot

Our robot is now getting quite busy, and our Raspberry Pi is above the encoder's slots. Due to the slots being under the Raspberry Pi, we should wire them in a little before returning the Raspberry Pi. After bolting in the Raspberry Pi, we wire the encoders to its GPIO, as well as the power and ground.

Figure 11.5 shows what the robot block diagram looks like after attaching the encoders:

Figure 11.5 – Robot block diagram with encoders

This block diagram adds a left and right encoder, each with an arrow for the information flow connecting them to the Raspberry Pi. The highlighted elements are the new ones.

Before we start changing the robot and making it harder to see, we need to know the number of slots in the encoder wheel for later:

Figure 11.6 – Encoder wheel

My encoder wheels, shown in Figure 11.6, ended up having 20 slots. Ensure you use the number of spaces your...

Detecting the distance traveled in Python

Using encoder sensor devices requires us to count pulses. In this section, we will create code to turn on the motors and count pulses for a while. The code validates that the sensors are connected correctly. We then take this code and make it part of the robot class as a behavior.

Introducing logging

So far in our Python code, we have been using print to output information to see what our robot is doing. This works, but prints can become overwhelming if we print everything we might want to inspect. Logging allows us to still display information, but we can control how much. By importing the logging module, we can take advantage of this.

First, there are logging levels, with debug, info, warning, and error. While fixing problems or initially developing, debug is useful – it can show everything – while info is used to show a little less than that. The warning and error levels are reserved only for those kinds of problems...

Driving in a straight line

By now, you have seen differences in the outputs – that is, a veer. In only 400 mm, my left side is around 20 mm behind the right, an error that is climbing. Depending on your motors, your robot may have some veer too. It is rare for a robot to have driven perfectly straight. We use the sensors to correct this.

Tip

This behavior works better on wooden flooring or MDF boards, and poorly on carpet.

This correction is still dead reckoning; slipping on surfaces or incorrect measurements can still set this off course. How can we use motors and encoders to correct our course and drive in a straight line?

Correcting veer with a PID

A behavior to self-correct steering and drive in a straight line needs to vary motor speeds until the wheels have turned the same amount. If the wheels turn the same amount soon enough, then they will account for major course deviations.

Our robot will use the encoder sensor to measure how much each wheel has...

Driving a specific distance

For driving a specific distance, we use the PI controller again and incorporate the distance measurements into our encoder object. We calculate how many ticks we want the left wheel to have turned for a given distance, and then use this instead of a timeout component.

Refactoring unit conversions into the EncoderCounter class

We want the conversions for our encoders in the EncoderCounter class to use them in these behaviors. Refactoring is the process of moving code or improving code while retaining its functionality. In this case, converting distances is one of the purposes of using encoders, so it makes sense to move this code in there:

  1. Open up your encoder_counter.py class. First, we need the math import:
    from gpiozero import DigitalInputDevice
    import math
    ...
  2. At the top of the class, add ticks_to_mm_const as a class variable (not an instance variable) to use it without any instances of the class. Set this to none initially so that we...

Making a specific turn

The next task we can use our encoders for is to make a specific turn. When turning a robot, each wheel is going through an arc. Figure 11.13 illustrates this:

Figure 11.13 – Illustrating wheel movement when turning through an arc

The inner wheel drives a shorter distance than the outer wheel, and from the basics of differential steering, this is how we make the turn. To make an exact turn, we need to calculate these two distances or the ratio between them. Figure 11.14 shows how the wheels and the turn relate to each other:

Figure 11.14 – Relating wheels to turn radiuses

If we consider the turn radius as setting where the middle of the robot is, an inner wheel's turn radius is the difference between the turn radius and half the distance between the wheels:

The outer wheel's turn radius is the turn radius added to half the distance:

We convert our angle to turn into...

Summary

In this chapter, we saw how to incorporate wheel encoder sensors into our robot and used them to determine how far each wheel has turned. We saw how to use this to get the robot onto a straighter path using a reduced PID controller and then used this to drive a specific distance. We then took the calculations further to calculate turning a corner in terms of wheel movements and driving the robot in a square.

A PID controller can be used in many situations where you need to apply a difference between a measurement and expectation, and you have seen how to combine this with sensors. You could use the same system to control a heating element connected to a thermal sensor. You could also use encoders to move robots with some precision, where the restricted range of motion used in servo motors does not make sense.

In the next couple of chapters, we will explore giving our robot even more interactive and intelligent behaviors, with chapters on visual processing using a Raspberry...

Exercises

  1. Try experimenting with turning on different logging levels and differently named loggers, tuning how much output a robot behavior creates.
  2. For the PID behaviors, tune the PIDs, try high values for the proportional or the integral, and observe how this makes the robot behave. Could you combine this with graphing in matplotlib to observe the PID behavior?
  3. There are a few ways that the drive distance code could be improved. Applying a PID controller to the distance moved by the primary could make it close in more precisely on the exact distance to travel. Detecting no movement in either encoder could be used to make the code stop after a timeout so that it doesn't drive off without stopping. Try this out.
  4. You could now use this code to make further geometric shapes or to follow paths without a line. Try adding high-level left turn/right turn 90-degree functions as building blocks for right-angled path construction, then use this to make paths.
  5. Consider...

Further reading

Please refer to the following for more information:

  • PID control is a deep subject. It is a key area in self-balancing robots, drones, and other autonomous control systems. Here is a great video series so that you can explore these further:

    YouTube: Brian Douglas – PID Control – A brief introduction: https://www.youtube.com/watch?v=UR0hOmjaHp0

  • I've greatly simplified some of the corner-turning algorithms. A very in-depth article on how this was used for a competition-winning LEGO Mindstorms robot holds a more detailed method:

    GW Lucas – Using a PID-based Technique For Competitive Odometry and Dead-Reckoning: http://www.seattlerobotics.org/encoder/200108/using_a_pid.html

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Learn Robotics Programming - Second Edition
Published in: Feb 2021Publisher: PacktISBN-13: 9781839218804
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at ₹800/month. Cancel anytime

Author (1)

author image
Danny Staple

Danny Staple builds robots and gadgets as a hobbyist, makes videos about his work with robots, and attends community events such as PiWars and Arduino Day. He has been a professional Python programmer, later moving into DevOps, since 2009, and a software engineer since 2000. He has worked with embedded systems, including embedded Linux systems, throughout the majority of his career. He has been a mentor at a local CoderDojo, where he taught how to code with Python. He has run Lego Robotics clubs with Mindstorms. He has also developed Bounce!, a visual programming language targeted at teaching code using the NodeMCU IoT platform. The robots he has built with his children include TankBot, SkittleBot (now the Pi Wars robot), ArmBot, and SpiderBot.
Read more about Danny Staple