Skip to main content

1.3 Trigonometriya — Amaliyot

Laboratoriya ishi: Python da trigonometriya va robot kinematikasi


1. Asosiy Trigonometrik Funksiyalar

import numpy as np
import matplotlib.pyplot as plt

# Burchaklar (gradus va radian)
angles_deg = np.array([0, 30, 45, 60, 90, 120, 135, 150, 180])
angles_rad = np.radians(angles_deg)

# Trigonometrik qiymatlar
print("θ(°)\tθ(rad)\t\tsin(θ)\t\tcos(θ)\t\ttan(θ)")
print("-" * 70)
for deg, rad in zip(angles_deg, angles_rad):
sin_val = np.sin(rad)
cos_val = np.cos(rad)
tan_val = np.tan(rad) if abs(cos_val) > 1e-10 else float('inf')
print(f"{deg}\t{rad:.4f}\t\t{sin_val:.4f}\t\t{cos_val:.4f}\t\t{tan_val:.4f}")

# Grafik
theta = np.linspace(0, 2*np.pi, 100)
plt.figure(figsize=(12, 4))

plt.subplot(1, 3, 1)
plt.plot(theta, np.sin(theta), 'b-', linewidth=2)
plt.title('sin(θ)')
plt.xlabel('θ (rad)')
plt.grid(True)

plt.subplot(1, 3, 2)
plt.plot(theta, np.cos(theta), 'r-', linewidth=2)
plt.title('cos(θ)')
plt.xlabel('θ (rad)')
plt.grid(True)

plt.subplot(1, 3, 3)
plt.plot(theta, np.tan(theta), 'g-', linewidth=2)
plt.ylim(-5, 5)
plt.title('tan(θ)')
plt.xlabel('θ (rad)')
plt.grid(True)

plt.tight_layout()
plt.savefig('trig_functions.png', dpi=150)
plt.show()

2. Birlik Aylana Vizualizatsiyasi

import numpy as np
import matplotlib.pyplot as plt

def plot_unit_circle(angle_deg):
"""Birlik aylanada burchakni ko'rsatish"""
angle_rad = np.radians(angle_deg)

# Aylana
theta = np.linspace(0, 2*np.pi, 100)
x_circle = np.cos(theta)
y_circle = np.sin(theta)

# Nuqta
x = np.cos(angle_rad)
y = np.sin(angle_rad)

plt.figure(figsize=(8, 8))
plt.plot(x_circle, y_circle, 'b-', linewidth=2)
plt.axhline(y=0, color='k', linewidth=0.5)
plt.axvline(x=0, color='k', linewidth=0.5)

# Radius va nuqta
plt.plot([0, x], [0, y], 'r-', linewidth=2, label=f'θ = {angle_deg}°')
plt.plot(x, y, 'ro', markersize=10)

# sin va cos
plt.plot([x, x], [0, y], 'g--', linewidth=2, label=f'sin(θ) = {y:.3f}')
plt.plot([0, x], [y, y], 'm--', linewidth=2, label=f'cos(θ) = {x:.3f}')

plt.xlim(-1.5, 1.5)
plt.ylim(-1.5, 1.5)
plt.gca().set_aspect('equal')
plt.grid(True)
plt.legend()
plt.title(f'Birlik Aylana: θ = {angle_deg}°')
plt.savefig(f'unit_circle_{angle_deg}.png', dpi=150)
plt.show()

# Test
plot_unit_circle(45)
plot_unit_circle(120)

3. atan2 vs arctan

import numpy as np

def compare_atan(x, y):
"""arctan va atan2 solishtiruvi"""
if x != 0:
arctan_result = np.arctan(y/x)
else:
arctan_result = np.pi/2 if y > 0 else -np.pi/2

atan2_result = np.arctan2(y, x)

print(f"Nuqta: ({x}, {y})")
print(f" arctan(y/x) = {np.degrees(arctan_result):.2f}°")
print(f" atan2(y, x) = {np.degrees(atan2_result):.2f}°")
print()

