PID Control

Prelab

For sending and receiving data over Bluetooth, I simply used the notification handler used in pervious labs.

Arduino Code

    // Compute error (how far we are from the setpoint)
      float error = setpoint - distance2;
    
      // P-Controller
      float proportional = Kp * error;
    
      // PI-Controller (adds integral term)
      integral += error * (currTime - prevTime)/50;
      float integralTerm = Ki * integral;
    
      // PID-Controller (adds derivative term)
      float derivative = (error - prevError) / (currTime - prevTime);
      float derivativeTerm = Kd * derivative;
    
      // Final PID output
      float output = proportional + integralTerm + derivativeTerm;
      int speed = constrain(abs(output), 0, 255); // Limit PWM values
    
      // Apply scaling factor to the right motor to correct imbalance
      int rightSpeed = speed * rightMotorScale;
      int leftSpeed = speed;  // Left motor remains unchanged
    
      if (distance2 > setpoint) { 
        // Move forward
        analogWrite(MotorPin1, rightSpeed);
        digitalWrite(MotorPin2, LOW);
        analogWrite(MotorPin3, leftSpeed);
        digitalWrite(MotorPin4, LOW);
      } else { 
        // Staggered stop: Right motor stops slightly earlier
        analogWrite(MotorPin1, 0);
        delay(stopDelay);  // Allow right motor to slow first
        analogWrite(MotorPin3, 0);

    

Python Code for Bluetooth Communication

    [INSERT CODE]
    

Lab Tasks

P/I/D Discussion

I chose a PID controller with the following values:

This combination allowed for fast and stable control while avoiding oscillations and overshoot. These values allow for the error to build up making the pwm signal to gradually climb and at some point allowing the robot to move. Since it a slow build the robot's speed will be slow and will only increase to a higher speed if the error build up is large enough. Since the intergral code is contiously adding error without making this term extremely small the output will quickly become an extremely large number capping out the speed when intially turn on. This lead to many instances of overshooting. I did not use a derative term since my code only outputted 0.00 for it. This lead me to believe for my implementaion I did not need it and as seen in a video later that my assupmtion was true.

Range/Sampling Time Discussion

The ToF sensor was set to short range. The PID loop ran at approximately 50 Hz, while the sensor updated at ~10 Hz.

Graphs

Currently I do not have graphs or pictures due to time constraints. I will add them over the weekend.

ToF Sensor Data vs. Time Motor Input vs. Time

Videos and Images

Down below is a video of what I was able to accomplish with a PI controller.

Discussion

The robot successfully stopped at 1 ft from the wall in multiple trials. I will show the extrapolated ToF data later with updated info and analysis. The main challenges were noise in the derivative term and motor deadband, which were addressed by using a scaling/calibration factor.