在AirSim里用Python实现LQR控制:让无人机自动跟踪预设轨迹(附完整代码)
用Python实现AirSim无人机LQR轨迹跟踪从理论到代码落地1. 环境准备与基础概念在开始编写代码之前我们需要先搭建好开发环境并理解几个核心概念。AirSim是微软开源的无人机/车辆仿真平台基于Unreal Engine构建提供了高度逼真的物理模拟和丰富的API接口。而LQRLinear Quadratic Regulator则是一种经典的最优控制算法特别适合像无人机这样的线性系统控制。1.1 安装必要的软件包首先确保你已经安装了以下组件pip install airsim numpy scipy matplotlib对于AirSim本身需要从GitHub克隆并编译git clone https://github.com/microsoft/AirSim.git cd AirSim ./setup.sh ./build.sh提示编译AirSim需要安装Visual StudioWindows或gccLinux并确保系统已安装Unreal Engine。1.2 理解无人机动力学模型无人机在空中的运动可以用以下状态空间方程表示$$ \begin{aligned} \dot{x} Ax Bu \ y Cx Du \end{aligned} $$其中$x$ 是状态向量位置、速度等$u$ 是控制输入电机推力$A$ 是系统矩阵$B$ 是输入矩阵对于简单的二维平面控制我们可以将状态向量定义为x [position_x, position_y, velocity_x, velocity_y]2. LQR控制器设计与实现2.1 LQR算法核心原理LQR通过最小化以下代价函数来找到最优控制律$$ J \int_0^\infty (x^TQx u^TRu)dt $$其中$Q$ 是状态权重矩阵$R$ 是控制输入权重矩阵求解LQR问题最终归结为求解代数Riccati方程from scipy.linalg import solve_continuous_are # 解Riccati方程 P solve_continuous_are(A, B, Q, R) # 计算反馈矩阵K K np.linalg.inv(R) B.T P2.2 Python实现LQR控制器下面是一个完整的LQR控制器类实现import numpy as np from scipy.linalg import solve_continuous_are class LQRController: def __init__(self, A, B, Q, R): self.A A self.B B self.Q Q self.R R self.compute_gain_matrix() def compute_gain_matrix(self): 计算LQR反馈矩阵K P solve_continuous_are(self.A, self.B, self.Q, self.R) self.K np.linalg.inv(self.R) self.B.T P def compute_control(self, x, x_desired): 计算控制输入 error x - x_desired return -self.K error3. AirSim接口与轨迹跟踪3.1 连接AirSim并获取无人机状态首先我们需要建立与AirSim的连接并获取无人机状态import airsim # 连接到AirSim client airsim.MultirotorClient() client.confirmConnection() client.enableApiControl(True) client.armDisarm(True) # 获取无人机状态 def get_drone_state(): state client.getMultirotorState() position state.kinematics_estimated.position velocity state.kinematics_estimated.linear_velocity return np.array([ position.x_val, position.y_val, velocity.x_val, velocity.y_val ])3.2 轨迹生成与跟踪我们可以定义一个简单的圆形轨迹作为跟踪目标def generate_circular_trajectory(radius10, speed2, dt0.05): 生成圆形轨迹 t 0 while True: x radius * np.cos(speed * t) y radius * np.sin(speed * t) vx -radius * speed * np.sin(speed * t) vy radius * speed * np.cos(speed * t) yield np.array([x, y, vx, vy]) t dt4. 完整控制循环实现4.1 主控制循环将前面所有组件整合成一个完整的控制循环def main(): # 初始化 client.takeoffAsync().join() # 定义系统矩阵 (简化模型) A np.array([ [0, 0, 1, 0], [0, 0, 0, 1], [0, 0, 0, 0], [0, 0, 0, 0] ]) B np.array([ [0, 0], [0, 0], [1, 0], [0, 1] ]) # 权重矩阵 Q np.diag([10, 10, 1, 1]) # 更重视位置误差 R np.diag([0.1, 0.1]) # 控制输入权重 # 创建控制器 controller LQRController(A, B, Q, R) # 轨迹生成器 trajectory generate_circular_trajectory() try: while True: # 获取当前状态和期望状态 x get_drone_state() x_desired next(trajectory) # 计算控制输入 u controller.compute_control(x, x_desired) # 转换为AirSim控制指令 client.moveByVelocityAsync( u[0], u[1], 0, 0.1 # 只控制xy平面 ) time.sleep(0.05) except KeyboardInterrupt: client.armDisarm(False) client.reset()4.2 调试与优化技巧在实际应用中你可能需要关注以下几点系统辨识真实的无人机动力学可能更复杂需要通过实验或系统辨识来获取更准确的A、B矩阵权重调整Q和R矩阵的选择对控制效果影响很大需要根据实际需求调整状态估计如果使用真实无人机可能需要卡尔曼滤波来处理传感器噪声抗饱和处理当控制输入达到物理限制时需要特殊处理避免积分饱和5. 高级话题与扩展5.1 三维空间扩展将我们的二维控制器扩展到三维空间# 3D状态向量 x_3d [pos_x, pos_y, pos_z, vel_x, vel_y, vel_z] # 3D系统矩阵 A_3d np.block([ [np.zeros((3,3)), np.eye(3)], [np.zeros((3,3)), np.zeros((3,3))] ]) B_3d np.block([ [np.zeros((3,3))], [np.eye(3)] ])5.2 非线性系统处理对于非线性系统可以考虑使用LQR的变种增益调度在不同工作点设计多个LQR控制器SDREState-Dependent Riccati EquationMPCModel Predictive Control5.3 实际部署注意事项当准备将代码部署到真实无人机时通信延迟网络延迟会影响控制性能状态估计需要融合IMU、GPS等多种传感器数据安全机制必须实现紧急停止和故障保护计算效率嵌入式设备上的计算资源有限在调试过程中我发现最关键的参数是Q矩阵中对位置误差的权重。过小的权重会导致无人机跟踪滞后而过大的权重则可能引起振荡。一个实用的技巧是从较小的权重开始逐步增加直到获得满意的响应速度。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2472330.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!