Go to the documentation of this file.00001 import numpy as np, math
00002
00003 import roslib; roslib.load_manifest('hrl_generic_arms')
00004 import rospy
00005 from std_msgs.msg import Float64, Float64MultiArray
00006
00007
00008
00009
00010 class PIDController(object):
00011 def __init__(self, rate=100., k_p=0., k_i=0., k_d=0., i_max=None, feed_forward=0.,
00012 init_integ=0., saturation=None, name=None):
00013 self.y = 0.
00014 self.k_p = k_p
00015 self.k_i = k_i
00016 self.k_d = k_d
00017 self.i_max = i_max
00018 self.feed_forward = feed_forward
00019 self.rate = rate
00020 self.saturation = saturation
00021 self.err_last = None
00022 self.integral = init_integ
00023 self.name = name
00024 if self.name is not None:
00025 self.err_pub = rospy.Publisher("/pid_controller/" + name + "_error", Float64)
00026 self.out_pub = rospy.Publisher("/pid_controller/" + name + "_output", Float64)
00027 self.diag_pub = rospy.Publisher("/pid_controller/" + name + "_diag", Float64MultiArray)
00028
00029
00030
00031 def update_state(self, err):
00032 last_integral = self.integral
00033 self.integral += err / self.rate
00034 if self.i_max is not None:
00035 self.integral = np.clip(self.integral, -self.i_max, self.i_max)
00036 if self.err_last is None:
00037 self.err_last = err
00038 propr = self.k_p * err
00039 integ = self.k_i * self.integral
00040 deriv = self.k_d * (err - self.err_last) * self.rate
00041 feedf = self.feed_forward
00042 raw_y = propr + integ + deriv + feedf
00043 self.err_last = err
00044 if self.saturation is not None:
00045 self.y = np.clip(raw_y, -self.saturation, self.saturation)
00046 if self.y in [-self.saturation, self.saturation]:
00047 self.integral = last_integral
00048 if self.name is not None:
00049 self.err_pub.publish(err)
00050 self.out_pub.publish(self.y)
00051 diag_msg = Float64MultiArray()
00052 diag_msg.data = [self.y, propr, integ, deriv, feedf, raw_y, self.saturation]
00053 self.diag_pub.publish(diag_msg)
00054 return self.y
00055
00056 def reset_controller(self):
00057 self.err_last = None
00058 self.integral = 0