# Test - turli choraklarda
print("=== atan2 va arctan solishtiruvi ===\n")
compare_atan(1, 1) # I chorak
compare_atan(-1, 1) # II chorak
compare_atan(-1, -1) # III chorak
compare_atan(1, -1) # IV chorak

Natija:

Nuqta: (1, 1)
arctan(y/x) = 45.00°
atan2(y, x) = 45.00°

Nuqta: (-1, 1)
arctan(y/x) = -45.00° ← NOTO'G'RI!
atan2(y, x) = 135.00° ← TO'G'RI

Nuqta: (-1, -1)
arctan(y/x) = 45.00° ← NOTO'G'RI!
atan2(y, x) = -135.00° ← TO'G'RI

4. 2D Robot Qo'li - Forward Kinematika

import numpy as np
import matplotlib.pyplot as plt

def forward_kinematics_2d(L1, L2, theta1_deg, theta2_deg):
"""
2 bo'g'inli robot qo'lining forward kinematikasi
theta1: birinchi bo'g'in burchagi (bazadan)
theta2: ikkinchi bo'g'in burchagi (birinchidan)
"""
theta1 = np.radians(theta1_deg)
theta2 = np.radians(theta2_deg)

# Birinchi bo'g'in oxiri
x1 = L1 * np.cos(theta1)
y1 = L1 * np.sin(theta1)

# Ikkinchi bo'g'in oxiri (end effector)
x2 = x1 + L2 * np.cos(theta1 + theta2)
y2 = y1 + L2 * np.sin(theta1 + theta2)

return [(0, 0), (x1, y1), (x2, y2)]

def plot_robot_arm(L1, L2, theta1, theta2):
"""Robot qo'lini chizish"""
joints = forward_kinematics_2d(L1, L2, theta1, theta2)

plt.figure(figsize=(10, 8))

# Bo'g'inlar
xs = [j[0] for j in joints]
ys = [j[1] for j in joints]

plt.plot(xs, ys, 'bo-', linewidth=3, markersize=15)
plt.plot(xs[-1], ys[-1], 'r*', markersize=20, label='End Effector')

# Workspace chegarasi
theta = np.linspace(0, 2*np.pi, 100)
plt.plot((L1+L2)*np.cos(theta), (L1+L2)*np.sin(theta), 'g--', alpha=0.3, label='Max reach')
plt.plot(abs(L1-L2)*np.cos(theta), abs(L1-L2)*np.sin(theta), 'r--', alpha=0.3, label='Min reach')

plt.xlim(-(L1+L2+0.5), L1+L2+0.5)
plt.ylim(-(L1+L2+0.5), L1+L2+0.5)
plt.gca().set_aspect('equal')
plt.grid(True)
plt.legend()
plt.title(f'2D Robot Qo\'li: θ1={theta1}°, θ2={theta2}°')
plt.xlabel('X (m)')
plt.ylabel('Y (m)')

# End effector pozitsiyasi
print(f"End Effector: ({xs[-1]:.3f}, {ys[-1]:.3f}) m")

plt.savefig('robot_arm_2d.png', dpi=150)
plt.show()

# Test
L1, L2 = 1.0, 0.8 # Bo'g'in uzunliklari (m)
plot_robot_arm(L1, L2, 45, 30)

5. Inverse Kinematika

import numpy as np

def inverse_kinematics_2d(L1, L2, x, y):
"""
Maqsad pozitsiyadan bo'g'in burchaklarini hisoblash
Qaytaradi: (theta1, theta2) gradusda, yoki None agar yetib bo'lmasa
"""
# Maqsadgacha masofa
r = np.sqrt(x**2 + y**2)

# Yetish mumkinligini tekshirish
if r > L1 + L2 or r < abs(L1 - L2):
return None # Yetib bo'lmaydi

# theta2 ni hisoblash (kosinus teoremasi)
cos_theta2 = (r**2 - L1**2 - L2**2) / (2 * L1 * L2)
cos_theta2 = np.clip(cos_theta2, -1, 1) # Raqamli xatolar uchun

# Ikki yechim mavjud: "elbow up" va "elbow down"
theta2_up = np.arccos(cos_theta2)
theta2_down = -np.arccos(cos_theta2)

