In the first part of this project series the rover had four wheels, looking good and was roving the room like a boss. It efficiently was avoiding obstacles, except with one problem: the back wheels drag while turning left and right. This causes the bot to drift on the side rather than turn in an angle freely. So, I decided to remove the back wheels and that big hideous box it was caring turning the rover in to a simple platform differential drive bot.
I think it still looks good and also has now 360 degree freedom of rotation.I will keep improving the design but the first CAD design version is linked below.
PID controlThe PID control solution comes to my mind as soon as I observe the bot drifts in a curve path. The motors on both wheels are the same! Infact they both are 6V, 1600 RPM. They draw the same current and have the same torque however; in reality the friction on both wheels is not the same and can not be the same. For this reason the robot drives in a curve path not in a perfect straight line. The bot has to respect physics.
The simple solution for this problem is to get a speed reading of both wheels and whenever a difference in speed is occurring in some time interval then control the speed of the wheels to be the same by adjusting it over time ( integral value ). In short PID ( proportional Integral derivative ) control.
This is the PID control snippet part from the code and I believe this is the easiest and simplest implementation.
First read angle values using the two wheel encoders of the motors. I used the AS5600 magnetic encoder and fitted them in the wheel stabilizers which I designed and 3D printed them from PCBWay for this purpose. PCBWay is the sponsor of 3D printing the wheel stabilizers and encoder cases for this project. Their service is awesome and I am definitely will be using their pcb service for my future projects.
The encoders are connected to the TCA9548A I2C multiplexer because the encoders have the same I2C bus address and they conflict if they are on the same I2C bus (pin 21 and 22). Then get the difference of the two readings as an "Error". An overall values of this error over time is the Integral. Which has to be between some -Max_INTEGRAL and + MAX_INTEGRAL to avoid clamping and I experimented with different values of MAX_INTEGRAL values as it is just a constant.I found MAX_INTEGRAL to be 50 as it is just optimal for my design. Then the derivative is the difference of errors overtime. Output = KP * error + KI * integral + KD * derivative; is the key variable to set the motor speed values over time. It can also be set two a constant MAX_OUTPUT = 50 also to avoid clamping. Finally the robot roves in a straight line as long as it doesn't encounter obstacles.
1. Set Up
Install the required libraries:
Wire.h for I2C communication. AS5600.h library for the AS5600 encoder (you may need to install it via the Arduino Library Manager or download it from a GitHub repository).
2. Wiring
Connect the TCA9548A to the ESP32:SDA β SDA
(ESP32, GPIO 21)SCL β SCL (ESP32, GPIO 22)VCC β 3.3V (ESP32)GND β GND (ESP32)
SDA β SDA (TCA9548A)SCL β SCL (TCA9548A)VCC β 3.3V (TCA9548A)GND β GND3
3. Code
You can check out my implementation of PID down in the attachment section.
Odometry- Left encoder is on channel 0, and right encoder is on channel 1 of the TCA9548A multiplexer.
- The code reads the raw angle from the AS5600 encoders for both wheels and calculates the corresponding distance traveled based on the wheel's radius.
- Odometry is calculated as the distance traveled by the wheel, using the formula
Distance = (Angle / 360) * Wheel Circumference
. - To get wheel circumference = 2*pi*r. r=20/2=10
Comments