AI-система управления дроном / БПЛА
RL для дронов решает задачи, где классический PID/MPC недостаточен: агрессивный полёт через узкие проходы, посадка на подвижную платформу, полёт в условиях сильного ветра. Среды симуляции — AirSim, Isaac Gym, Gazebo — позволяют обучить политику миллионам полётов без единой аварии.
Стек управления БПЛА
Autopilot уровень (PX4 / ArduPilot): Низкоуровневое управление моторами @ 400 Hz. Attitude control (pitch/roll/yaw). Sensor fusion: IMU + Barometer + GPS + Optical Flow.
Companion computer: Jetson Orin / Raspberry Pi 5. ROS2. Обработка сенсоров, RL policy inference @ 50–100 Hz. MAVLink коммуникация с PX4.
Perception: Depth camera (Intel RealSense), stereo vision, или LiDAR для obstacle detection. SLAM: ORB-SLAM3, Cartographer.
Задачи для RL
Trajectory tracking с возмущениями: Wind gusts, sensor noise, motor failures → RL агент адаптируется там, где PID теряет устойчивость.
Aggressive maneuvers: Перевороты (flip), полёт на максимальной скорости через ворота (drone racing). Классические контроллеры не справляются при агрессивных манёврах — RL policy обучается напрямую.
Landing на подвижную платформу: Корабль/автомобиль как посадочная платформа. Релятивная навигация через AprilTag или ArUco markers.
Симуляция: AirSim + AirGen
import airsim
import gymnasium as gym
class DroneEnv(gym.Env):
def __init__(self):
self.client = airsim.MultirotorClient()
self.client.confirmConnection()
self.client.enableApiControl(True)
self.client.armDisarm(True)
# наблюдение: pose + velocity + depth image
self.observation_space = spaces.Dict({
'pose': spaces.Box(-np.inf, np.inf, (12,)), # xyz + euler + velocities
'depth': spaces.Box(0, 255, (64, 64, 1), dtype=np.uint8)
})
# действие: velocity commands [vx, vy, vz, yaw_rate]
self.action_space = spaces.Box(
low=np.array([-5, -5, -5, -180]),
high=np.array([5, 5, 5, 180]),
dtype=np.float32
)
def step(self, action):
vx, vy, vz, yaw_rate = action
self.client.moveByVelocityAsync(vx, vy, vz, 0.1,
yaw_mode=airsim.YawMode(True, yaw_rate)).join()
state = self.client.getMultirotorState()
obs = self._extract_obs(state)
reward = self._compute_reward(state)
done = self._check_crash(state) or self._check_goal_reached(state)
return obs, reward, done, False, {}
Domain randomization в AirSim:
# случайный ветер
wind = airsim.Vector3r(
np.random.uniform(-5, 5), # Vx m/s
np.random.uniform(-5, 5), # Vy m/s
0
)
self.client.simSetWind(wind)
# случайные параметры дрона
# motor_thrust_noise, prop_blade_pitch_variation
Policy архитектура
MLP для hover/navigation:
class DronePolicy(nn.Module):
def __init__(self, obs_dim=12, action_dim=4):
super().__init__()
self.net = nn.Sequential(
nn.Linear(obs_dim, 256), nn.ELU(),
nn.Linear(256, 256), nn.ELU(),
nn.Linear(256, 128), nn.ELU(),
)
self.mean = nn.Linear(128, action_dim)
self.log_std = nn.Parameter(torch.zeros(action_dim))
CNN + MLP для vision-based obstacle avoidance: Depth image → CNN encoder → concat с pose → MLP → velocity command.
Recurrent policy (LSTM): Важна при частичной наблюдаемости: ветер не виден напрямую, LSTM запоминает его эффекты.
Reward для навигации
def compute_reward(self, state, target_pos):
drone_pos = np.array([state.kinematics_estimated.position.x_val,
state.kinematics_estimated.position.y_val,
state.kinematics_estimated.position.z_val])
# прогресс к цели
dist_to_goal = np.linalg.norm(drone_pos - target_pos)
reward = -dist_to_goal * 0.1
# достижение цели
if dist_to_goal < 0.5:
reward += 100.0
# штраф за столкновение
collision = self.client.simGetCollisionInfo()
if collision.has_collided:
reward -= 200.0
# энергоэффективность
velocity = state.kinematics_estimated.linear_velocity
speed = np.sqrt(velocity.x_val**2 + velocity.y_val**2 + velocity.z_val**2)
reward -= speed * 0.01 # небольшой штраф за скорость
return reward
Sim-to-Real трансфер
Главная проблема дронов: reality gap. AirSim выглядит реально, но реальный воздух, vibrations, motor delays отличаются.
Методы:
- System Identification: измерение реальных параметров дрона (thrust curves, moment of inertia) → точная симуляция
- Domain Randomization: широкий диапазон физических параметров в симуляции
- Residual Policy Learning: классический контроллер (PID) + RL residual term. RL исправляет ошибки PID, не заменяет его
def get_control_command(self, state, target):
# базовый PID сигнал
pid_cmd = self.pid_controller.compute(state, target)
# RL residual (маленький, не разрушает PID)
rl_residual = self.rl_policy.predict(state) * 0.3 # scaling factor
return pid_cmd + rl_residual
Автономный дрон racing
MultiDrones раздел Flightmare: специализированная среда для дрон-рейсинга. Gate detection + minimum-time trajectory.
Deep Drone Racing (ICRA 2023): тренировка на 100M шагов в симуляции → перенос на реальный гоночный дрон. Скорость прохождения трассы близка к пилотам-чемпионам.
Сроки: 14–28 недель
Hover + navigation в AirSim с sim-to-real на готовой платформе — 10–14 недель. Vision-based obstacle avoidance, aggressive maneuvers, landing на подвижную платформу — 20–28 недель.







