|
@@ -32,7 +32,8 @@ class BaseController:
|
|
|
self.isBalance = balance_mode
|
|
|
self.cmd_topic = cmd_topic
|
|
|
self.PID_rate = 100 #下位机中pid固定频率100hz
|
|
|
-
|
|
|
+ self.target_speed = 0
|
|
|
+
|
|
|
self.odom_name = rospy.get_param("~odom_name", "odom")
|
|
|
self.debugPID = rospy.get_param('/dynamic_tutorials/debugPID', False)
|
|
|
|
|
@@ -146,26 +147,30 @@ class BaseController:
|
|
|
self.arduino.i2c_update_pid(self.AWheel_Kp, self.AWheel_Kd, self.AWheel_Ki, self.AWheel_Ko,
|
|
|
self.BWheel_Kp, self.BWheel_Kd, self.BWheel_Ki, self.BWheel_Ko,)
|
|
|
|
|
|
+ def pwm_ctrl(self, pwmA, pwmB):
|
|
|
+ if pwmA > 255:
|
|
|
+ pwmA = 255
|
|
|
+ elif pwmA < -255:
|
|
|
+ pwmA = -255
|
|
|
+
|
|
|
+ if pwmB > 255:
|
|
|
+ pwmB = 255
|
|
|
+ elif pwmB < -255:
|
|
|
+ pwmB = -255
|
|
|
+
|
|
|
+ return int(pwmA), int(pwmB)
|
|
|
+
|
|
|
#底盘运动控制的主循环,执行频率由arduino_node中的频率决定,默认50hz
|
|
|
def poll(self):
|
|
|
#发送调试pid参数的数据
|
|
|
self.send_debug_pid()
|
|
|
|
|
|
- #是否开启平衡车模式,计算控制周期内控制电机的pwm值
|
|
|
- if self.isBalance:
|
|
|
- pwm = self.balanceControl.keepBalance()
|
|
|
- if self.use_serial:
|
|
|
- self.arduino.pwm_drive(-pwm, pwm)
|
|
|
- else:
|
|
|
- self.arduino.i2c_pwm_drive(-pwm, pwm)
|
|
|
-
|
|
|
#读取编码器计数值,用于计算里程计信息
|
|
|
try:
|
|
|
if self.use_serial:
|
|
|
aWheel_enc, bWheel_enc = self.arduino.get_encoder_counts()
|
|
|
else:
|
|
|
aWheel_enc, bWheel_enc = self.arduino.i2c_get_encoder_counts()
|
|
|
- rospy.loginfo("get encoder counts: "+str(self.arduino.i2c_get_encoder_counts()))
|
|
|
except:
|
|
|
try:
|
|
|
#rospy.logwarn("Failed to get encoder counts, try again. ")
|
|
@@ -176,16 +181,51 @@ class BaseController:
|
|
|
except:
|
|
|
rospy.logerr("Encoder exception count !")
|
|
|
return
|
|
|
+ #rospy.loginfo("Encoder A:B=" + str(aWheel_enc) + ":" + str(bWheel_enc))
|
|
|
+
|
|
|
+ #计算编码器计数差值,当前值减去上次的计数值
|
|
|
+ encoder_diff_A = aWheel_enc - self.enc_A
|
|
|
+ encoder_diff_B = bWheel_enc - self.enc_B
|
|
|
|
|
|
#当读取到最新的编码器计数为0,说明下位机已经将计数清零,那上位机保存的上一次编码器计数也得清零
|
|
|
- if aWheel_enc == 0:
|
|
|
+ if aWheel_enc == 0 and bWheel_enc == 0:
|
|
|
self.enc_A = 0
|
|
|
- if bWheel_enc == 0:
|
|
|
self.enc_B = 0
|
|
|
+ if self.isBalance:
|
|
|
+ self.balanceControl.encoder_integral = 0
|
|
|
+ self.balanceControl.encoder_lowout = 0
|
|
|
+
|
|
|
+ #是否开启平衡车模式,在控制周期内计算控制电机的pwm值
|
|
|
+ if self.isBalance:
|
|
|
+ #计算小车当前的倾角,用于直立环和判断小车是否倒下
|
|
|
+ pitch_err = self.balanceControl.pitchData - self.balanceControl.middle_val
|
|
|
+
|
|
|
+ #启动直立环控制,PD控制器,控制pitch角度和角速度
|
|
|
+ stand_pwm = self.balanceControl.keepBalance(pitch_err)
|
|
|
+
|
|
|
+ #启动速度环控制,PI控制器
|
|
|
+ #speed_pwm = self.balanceControl.keepVelocity(encoder_diff_A, encoder_diff_B, self.target_speed)
|
|
|
+ speed_pwm = 0
|
|
|
+
|
|
|
+ #启动转向环控制
|
|
|
+ turn_pwm = 0
|
|
|
+
|
|
|
+ #计算最终发送给电机的pwm
|
|
|
+ pwm_A_tmp = -(stand_pwm + speed_pwm - turn_pwm)
|
|
|
+ pwm_B_tmp = stand_pwm + speed_pwm + turn_pwm
|
|
|
+
|
|
|
+ #将计算得到的pwm值进行限幅,最大pwm值为255,保持正负号
|
|
|
+ pwm_A, pwm_B = self.pwm_ctrl(pwm_A_tmp, pwm_B_tmp)
|
|
|
+ pwm_A, pwm_B = self.balanceControl.checkIfDown(pitch_err, pwm_A, pwm_B)
|
|
|
+ #rospy.loginfo("pwm_A:pwm_B= " + str(pwm_A) + " : " + str(pwm_B))
|
|
|
+ if self.use_serial:
|
|
|
+ self.arduino.pwm_drive(pwm_A, pwm_B)
|
|
|
+ else:
|
|
|
+ self.arduino.i2c_pwm_drive(pwm_A, pwm_B)
|
|
|
|
|
|
#根据编码器两次反馈的差值来计算车轮移动的距离
|
|
|
- dist_A = (aWheel_enc - self.enc_A)/self.ticks_per_meter
|
|
|
- dist_B = (bWheel_enc - self.enc_B)/self.ticks_per_meter
|
|
|
+ dist_A = encoder_diff_A/self.ticks_per_meter
|
|
|
+ dist_B = encoder_diff_B/self.ticks_per_meter
|
|
|
|
|
|
#保存当前编码器计数值,用于下次计算
|
|
|
self.enc_A = aWheel_enc
|