7.1 Quadcopter Asoslari ā Masalalar
Jami: 25 ta | Yechim bilan: ā
Asosiy Masalalar (1-10)ā
Masala 1 āāā
Quadcopter massasi 2 kg. Hovering uchun har bir motorning thrust kuchi?
Yechim
N
N
Masala 2 āāā
Motor: N/(rad/s)². Hovering uchun motor RPM? (m = 2 kg)
Yechim
N
rad/s
RPM
Masala 3 āāā
3S LiPo batareya (11.1V, 5000mAh). Hovering quvvati 150W. Uchish vaqti?
Yechim
Energiya: Wh
Vaqt: h = 22 daqiqa
(Real: 80% efficiency ā ~18 min)
Masala 4 āāā
Roll burchagi 10°. Horizontal tezlanish? (m = 2 kg, hovering thrust)
Yechim
Horizontal kuch: N
Tezlanish: m/s²
Masala 5 āāā
Propeller: diametr 10", pitch 4.5". Static thrust taxmini? (Formula: g)
Yechim
D = 10", pitch = 4.5", RPM = 10000 deb faraz qilsak:
g ā 1.4 kg = 14 N
Masala 6 āāā
Roll moment kerak: Nm. Motor arm L = 0.2 m. Thrust farqi?
Yechim
(2 ta motor har tomonda)
N
Motor 1,4 va 2,3 orasidagi farq.
Masala 7 āāā
Barometer: dengiz sathida Pā = 101325 Pa. 100 m balandlikda bosim?
Yechim
Taxminiy formula: Pa
Pa
(1 hPa ā 8.4 m)
Masala 8 āāā
GPS: 5 Hz update, 1 m accuracy. 10 m/s tezlikda pozitsiya xatosi?
Yechim
Update interval: s
Xato: 1 m + harakat = 1 + 10 Ć 0.2 = 3 m (worst case)
Shuning uchun IMU fusion kerak!
Masala 9 āāā
Accelerometer: 0.5g kuch o'lchadi. Dron qaysi burchakda (hovering)?
Yechim
Hoverda accelerometer faqat g ni o'lchaydi (vertikal).
0.5g o'lchash ā bu egilish burchagi:
Masala 10 āāā
Gyroscope drift: 0.01°/s. 1 daqiqada qancha drift?
Yechim
per minute
10 daqiqada: 6° ā sezilarlı xato!
O'rtacha Masalalar (11-18)ā
Masala 11 āāāā
Attitude controller: Roll error 5°, , . Roll rate 2°/s. PD chiqishi?
Yechim
, (error rate = if trying to reduce)
(Birlik: moment yoki rate command)
Masala 12 āāāā
Mixer: T = 22N, = 0.5 Nm, = 0, = 0.1 Nm. Motor thrustlari?
Yechim
import numpy as np
# Parameters
L = 0.2 # arm length
kT = 1.5e-7
kQ = 1e-8
# Simplified mixer (X configuration)
# T1 + T2 + T3 + T4 = T
# L(-T1 + T2 + T3 - T4) = tau_phi
# L(T1 + T2 - T3 - T4) = tau_theta
# (T1 - T2 + T3 - T4) * kQ/kT = tau_psi
T = 22
tau_phi = 0.5
tau_theta = 0
tau_psi = 0.1
# Solve (simplified, ignoring drag moment)
T1 = T/4 - tau_phi/(4*L) + tau_theta/(4*L) + tau_psi*kT/(4*kQ)
T2 = T/4 + tau_phi/(4*L) + tau_theta/(4*L) - tau_psi*kT/(4*kQ)
T3 = T/4 + tau_phi/(4*L) - tau_theta/(4*L) + tau_psi*kT/(4*kQ)
T4 = T/4 - tau_phi/(4*L) - tau_theta/(4*L) - tau_psi*kT/(4*kQ)
print(f"T1 = {T1:.2f} N") # ~4.9
print(f"T2 = {T2:.2f} N") # ~6.1
print(f"T3 = {T3:.2f} N") # ~6.1
print(f"T4 = {T4:.2f} N") # ~4.9
Masala 13 āāāā
Complementary filter: . Gyro = 45°, Accel = 44.5°. Filtered angle?
Yechim
Gyro dominant ā high frequency movements.
Masala 14 āāāā
Thrust-to-weight ratio (TWR) = 2. Maksimal vertikal tezlanish?
Yechim
m/s²
Pastga ham: (erkin tushish)
Masala 15 āāāā
Position hold: GPS pozitsiya error = 2m (sharq). Kerakli roll burchak? ( 1/m)
Yechim
rad?
Yo'q, bu juda katta. Real systemda:
rad = 11.5°
(Saturatsiya bilan ~15° max)
Masala 16 āāāā
Motor inertia: kg·m². 0 dan 10000 RPM ga 50ms da. Kerakli moment?
Yechim
rad/s
rad/s²
Nm
Masala 17 āāāā
Yaw control: 4 ta motor, ikki juft CW/CCW. Yaw tezligi 30°/s kerak. kg·m². Moment?
Yechim
Agar barqaror yaw rate kerak (tezlanishsiz), (ideally).
Lekin 0 dan 30°/s ga 0.5s da:
rad/s
rad/s²
Nm
Masala 18 āāāā
ESC protocol: PWM 1000-2000μs. 50% throttle = ?
Yechim
PWM range: 1000μs (0%) - 2000μs (100%)
50%: μs
Dshot/OneShot ā raqamli, PWM emas.
Murakkab Masalalar (19-25)ā
Masala 19 āāāāā
Altitude controller: Setpoint 10m, actual 8m, vertical speed -0.5m/s. PID output? (, dt=0.01, integral=2)
Yechim
# Error
e = 10 - 8 = 2 # m
# P
P = 5 * 2 = 10
# I (assuming integral already has some value)
I = 1 * (2 + 2*0.01) = 2.02 # approximately
# D (derivative of error = -velocity)
D = 3 * (-(-0.5)) = 3 * 0.5 = 1.5
# Total
u = P + I + D = 10 + 2 + 1.5 = 13.5
# This is thrust adjustment (N or %)
Thrust += 13.5 (gravity compensation ustiga)
Masala 20 āāāāā
Quadcopter simulyatsiya: 1 sekund hovering keyin roll 10°. Trajectory?
Yechim
import numpy as np
def simulate_quadcopter(duration=5, dt=0.01):
m = 2 # kg
g = 10
# State: [x, y, z, vx, vy, vz, phi, theta, psi]
state = np.zeros(9)
state[2] = 10 # Start at 10m
t = 0
trajectory = []
while t < duration:
x, y, z, vx, vy, vz, phi, theta, psi = state
# Control
if t < 1:
T = m * g # Hover
phi_cmd = 0
else:
T = m * g / np.cos(np.radians(10)) # Compensate
phi_cmd = np.radians(10)
# Simple dynamics
phi = phi_cmd # Instant attitude (simplified)
ax = T * np.sin(phi) / m
ay = 0
az = T * np.cos(phi) / m - g
# Update
vx += ax * dt
vy += ay * dt
vz += az * dt
x += vx * dt
y += vy * dt
z += vz * dt
state = np.array([x, y, z, vx, vy, vz, phi, theta, psi])
trajectory.append([t, x, y, z])
t += dt
return np.array(trajectory)
traj = simulate_quadcopter()
print(f"Final position: x={traj[-1,1]:.2f}m, z={traj[-1,3]:.2f}m")
Masala 21 āāāāā
Sensor fusion: Kalman filter for altitude (barometer + accelerometer).
Yechim
class AltitudeKalman:
def __init__(self):
# State: [altitude, vertical_velocity]
self.x = np.array([0.0, 0.0])
# Covariance
self.P = np.eye(2) * 100
# Process noise
self.Q = np.array([[0.01, 0], [0, 0.1]])
# Measurement noise
self.R_baro = 0.5 # m²
self.R_accel = 0.1 # (m/s²)²
def predict(self, accel, dt):
# State transition
F = np.array([[1, dt], [0, 1]])
B = np.array([0.5*dt**2, dt])
self.x = F @ self.x + B * accel
self.P = F @ self.P @ F.T + self.Q
def update_baro(self, z_baro):
H = np.array([[1, 0]])
y = z_baro - H @ self.x
S = H @ self.P @ H.T + self.R_baro
K = self.P @ H.T / S
self.x = self.x + K.flatten() * y
self.P = (np.eye(2) - np.outer(K, H)) @ self.P
def get_state(self):
return self.x[0], self.x[1]
# Usage
kf = AltitudeKalman()
kf.predict(accel=0.5, dt=0.01)
kf.update_baro(z_baro=10.2)
alt, vel = kf.get_state()
Masala 22 āāāāā
Waypoint navigation: 3 ta waypoint, ETA hisoblash.
Yechim
import numpy as np
def navigate_waypoints(waypoints, max_speed=5, current_pos=np.array([0,0,0])):
total_distance = 0
pos = current_pos.copy()
for wp in waypoints:
wp = np.array(wp)
distance = np.linalg.norm(wp - pos)
total_distance += distance
pos = wp
print(f"To {wp}: {distance:.1f}m")
eta = total_distance / max_speed
print(f"\nTotal: {total_distance:.1f}m, ETA: {eta:.1f}s")
return eta
waypoints = [
[10, 0, 5],
[10, 10, 10],
[0, 10, 5]
]
navigate_waypoints(waypoints)
Masala 23 āāāāā
Battery estimation: Current draw vs remaining capacity.
Yechim
class BatteryEstimator:
def __init__(self, capacity_mah=5000, voltage=11.1):
self.capacity = capacity_mah
self.remaining = capacity_mah
self.voltage = voltage
def update(self, current_a, dt_s):
# mAh consumed
consumed = current_a * 1000 * (dt_s / 3600)
self.remaining -= consumed
# Voltage drop model (simplified)
self.voltage = 12.6 - (1 - self.remaining/self.capacity) * 3.6
return self.remaining, self.voltage
def time_remaining(self, current_a):
return (self.remaining / 1000) / current_a * 3600 # seconds
def percent(self):
return (self.remaining / self.capacity) * 100
# Simulation
bat = BatteryEstimator(5000, 12.6)
current = 15 # Amps
for t in range(0, 1200, 60): # 20 minutes
remaining, voltage = bat.update(current, 60)
print(f"t={t//60}min: {bat.percent():.1f}%, {voltage:.2f}V, "
f"remaining: {bat.time_remaining(current)/60:.1f}min")
Masala 24 āāāāā
Geofence: Doira ichida yoki tashqarisini aniqlash.
Yechim
import numpy as np
class Geofence:
def __init__(self, center, radius, max_altitude=100):
self.center = np.array(center)
self.radius = radius
self.max_alt = max_altitude
def check(self, position):
pos = np.array(position)
# Horizontal distance
h_dist = np.linalg.norm(pos[:2] - self.center[:2])
violations = []
if h_dist > self.radius:
violations.append(f"RADIUS: {h_dist:.1f}m > {self.radius}m")
if pos[2] > self.max_alt:
violations.append(f"ALTITUDE: {pos[2]:.1f}m > {self.max_alt}m")
if pos[2] < 0:
violations.append(f"BELOW GROUND: {pos[2]:.1f}m")
return len(violations) == 0, violations
def clamp(self, position):
"""Return safe position"""
pos = np.array(position)
# Clamp horizontal
h_vec = pos[:2] - self.center[:2]
h_dist = np.linalg.norm(h_vec)
if h_dist > self.radius:
h_vec = h_vec / h_dist * self.radius
pos[:2] = self.center[:2] + h_vec
# Clamp vertical
pos[2] = np.clip(pos[2], 0, self.max_alt)
return pos
# Test
fence = Geofence([0, 0, 0], radius=50, max_altitude=100)
test_positions = [
[30, 40, 50], # Inside
[60, 0, 50], # Outside radius
[0, 0, 120], # Too high
]
for pos in test_positions:
ok, violations = fence.check(pos)
print(f"{pos}: {'OK' if ok else violations}")
Masala 25 āāāāā
Auto-land: Vertikal tezlikni cheklash bilan qo'nish.
Yechim
def auto_land_controller(altitude, velocity, target_velocity=-0.5):
"""
Safe landing controller
target_velocity: desired descent rate (negative = down)
"""
Kp = 5
Kd = 2
# Near ground - slow down
if altitude < 2:
target_velocity = -0.2
if altitude < 0.5:
target_velocity = -0.1
# Velocity error
vel_error = target_velocity - velocity
# Control (simplified)
# Negative = reduce thrust, positive = increase
thrust_adjust = Kp * vel_error
# Safety limits
thrust_adjust = np.clip(thrust_adjust, -5, 5)
return thrust_adjust, target_velocity
# Simulation
altitude = 10
velocity = 0
g = 10
m = 2
dt = 0.01
print("Auto-landing simulation:")
for i in range(2000):
adj, target = auto_land_controller(altitude, velocity)
# Base hover thrust + adjustment
thrust = m * g + adj
# Dynamics
accel = thrust/m - g
velocity += accel * dt
altitude += velocity * dt
if i % 100 == 0:
print(f"t={i*dt:.2f}s: alt={altitude:.2f}m, vel={velocity:.2f}m/s")
if altitude <= 0:
print(f"LANDED at t={i*dt:.2f}s, impact vel={velocity:.2f}m/s")
break
ā Tekshirish Ro'yxatiā
- 1-10: Asosiy hovering va thrust
- 11-18: Kontrol va sensorlar
- 19-25: Murakkab flight control
Keyingi Qadamā
š¬ Amaliyot ā Dron simulyatsiyasi!