Difference between revisions of "Phidgets PID"
(→References =) |
(→PID Calibration) |
||
(16 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
= References = | = References = | ||
− | + | * [http://wiki.ros.org/pid ROS PID] | |
+ | * [http://docs.ros.org/jade/api/control_toolbox/html/classcontrol__toolbox_1_1Pid.html ROS PID API] | ||
− | + | = ROS PID Code = | |
− | + | ||
− | + | This is in <tt>motor_control_pc_nav.cpp</tt>. | |
− | * | + | Includes and globals |
+ | #include <control_toolbox/pid.h> | ||
+ | |||
+ | // Motor pid control | ||
+ | double k_p_ = 1.0; | ||
+ | double k_i_ = 0.0; | ||
+ | double k_d_ = 0.0; | ||
+ | |||
+ | // motor characteristics | ||
+ | control_toolbox::Pid pid_motor0_; | ||
+ | control_toolbox::Pid pid_motor1_; | ||
+ | ros::Time last_time_; | ||
+ | ros::Time beginning_time_; | ||
+ | |||
+ | // Phidget motor control settings | ||
+ | double power_wheel0_; | ||
+ | double power_wheel1_; | ||
+ | |||
+ | PID intialization | ||
+ | void initMotorPower () | ||
+ | { | ||
+ | // pid related | ||
+ | pid_motor0_.initPid(k_p_, k_i_, k_d_, 0.0, -0.0); | ||
+ | pid_motor1_.initPid(k_p_, k_i_, k_d_, 0.0, -0.0); | ||
+ | last_time_ = ros::Time::now(); | ||
+ | |||
+ | // motor power related | ||
+ | power_wheel0_ = 0; | ||
+ | power_wheel1_ = 0; | ||
+ | } | ||
+ | |||
+ | In the odometry callyback function | ||
+ | void setMotorPower () | ||
+ | { | ||
+ | ... | ||
+ | |||
+ | // Compute motor control power | ||
+ | // Motor power computed between -100 and 100 percent of full power | ||
+ | ros::Time time = ros::Time::now(); | ||
+ | power_wheel0_ = power_wheel0_ + pid_motor0_.computeCommand( | ||
+ | wheel0_target_speed - wheel0_speed, time - last_time_); | ||
+ | if (power_wheel0_ > 100) power_wheel0_ = 100; | ||
+ | if (power_wheel0_ < -100) power_wheel0_ = -100; | ||
+ | power_wheel1_ = power_wheel1_ + pid_motor1_.computeCommand( | ||
+ | wheel1_target_speed - wheel1_speed, time - last_time_); | ||
+ | if (power_wheel1_ > 100) power_wheel1_ = 100; | ||
+ | if (power_wheel1_ < -100) power_wheel1_ = -100; | ||
+ | last_time_ = time; | ||
+ | |||
+ | // *** apply power to the motors *** | ||
+ | CPhidgetMotorControl_setVelocity (phid_, 0, power_wheel0_); | ||
+ | CPhidgetMotorControl_setVelocity (phid_, 1, -power_wheel1_); | ||
+ | |||
+ | ... | ||
+ | } | ||
+ | |||
+ | = PID Calibration = | ||
+ | |||
+ | * [http://wiki.ros.org/differential_drive/tutorials/setup ROS PID Tuning] | ||
+ | ** A quick and dirty tuning experiment | ||
+ | *** Target linear speed 0.2 m/sec, angular 0.2 radians/sec | ||
+ | *** Definite oscillation with P = 60. | ||
+ | *** Set P to 1/2 of that or 30 | ||
+ | *** Tried a I of 60 | ||
+ | ** See [[Phidgets PID Tuning]] for details | ||
+ | |||
+ | * [https://en.wikipedia.org/wiki/PID_controller#Manual_tuning Manual PID Tuning from Wikipedia] | ||
+ | |||
+ | "If the system must remain online, one tuning method is to first set K_i and K_d values to zero. Increase the K_p until the output of the loop oscillates, then the K_p should be set to approximately half of that value for a "quarter amplitude decay" type response. Then increase K_i until any offset is corrected in sufficient time for the process. However, too much K_i will cause instability. Finally, increase K_d, if required, until the loop is acceptably quick to reach its reference after a load disturbance. However, too much K_d will cause excessive response and overshoot. A fast PID loop tuning usually overshoots slightly to reach the setpoint more quickly; however, some systems cannot accept overshoot, in which case an over-damped closed-loop system is required, which will require a K_p setting significantly less than half that of the K_p setting that was causing oscillation." | ||
+ | |||
+ | == Other PID References == | ||
+ | |||
+ | * [https://en.m.wikipedia.org/wiki/PID_controller PID Controller] Theory from Wikipedia | ||
* [http://www.seattlerobotics.org/encoder/200108/using_a_pid.html Using PID based Techniques For Competitive Odometry and Dead-Reckoning] G.W. Lucas | * [http://www.seattlerobotics.org/encoder/200108/using_a_pid.html Using PID based Techniques For Competitive Odometry and Dead-Reckoning] G.W. Lucas | ||
− |
Latest revision as of 13:10, 20 September 2017
References
ROS PID Code
This is in motor_control_pc_nav.cpp.
Includes and globals
#include <control_toolbox/pid.h> // Motor pid control double k_p_ = 1.0; double k_i_ = 0.0; double k_d_ = 0.0; // motor characteristics control_toolbox::Pid pid_motor0_; control_toolbox::Pid pid_motor1_; ros::Time last_time_; ros::Time beginning_time_; // Phidget motor control settings double power_wheel0_; double power_wheel1_;
PID intialization
void initMotorPower () { // pid related pid_motor0_.initPid(k_p_, k_i_, k_d_, 0.0, -0.0); pid_motor1_.initPid(k_p_, k_i_, k_d_, 0.0, -0.0); last_time_ = ros::Time::now(); // motor power related power_wheel0_ = 0; power_wheel1_ = 0;
}
In the odometry callyback function
void setMotorPower () { ... // Compute motor control power // Motor power computed between -100 and 100 percent of full power ros::Time time = ros::Time::now(); power_wheel0_ = power_wheel0_ + pid_motor0_.computeCommand( wheel0_target_speed - wheel0_speed, time - last_time_); if (power_wheel0_ > 100) power_wheel0_ = 100; if (power_wheel0_ < -100) power_wheel0_ = -100; power_wheel1_ = power_wheel1_ + pid_motor1_.computeCommand( wheel1_target_speed - wheel1_speed, time - last_time_); if (power_wheel1_ > 100) power_wheel1_ = 100; if (power_wheel1_ < -100) power_wheel1_ = -100; last_time_ = time; // *** apply power to the motors *** CPhidgetMotorControl_setVelocity (phid_, 0, power_wheel0_); CPhidgetMotorControl_setVelocity (phid_, 1, -power_wheel1_); ... }
PID Calibration
- ROS PID Tuning
- A quick and dirty tuning experiment
- Target linear speed 0.2 m/sec, angular 0.2 radians/sec
- Definite oscillation with P = 60.
- Set P to 1/2 of that or 30
- Tried a I of 60
- See Phidgets PID Tuning for details
- A quick and dirty tuning experiment
"If the system must remain online, one tuning method is to first set K_i and K_d values to zero. Increase the K_p until the output of the loop oscillates, then the K_p should be set to approximately half of that value for a "quarter amplitude decay" type response. Then increase K_i until any offset is corrected in sufficient time for the process. However, too much K_i will cause instability. Finally, increase K_d, if required, until the loop is acceptably quick to reach its reference after a load disturbance. However, too much K_d will cause excessive response and overshoot. A fast PID loop tuning usually overshoots slightly to reach the setpoint more quickly; however, some systems cannot accept overshoot, in which case an over-damped closed-loop system is required, which will require a K_p setting significantly less than half that of the K_p setting that was causing oscillation."
Other PID References
- PID Controller Theory from Wikipedia
- Using PID based Techniques For Competitive Odometry and Dead-Reckoning G.W. Lucas