# theta1 ni hisoblash
def calc_theta1(theta2):
sin_theta2 = np.sin(theta2)
alpha = np.arctan2(y, x)
beta = np.arctan2(L2 * sin_theta2, L1 + L2 * cos_theta2)
return alpha - beta

theta1_up = calc_theta1(theta2_up)
theta1_down = calc_theta1(theta2_down)

return {
'elbow_up': (np.degrees(theta1_up), np.degrees(theta2_up)),
'elbow_down': (np.degrees(theta1_down), np.degrees(theta2_down))
}

# Test
L1, L2 = 1.0, 0.8
target = (1.2, 0.8)

result = inverse_kinematics_2d(L1, L2, *target)
if result:
print(f"Maqsad: {target}")
print(f"Elbow Up: θ1 = {result['elbow_up'][0]:.2f}°, θ2 = {result['elbow_up'][1]:.2f}°")
print(f"Elbow Down: θ1 = {result['elbow_down'][0]:.2f}°, θ2 = {result['elbow_down'][1]:.2f}°")
else:
print("Maqsadga yetib bo'lmaydi!")

6. Euler Burchaklari (3D)

import numpy as np

def euler_to_rotation_matrix(roll, pitch, yaw, degrees=True):
"""
Euler burchaklaridan aylanish matritsasi (ZYX konvensiya)
"""
if degrees:
roll = np.radians(roll)
pitch = np.radians(pitch)
yaw = np.radians(yaw)

# Rx (roll)
Rx = np.array([
[1, 0, 0],
[0, np.cos(roll), -np.sin(roll)],
[0, np.sin(roll), np.cos(roll)]
])

# Ry (pitch)
Ry = np.array([
[np.cos(pitch), 0, np.sin(pitch)],
[0, 1, 0],
[-np.sin(pitch), 0, np.cos(pitch)]
])

# Rz (yaw)
Rz = np.array([
[np.cos(yaw), -np.sin(yaw), 0],
[np.sin(yaw), np.cos(yaw), 0],
[0, 0, 1]
])

# ZYX tartibida
R = Rz @ Ry @ Rx
return R

def rotation_matrix_to_euler(R):
"""
Aylanish matritsasidan Euler burchaklari (ZYX)
"""
# Gimbal lock tekshiruvi
if abs(R[2, 0]) >= 1:
yaw = 0
if R[2, 0] < 0:
pitch = np.pi / 2
roll = np.arctan2(R[0, 1], R[0, 2])
else:
pitch = -np.pi / 2
roll = np.arctan2(-R[0, 1], -R[0, 2])
else:
pitch = np.arcsin(-R[2, 0])
roll = np.arctan2(R[2, 1], R[2, 2])
yaw = np.arctan2(R[1, 0], R[0, 0])

return np.degrees(roll), np.degrees(pitch), np.degrees(yaw)

# Test
roll, pitch, yaw = 10, 20, 30 # gradus

R = euler_to_rotation_matrix(roll, pitch, yaw)
print("Euler burchaklari:", roll, pitch, yaw)
print("\nAylanish matritsasi:")
print(np.round(R, 4))

# Qayta aylantirish
r, p, y = rotation_matrix_to_euler(R)
print(f"\nQayta hisoblangan: roll={r:.2f}°, pitch={p:.2f}°, yaw={y:.2f}°")

7. Dron Yo'nalishini Hisoblash

import numpy as np

def calculate_heading(current_pos, target_pos):
"""
Joriy pozitsiyadan maqsadga yo'nalish (yaw) burchagini hisoblash
"""
dx = target_pos[0] - current_pos[0]
dy = target_pos[1] - current_pos[1]

heading = np.degrees(np.arctan2(dy, dx))

# 0-360 oralig'iga o'tkazish
if heading < 0:
heading += 360

return heading

def calculate_elevation(current_pos, target_pos):
"""
Elevatsiya (pitch) burchagini hisoblash
"""
dx = target_pos[0] - current_pos[0]
dy = target_pos[1] - current_pos[1]
dz = target_pos[2] - current_pos[2]

