Arduino - Wall Follower With PID Controller Fault

Hi all,

I am working on a wall follower program with Arduino. Below video shows PID (Proportional-Integral-Derivative controller) version of 'wall follower'. It follows the sofa (fabric), the wall (brick) and the cupboard (wood) as shown in the video.

Wall Follower With PID Controller

The wall follower code is given below.

Wall Follower Header File
Wall Follower Main File

It utilizes the below electronics components for this purpose:

  1. Ardino microcontroller
  2. DC motors - 2
  3. L293D motor driver shield
  4. Two Ultrasonic sensors

One ultrasonic sensor is mounted on the left side of the car and another mounted on the front of the car. PID algorithm is applied to the Left Ultrasonic sensor. Front sensor navigates to the right (sharp turn) when there is an object in front of the car.

Now, the questions are, why the robot collide with the cupboard at the end? Could you please guide me about debugging the issue, that will help the robot move ahead from the cupboard? Why the robot is unable to detect the turn at the cupboard (when it is able to detect other left/right turns)?

Regards,
Android Explorer.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :slight_smile:

Hi,

Thanks for your suggestions. I have tried to incorporate them at my best below. I have attached the hand-drawn circuit diagram for the Wall Follower (PID Controller) with this reply.

As well as I am putting the relevant code in the code tags for the wall follower below.

Below is the code for Wall Follower main program.

SR04 wf_sr04_left = SR04(LEFT_US_SENSOR_ECHO,LEFT_US_SENSOR_TRIG);
SR04 wf_sr04_front = SR04(FRONT_US_SENSOR_ECHO,FRONT_US_SENSOR_TRIG);

int WF_Left=0;
int WF_Front=0;

int WF_Left_Status=0;
int WF_Front_Status=0;

float WF_Error = 0;
float WF_Kp = 11;
float WF_Ki = 0.003;
float WF_Kd = 0.2; 
int WF_LeftTurnSpeed = 0;
int WF_RightTurnSpeed = 0;
int WF_Correction = 0;
float WF_Integral = 0;
float WF_Derivative = 0;
float WF_LastError = 0;



void WALL_FOLLOWER (IRrecv irrecv) {

     while (!IS_REMOTE_BUTTON_STOP(GET_REMOTE_CODE(irrecv))) {

      WF_Front_Status = WF_GET_FRONT_US_STATUS();
      WF_Left_Status = WF_GET_LEFT_US_STATUS();

      if(WF_Front_Status == NO_OBSTACLE && WF_Left_Status == OBSTACLE) {
        WF_CONTINUE_WALL();
      } else if(WF_Front_Status == NO_OBSTACLE && WF_Left_Status == NO_OBSTACLE) {
        WF_LEFT();
      } else {
        WF_RIGHT();
      }

      }

  WF_STOP();
}


void WF_INITIALIZE_WALL(void) {
WF_Integral = 0;
WF_Derivative = 0;
WF_LastError = 0;

}

void WF_CONTINUE_WALL (void)
{
    WF_Left = wf_sr04_left.Distance();
    WF_Error = WF_Left - WF_DISTANCE;
    WF_Integral = (WF_Error + WF_Integral);
    WF_Derivative = (WF_Error - WF_LastError);

    WF_Correction = WF_Kp * WF_Error + WF_Kd * WF_Derivative + WF_Ki * WF_Integral;

    WF_LeftTurnSpeed = 128 - WF_Correction;
    WF_RightTurnSpeed = 128 + WF_Correction;

    motor3.setSpeed(WF_LeftTurnSpeed);
    motor3.run(FORWARD);
    motor4.setSpeed(WF_RightTurnSpeed);
    motor4.run(FORWARD);

    WF_LastError = WF_Error;
}

int WF_GET_LEFT_US_STATUS(void) {
     if(wf_sr04_left.Distance() < WF_DISTANCE)
      return OBSTACLE;
     else
      return NO_OBSTACLE;
}

int WF_GET_FRONT_US_STATUS(void) {
     if(wf_sr04_front.Distance() < WF_FRONT_DISTANCE)
      return OBSTACLE;
     else
      return NO_OBSTACLE;
}


void WF_RIGHT (void)
{
   //Serial.println("Right ..");
   motor3.setSpeed(WF_SPEED);
   motor3.run(FORWARD);
   motor4.setSpeed(WF_NO_SPEED);
   motor4.run(FORWARD);
}

void WF_LEFT (void)
{
   //Serial.println("Left ..");
   motor3.setSpeed(WF_NO_SPEED);
   motor3.run(FORWARD);
   motor4.setSpeed(WF_SPEED);
   motor4.run(FORWARD);
}

void WF_STOP (void)
{
  //Serial.println("Stop..");
   motor3.setSpeed(WF_NO_SPEED);
   motor4.setSpeed(WF_NO_SPEED);
}

Below is the code for wall follower header file.

#include "SR04.h"

#define LEFT_US_SENSOR_TRIG 16
#define LEFT_US_SENSOR_ECHO 15
#define FRONT_US_SENSOR_TRIG 18
#define FRONT_US_SENSOR_ECHO 17

#define NO_OBSTACLE 0
#define OBSTACLE 1

#define WF_SPEED 180
#define WF_NO_SPEED 0

#define WF_DISTANCE 10
#define WF_FRONT_DISTANCE 16

void WF_LEFT (void);
void WF_RIGHT (void);
void WF_CONTINUE_WALL (void);
void WF_INITIALIZE_WALL(void);
int WF_GET_LEFT_US_STATUS(void);
int WF_GET_FRONT_US_STATUS(void);
void WF_STOP (void);
void WALL_FOLLOWER (IRrecv irrecv);

extern SR04 wf_sr04_left;
extern SR04 wf_sr04_front;

I have written the description of the problem (along with the video) in the original post.
Please let me know if more details are needed OR all the details should be put in one post for clarity.

Arduino Explorer.

This project is "almost" complete now. The reason for saying "almost" is because, it is very sensitive to voltage. And do not behave consistently. I need to design a voltage regulator to maintain a constant voltage to microcontroller and sensors.

I needed to make changes to the PID values, to make it work (as it exists now, in the below video).

Please take a look at the latest video and the latest code.

Wall Follower Patrolling Over The Room - Video

The latest code which made it work is below.