|  |  |  | @ -4,10 +4,12 @@ from common.realtime import DT_CTRL | 
			
		
	
		
			
				
					|  |  |  |  | from selfdrive.car.body import bodycan | 
			
		
	
		
			
				
					|  |  |  |  | from opendbc.can.packer import CANPacker | 
			
		
	
		
			
				
					|  |  |  |  | from selfdrive.car.body.values import SPEED_FROM_RPM | 
			
		
	
		
			
				
					|  |  |  |  | from selfdrive.controls.lib.pid import PIDController | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | MAX_TORQUE = 500 | 
			
		
	
		
			
				
					|  |  |  |  | MAX_TORQUE_RATE = 50 | 
			
		
	
		
			
				
					|  |  |  |  | MAX_ANGLE_ERROR = 7 | 
			
		
	
		
			
				
					|  |  |  |  | MAX_ANGLE_ERROR = np.radians(7) | 
			
		
	
		
			
				
					|  |  |  |  | MAX_POS_INTEGRATOR = 0.2   # meters | 
			
		
	
		
			
				
					|  |  |  |  | MAX_TURN_INTEGRATOR = 0.1  # meters | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -17,11 +19,10 @@ class CarController(): | 
			
		
	
		
			
				
					|  |  |  |  |     self.frame = 0 | 
			
		
	
		
			
				
					|  |  |  |  |     self.packer = CANPacker(dbc_name) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     self.i_speed = 0 | 
			
		
	
		
			
				
					|  |  |  |  |     self.i_speed_diff = 0 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     self.i_balance = 0 | 
			
		
	
		
			
				
					|  |  |  |  |     self.d_balance = 0 | 
			
		
	
		
			
				
					|  |  |  |  |     # Speed, balance and turn PIDs | 
			
		
	
		
			
				
					|  |  |  |  |     self.speed_pid = PIDController(0.115, k_i=0.23, rate=1/DT_CTRL) | 
			
		
	
		
			
				
					|  |  |  |  |     self.balance_pid = PIDController(1300, k_i=0, k_d=280, rate=1/DT_CTRL) | 
			
		
	
		
			
				
					|  |  |  |  |     self.turn_pid = PIDController(110, k_i=11.5, rate=1/DT_CTRL) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     self.torque_r_filtered = 0. | 
			
		
	
		
			
				
					|  |  |  |  |     self.torque_l_filtered = 0. | 
			
		
	
	
		
			
				
					|  |  |  | @ -46,37 +47,23 @@ class CarController(): | 
			
		
	
		
			
				
					|  |  |  |  |       speed_desired = CC.actuators.accel / 5. | 
			
		
	
		
			
				
					|  |  |  |  |       speed_diff_desired = -CC.actuators.steer | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       # Setpoint speed PID | 
			
		
	
		
			
				
					|  |  |  |  |       kp_speed = 0.001 / SPEED_FROM_RPM | 
			
		
	
		
			
				
					|  |  |  |  |       ki_speed = 0.002 / SPEED_FROM_RPM | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       speed_measured = SPEED_FROM_RPM * (CS.out.wheelSpeeds.fl + CS.out.wheelSpeeds.fr) / 2. | 
			
		
	
		
			
				
					|  |  |  |  |       speed_error = speed_desired - speed_measured | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       self.i_speed += speed_error * DT_CTRL | 
			
		
	
		
			
				
					|  |  |  |  |       self.i_speed = np.clip(self.i_speed, -MAX_POS_INTEGRATOR, MAX_POS_INTEGRATOR) | 
			
		
	
		
			
				
					|  |  |  |  |       set_point = kp_speed * speed_error + ki_speed * self.i_speed | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       # Balancing PID | 
			
		
	
		
			
				
					|  |  |  |  |       kp_balance = 1300 | 
			
		
	
		
			
				
					|  |  |  |  |       ki_balance = 0 | 
			
		
	
		
			
				
					|  |  |  |  |       kd_balance = 280 | 
			
		
	
		
			
				
					|  |  |  |  |       freeze_integrator = ((speed_error < 0 and self.speed_pid.error_integral <= -MAX_POS_INTEGRATOR) or | 
			
		
	
		
			
				
					|  |  |  |  |                            (speed_error > 0 and self.speed_pid.error_integral >= MAX_POS_INTEGRATOR)) | 
			
		
	
		
			
				
					|  |  |  |  |       angle_setpoint = self.speed_pid.update(speed_error, freeze_integrator=freeze_integrator) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       # Clip angle error, this is enough to get up from stands | 
			
		
	
		
			
				
					|  |  |  |  |       p_balance = np.clip((-CC.orientationNED[1]) - set_point, np.radians(-MAX_ANGLE_ERROR), np.radians(MAX_ANGLE_ERROR)) | 
			
		
	
		
			
				
					|  |  |  |  |       self.i_balance += CS.out.wheelSpeeds.fl + CS.out.wheelSpeeds.fr | 
			
		
	
		
			
				
					|  |  |  |  |       self.d_balance = np.clip(-CC.angularVelocity[1], -1., 1.) | 
			
		
	
		
			
				
					|  |  |  |  |       torque = int(np.clip((p_balance*kp_balance + self.i_balance*ki_balance + self.d_balance*kd_balance), -1000, 1000)) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       # yaw recovery PID | 
			
		
	
		
			
				
					|  |  |  |  |       kp_turn = 0.95 / SPEED_FROM_RPM | 
			
		
	
		
			
				
					|  |  |  |  |       ki_turn = 0.1 / SPEED_FROM_RPM | 
			
		
	
		
			
				
					|  |  |  |  |       angle_error = np.clip((-CC.orientationNED[1]) - angle_setpoint, -MAX_ANGLE_ERROR, MAX_ANGLE_ERROR) | 
			
		
	
		
			
				
					|  |  |  |  |       angle_error_rate = np.clip(-CC.angularVelocity[1], -1., 1.) | 
			
		
	
		
			
				
					|  |  |  |  |       torque = self.balance_pid.update(angle_error, error_rate=angle_error_rate) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       speed_diff_measured = SPEED_FROM_RPM * (CS.out.wheelSpeeds.fl - CS.out.wheelSpeeds.fr) | 
			
		
	
		
			
				
					|  |  |  |  |       speed_diff_error = speed_diff_measured - speed_diff_desired | 
			
		
	
		
			
				
					|  |  |  |  |       self.i_speed_diff += speed_diff_error * DT_CTRL | 
			
		
	
		
			
				
					|  |  |  |  |       self.i_speed_diff = np.clip(self.i_speed_diff, -MAX_TURN_INTEGRATOR, MAX_TURN_INTEGRATOR) | 
			
		
	
		
			
				
					|  |  |  |  |       torque_diff = int(np.clip(kp_turn * speed_diff_error + ki_turn * self.i_speed_diff, -100, 100)) | 
			
		
	
		
			
				
					|  |  |  |  |       turn_error = speed_diff_measured - speed_diff_desired | 
			
		
	
		
			
				
					|  |  |  |  |       freeze_integrator = ((turn_error < 0 and self.turn_pid.error_integral <= -MAX_POS_INTEGRATOR) or | 
			
		
	
		
			
				
					|  |  |  |  |                            (turn_error > 0 and self.turn_pid.error_integral >= MAX_POS_INTEGRATOR)) | 
			
		
	
		
			
				
					|  |  |  |  |       torque_diff = self.turn_pid.update(turn_error, freeze_integrator=freeze_integrator) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |       # Combine 2 PIDs outputs | 
			
		
	
		
			
				
					|  |  |  |  |       torque_r = torque + torque_diff | 
			
		
	
	
		
			
				
					|  |  |  | 
 |