horizontal_dist = np.sqrt(dx**2 + dy**2)
elevation = np.degrees(np.arctan2(dz, horizontal_dist))

return elevation

# Test: Dron navigatsiyasi
drone_pos = np.array([0, 0, 10]) # Dron pozitsiyasi
waypoints = [
np.array([100, 0, 10]), # Sharqqa
np.array([100, 100, 20]), # Shimoli-sharq, yuqoriga
np.array([0, 100, 5]), # Shimol, pastga
np.array([0, 0, 10]), # Qaytish
]

print("Dron Navigatsiya Rejasi")
print("=" * 50)
current = drone_pos
for i, wp in enumerate(waypoints):
heading = calculate_heading(current[:2], wp[:2])
elevation = calculate_elevation(current, wp)
distance = np.linalg.norm(wp - current)

print(f"\nWaypoint {i+1}: {wp}")
print(f" Heading: {heading:.1f}°")
print(f" Elevation: {elevation:.1f}°")
print(f" Distance: {distance:.1f} m")

current = wp

8. Topshiriq: Proektil Traektoriyasi

import numpy as np
import matplotlib.pyplot as plt

def projectile_motion(v0, theta_deg, h0=0, g=9.81, dt=0.01):
"""
Proektil harakati simulyatsiyasi

v0: boshlang'ich tezlik (m/s)
theta_deg: otish burchagi (gradus)
h0: boshlang'ich balandlik (m)
g: gravitatsiya tezlanishi (m/s²)
"""
theta = np.radians(theta_deg)

# Boshlang'ich tezlik komponentlari
vx0 = v0 * np.cos(theta)
vy0 = v0 * np.sin(theta)

# TODO: Traektoriyani hisoblang
# Hint: x(t) = vx0 * t
# y(t) = h0 + vy0 * t - 0.5 * g * t²

# Sizning kodingiz...

pass

# Test
# projectile_motion(50, 45, h0=0)
Yechim
def projectile_motion(v0, theta_deg, h0=0, g=9.81, dt=0.01):
theta = np.radians(theta_deg)
vx0 = v0 * np.cos(theta)
vy0 = v0 * np.sin(theta)

# Uchish vaqti (yerga tushguncha)
# 0 = h0 + vy0*t - 0.5*g*t²
# Diskriminant
t_flight = (vy0 + np.sqrt(vy0**2 + 2*g*h0)) / g

t = np.arange(0, t_flight, dt)
x = vx0 * t
y = h0 + vy0 * t - 0.5 * g * t**2

# Statistika
max_height = h0 + vy0**2 / (2*g)
range_x = vx0 * t_flight

# Grafik
plt.figure(figsize=(12, 6))
plt.plot(x, y, 'b-', linewidth=2)
plt.axhline(y=0, color='brown', linewidth=2)
plt.scatter([0], [h0], color='green', s=100, label='Start')
plt.scatter([range_x], [0], color='red', s=100, label='Landing')
plt.scatter([range_x/2], [max_height], color='orange', s=100, label=f'Max: {max_height:.1f}m')

plt.xlabel('Masofa (m)')
plt.ylabel('Balandlik (m)')
plt.title(f'Proektil: v₀={v0} m/s, θ={theta_deg}°')
plt.legend()
plt.grid(True)
plt.savefig('projectile.png', dpi=150)
plt.show()

print(f"Maksimal balandlik: {max_height:.2f} m")
print(f"Uchish masofasi: {range_x:.2f} m")
print(f"Uchish vaqti: {t_flight:.2f} s")

projectile_motion(50, 45, h0=0)

✅ Laboratoriya Tekshirish Ro'yxati

  • Trigonometrik funksiyalar grafigi
  • Birlik aylana vizualizatsiyasi
  • atan2 to'g'ri ishlaydi
  • Forward kinematika
  • Inverse kinematika
  • Euler burchaklari
  • Dron navigatsiyasi
  • Proektil topshiriq

Keyingi Mavzu

📖 1.4 Differensial Hisob