🚛 Практическая работа: Программирование модели транспортного робота

От простых команд до продвинутых алгоритмов

🎯 Для всех: Создаем работающего робота
⭐ Для любознательных: Понимаем, как это работает

👨‍🏫 Учитель: Ахметов Рустам
🏫 Школа: ГБОУ № 1362
📅 Дата: 2025-06-14
Время: 80 минут

🎯 Наша цель

🚛 Что мы будем делать

Создадим виртуального робота-грузовика, который умеет:

  • 🚗 Ездить по виртуальным дорогам
  • 👀 “Видеть” препятствия и объезжать их
  • 📦 Подбирать и перевозить грузы
  • 🎯 Находить дорогу к нужному месту

📊 План работы

  1. Постановка задачи (7 мин) - что должен уметь наш робот
  2. Вспоминаем основы (5 мин) - что мы уже знаем
  3. Собираем робота (15 мин) - создаем модель в компьютере
  4. Учим робота думать (20 мин) - пишем программу
  5. Испытания (15 мин) - проверяем, как работает
  6. Показываем результаты (10 мин) - демонстрируем успехи
  7. Подводим итоги (3 мин) - что получилось

🚛 Техническое задание для нашего робота

📋 Основные требования

Наш робот должен уметь:

  • Перевозить груз массой до 2 кг
  • Ехать со скоростью до 0.5 м/с (это как быстрая ходьба)
  • Останавливаться перед препятствиями
  • Находить груз и подбирать его
  • Доставлять груз в нужное место

Размеры робота:

  • Длина: 30 см (как школьная линейка)
  • Ширина: 20 см (как тетрадка)
  • Высота: 15 см (как толстая книга)

⭐ Для любознательных: Инженерные расчеты размеров

Математика размеров:

Коэффициент устойчивости:

\[K_{устойчивость} = \frac{Ширина}{Высота} = \frac{20}{15} = 1.33\]

Коэффициент маневренности:

\[K_{маневренность} = \frac{Длина}{Ширина} = \frac{30}{20} = 1.5\]

Оптимальные соотношения:

  • Устойчивость: K > 1.2 (наш робот: 1.33 ✅)
  • Маневренность: 1.3 < K < 2.0 (наш робот: 1.5 ✅)

Грузоподъемность:

\[m_{груз-макс} = 1.3 \times m_{робот} = 1.3 \times 1.5 = 1.95 ≈ 2.0 \text{ кг}\]

Инженерный компромисс:

  • ↗️ Больше размер = ↗️ устойчивость, ↘️ маневренность
  • ↘️ Меньше размер = ↗️ маневренность, ↘️ место для батарей

🔧 Детальная спецификация

Физические параметры:

  • Масса робота без груза: 1.5 кг
  • Центр тяжести: геометрический центр корпуса
  • Материал корпуса: АБС-пластик
  • Колесная база: 15 см
  • Дорожный просвет: 2 см

Энергосистема:

  • Батарея: Li-Po 7.4В, 2200 мАч
  • Время работы: 120 минут
  • Потребление в покое: 0.5А
  • Потребление при движении: 1.2А

🧠 Вспоминаем: как роботы “думают”

🤖 Основы робототехники

Любой робот состоит из:

  1. “Мозг” - компьютер, который принимает решения
  2. “Глаза” - датчики, которые “видят” мир
  3. “Мускулы” - моторы, которые двигают робота
  4. “Нервы” - провода, которые соединяют все части

🔧 Как робот движется

Наш робот - как танк:

  • Левое колесо крутится с одной скоростью
  • Правое колесо крутится с другой скоростью
  • Если колеса крутятся одинаково → робот едет прямо
  • Если правое быстрее → робот поворачивает налево
  • Если левое быстрее → робот поворачивает направо

Простая формула движения:

Если левое_колесо = правое_колесо → едем прямо
Если левое_колесо > правое_колесо → поворот направо  
Если левое_колесо < правое_колесо → поворот налево

⭐ Для любознательных: Кинематическая модель

Математические формулы движения:

Скорость центра робота:

\[v = \frac{v_L + v_R}{2}\]

Угловая скорость робота:

\[\omega = \frac{v_R - v_L}{L}\]

где $v_L$, $v_R$ - скорости левого и правого колес, $L$ - колесная база

Кинематические уравнения:

\[\begin{cases} \dot{x} = v \cos(\theta) \\ \dot{y} = v \sin(\theta) \\ \dot{\theta} = \omega \end{cases}\]

Практический пример:

  • Колесная база: L = 15 см
  • Левое колесо: 10 см/с, правое: 20 см/с
  • Скорость робота: v = (10+20)/2 = 15 см/с
  • Угловая скорость: ω = (20-10)/15 = 0.67 рад/с

Радиус поворота:

\[R = \frac{v}{\omega} = \frac{15}{0.67} = 22.4 \text{ см}\]

🛠️ Создаем виртуальную модель робота

🎯 Шаг 1: Основа робота

В программе Webots делаем:

  1. Создаем корпус робота

    • Форма: прямоугольник (как коробка)
    • Материал: пластик
    • Цвет: синий (чтобы было красиво)
  2. Добавляем колеса

    • 2 больших колеса (ведущие)
    • 2 маленьких колеса (поддерживающие)
    • Материал: резина (для хорошего сцепления)
  3. Устанавливаем моторы

    • Левый мотор управляет левым колесом
    • Правый мотор управляет правым колесом

🎯 Шаг 2: “Глаза” робота (датчики)

Добавляем датчики:

  1. Ультразвуковой датчик (как у летучих мышей)

    • Посылает звуковые волны
    • Слушает эхо
    • Вычисляет расстояние до препятствий
  2. Камера (как у смартфона)

    • “Видит” цветные объекты
    • Помогает найти груз
    • Определяет направление движения
  3. Датчики поворота колес (энкодеры)

    • Считают, сколько оборотов сделало колесо
    • Помогают понять, как далеко проехал робот

⭐ Для любознательных: Физика датчиков

Ультразвуковой датчик:

Принцип работы - измерение времени полета звука:

\[d = \frac{v_{звук} \times t}{2}\]

где $v_{звук} = 343$ м/с при 20°C

Зависимость скорости звука от температуры:

\[v = 331.3 + 0.606 \times T_{°C}\]

Погрешность измерения:

\[\sigma_d = \sqrt{(\frac{\partial d}{\partial t})^2 \sigma_t^2 + (\frac{\partial d}{\partial v})^2 \sigma_v^2}\]

Типичные погрешности:

  • Время: σₜ = 0.1 мс
  • Скорость: σᵥ = 1 м/с
  • Итого: σd ≈ ±2 см

Энкодер колеса:

Количество импульсов на оборот: N = 1000

Расстояние за один импульс:

\[d_{импульс} = \frac{2\pi r}{N} = \frac{2\pi \times 3}{1000} = 0.0188 \text{ см}\]

Камера и цветовые модели:

RGB → HSV преобразование:

\[H = \arctan2(\sqrt{3}(G-B), 2R-G-B)\] \[S = 1 - \frac{3\min(R,G,B)}{R+G+B}\] \[V = \frac{R+G+B}{3}\]

🎯 Шаг 3: Настройка физики в Webots

PROTO-определение робота:

PROTO TransportRobot [
  field SFVec3f translation 0 0 0.05
  field SFString name "transport_robot"
]
{
  Robot {
    translation IS translation
    name IS name
    children [
      # Основной корпус
      DEF BODY Transform {
        children [
          Shape {
            geometry Box { size 0.30 0.20 0.15 }
            appearance PBRAppearance {
              baseColor 0.3 0.3 0.8
            }
          }
        ]
      }
      
      # Левое колесо с мотором
      DEF LEFT_WHEEL HingeJoint {
        jointParameters HingeJointParameters {
          axis 0 1 0
          anchor -0.075 0.12 0
        }
        device RotationalMotor {
          name "left_motor"
          maxVelocity 10
        }
        endPoint Solid {
          translation -0.075 0.12 0
          children [
            Shape {
              geometry Cylinder { height 0.025 radius 0.04 }
            }
          ]
          physics Physics { density 1200 }
        }
      }
    ]
    
    physics Physics {
      density -1
      mass 1.5
      centerOfMass [0 0 0.02]
    }
  }
}

Параметры нашего робота:

  • Масса: 1.5 кг
  • Центр тяжести: в середине робота
  • Трение колес: 0.8 (хорошее сцепление)
  • Максимальная скорость: 0.5 м/с

💻 Программируем “мозг” робота

🧠 Основная программа

Структура программы:

# Подключаем библиотеки
from controller import Robot, Motor, DistanceSensor, Camera

# Создаем робота
robot = Robot()
timestep = 32  # миллисекунд между "мыслями" робота

# Подключаем устройства
left_motor = robot.getDevice('left_motor')
right_motor = robot.getDevice('right_motor')
distance_sensor = robot.getDevice('distance_sensor')
camera = robot.getDevice('camera')

# Настраиваем моторы
left_motor.setPosition(float('inf'))  # бесконечное вращение
right_motor.setPosition(float('inf'))

# Включаем датчики
distance_sensor.enable(timestep)
camera.enable(timestep)

# Основной цикл - "мышление" робота
while robot.step(timestep) != -1:
    # Читаем датчики
    distance = distance_sensor.getValue()
    
    # Принимаем решение
    if distance > 0.5:  # путь свободен (больше 50 см)
        move_forward()
    else:  # препятствие близко
        avoid_obstacle()

🎯 Базовые функции движения

def move_forward():
    """Едем прямо"""
    speed = 2.0  # скорость в радианах/секунду
    left_motor.setVelocity(speed)
    right_motor.setVelocity(speed)

def turn_left():
    """Поворачиваем налево"""
    left_motor.setVelocity(0.5)    # левое медленно
    right_motor.setVelocity(2.0)   # правое быстро

def turn_right():
    """Поворачиваем направо"""  
    left_motor.setVelocity(2.0)    # левое быстро
    right_motor.setVelocity(0.5)   # правое медленно

def stop():
    """Останавливаемся"""
    left_motor.setVelocity(0)
    right_motor.setVelocity(0)

⭐ Для любознательных: ПИД-регулятор

Что такое ПИД?

  • Пропорциональный - реагирует на размер ошибки
  • Интегральный - учитывает накопленную ошибку
  • Дифференциальный - предвидит будущую ошибку

Математическая формула ПИД:

\[u(t) = K_p e(t) + K_i \int_0^t e(\tau) d\tau + K_d \frac{de(t)}{dt}\]

Дискретная реализация:

\[u_k = K_p e_k + K_i \sum_{i=0}^k e_i \Delta t + K_d \frac{e_k - e_{k-1}}{\Delta t}\]
class PIDController:
    def __init__(self, kp=1.0, ki=0.1, kd=0.05):
        self.kp = kp  # пропорциональный коэффициент
        self.ki = ki  # интегральный коэффициент
        self.kd = kd  # дифференциальный коэффициент
        self.prev_error = 0
        self.integral = 0
        self.dt = 0.032  # шаг времени (32 мс)
        
    def compute(self, target, current):
        error = target - current
        
        # Пропорциональная составляющая
        proportional = self.kp * error
        
        # Интегральная составляющая
        self.integral += error * self.dt
        # Ограничение интеграла (anti-windup)
        self.integral = max(-10, min(10, self.integral))
        integral = self.ki * self.integral
        
        # Дифференциальная составляющая
        derivative = self.kd * (error - self.prev_error) / self.dt
        
        # Итоговый выход
        output = proportional + integral + derivative
        self.prev_error = error
        
        return output

# Пример использования для точного поворота
angle_pid = PIDController(kp=2.0, ki=0.5, kd=0.1)
target_angle = 90  # хотим повернуть на 90 градусов

while abs(current_angle - target_angle) > 1:  # точность 1°
    correction = angle_pid.compute(target_angle, current_angle)
    
    base_speed = 1.0
    left_motor.setVelocity(base_speed - correction)
    right_motor.setVelocity(base_speed + correction)
    
    robot.step(timestep)

Настройка коэффициентов:

  • Kp слишком большой → колебания
  • Ki слишком большой → неустойчивость
  • Kd слишком большой → шум

🎯 Алгоритм избежания препятствий

Простой алгоритм “правой руки”:

def avoid_obstacle():
    """Объезжаем препятствие по алгоритму 'правой руки'"""
    
    # Останавливаемся
    stop()
    time.sleep(0.5)  # пауза на полсекунды
    
    # Поворачиваем направо
    turn_right()
    time.sleep(1.0)  # поворачиваем 1 секунду
    
    # Едем вперед
    move_forward() 
    time.sleep(2.0)  # едем 2 секунды
    
    # Поворачиваем налево (возвращаемся к исходному направлению)
    turn_left()
    time.sleep(1.0)
    
    # Продолжаем ехать прямо
    move_forward()

🎯 Поиск и захват груза

📦 Ищем груз с помощью камеры

def find_red_cargo():
    """Ищем красный груз с помощью камеры"""
    
    image = camera.getImage()
    width = camera.getWidth()
    height = camera.getHeight()
    
    red_pixels = 0
    red_center_x = 0
    
    # Сканируем каждый пиксель
    for x in range(width):
        for y in range(height):
            # Получаем красную составляющую пикселя
            red_value = camera.imageGetRed(image, width, x, y)
            
            if red_value > 200:  # это красный пиксель
                red_pixels += 1
                red_center_x += x
    
    if red_pixels > 100:  # нашли достаточно красных пикселей
        # Вычисляем центр красного объекта
        red_center_x = red_center_x / red_pixels
        
        # Определяем, куда поворачивать
        image_center = width / 2
        if red_center_x < image_center - 20:
            return "turn_left"
        elif red_center_x > image_center + 20:
            return "turn_right"
        else:
            return "move_forward"  # груз прямо по курсу
    
    return "search"  # груз не найден, продолжаем поиск

🤖 Захватываем груз

def pickup_cargo():
    """Подбираем груз"""
    
    # Подъезжаем вплотную
    while distance_sensor.getValue() > 0.1:  # 10 см до груза
        move_forward_slowly()
        robot.step(timestep)
    
    stop()
    
    # Активируем захват (если есть)
    gripper = robot.getDevice('gripper')
    gripper.setPosition(0.0)  # закрываем захват
    
    time.sleep(1.0)  # ждем секунду
    
    # Проверяем, захватили ли груз
    force_sensor = robot.getDevice('force_sensor')
    if force_sensor.getValue() > 0.5:  # чувствуем вес груза
        print("Груз захвачен!")
        return True
    else:
        print("Груз не захвачен, пробуем еще раз")
        return False

⭐ Для любознательных: Компьютерное зрение

HSV цветовая модель для точного определения цвета:

def rgb_to_hsv(r, g, b):
    """Преобразование RGB в HSV"""
    r, g, b = r/255.0, g/255.0, b/255.0
    
    max_val = max(r, g, b)
    min_val = min(r, g, b)
    diff = max_val - min_val
    
    # Вычисляем оттенок (Hue)
    if diff == 0:
        h = 0
    elif max_val == r:
        h = (60 * ((g - b) / diff) + 360) % 360
    elif max_val == g:
        h = (60 * ((b - r) / diff) + 120) % 360
    else:
        h = (60 * ((r - g) / diff) + 240) % 360
    
    # Вычисляем насыщенность (Saturation)
    s = 0 if max_val == 0 else diff / max_val
    
    # Яркость (Value)
    v = max_val
    
    return h, s * 100, v * 100

def detect_red_object_hsv(image):
    """Более точное обнаружение красного объекта"""
    
    red_pixels = []
    
    for x in range(camera.getWidth()):
        for y in range(camera.getHeight()):
            r = camera.imageGetRed(image, camera.getWidth(), x, y)
            g = camera.imageGetGreen(image, camera.getWidth(), x, y)
            b = camera.imageGetBlue(image, camera.getWidth(), x, y)
            
            h, s, v = rgb_to_hsv(r, g, b)
            
            # Красный цвет в HSV: H=0-10 или H=350-360, S>50, V>50
            if ((h >= 0 and h <= 10) or (h >= 350 and h <= 360)) and s > 50 and v > 50:
                red_pixels.append((x, y))
    
    return red_pixels

# Кластеризация пикселей для нахождения объектов
def find_object_clusters(pixels, min_cluster_size=50):
    """Группируем близкие пиксели в объекты"""
    
    if not pixels:
        return []
    
    clusters = []
    used = set()
    
    for pixel in pixels:
        if pixel in used:
            continue
            
        # Начинаем новый кластер
        cluster = [pixel]
        queue = [pixel]
        used.add(pixel)
        
        while queue:
            current = queue.pop(0)
            x, y = current
            
            # Ищем соседние красные пиксели
            for dx in [-1, 0, 1]:
                for dy in [-1, 0, 1]:
                    neighbor = (x + dx, y + dy)
                    if neighbor in pixels and neighbor not in used:
                        cluster.append(neighbor)
                        queue.append(neighbor)
                        used.add(neighbor)
        
        # Добавляем кластер, если он достаточно большой
        if len(cluster) >= min_cluster_size:
            clusters.append(cluster)
    
    return clusters

Математические операции с изображениями:

Гауссово размытие для подавления шума:

\[G(x,y) = \frac{1}{2\pi\sigma^2} e^{-\frac{x^2+y^2}{2\sigma^2}}\]

Свертка изображения с ядром:

\[(I * K)(x,y) = \sum_{i=-n}^{n} \sum_{j=-n}^{n} I(x-i, y-j) \cdot K(i,j)\]

🧪 Тестирование и отладка

🔍 Базовые тесты

Тест 1: Проверяем движение

def test_basic_movement():
    """Проверяем, умеет ли робот двигаться"""
    
    print("Тест 1: Движение вперед")
    start_position = get_robot_position()
    
    move_forward()
    time.sleep(2.0)  # едем 2 секунды
    stop()
    
    end_position = get_robot_position()
    distance_traveled = calculate_distance(start_position, end_position)
    
    print(f"Проехали: {distance_traveled:.2f} метра")
    
    if distance_traveled > 0.5:
        print("✅ ТЕСТ ПРОЙДЕН")
        return True
    else:
        print("❌ ТЕСТ НЕ ПРОЙДЕН")
        return False

Тест 2: Проверяем датчики

def test_sensors():
    """Проверяем работу датчиков"""
    
    print("Тест 2: Датчики")
    
    # Тест ультразвукового датчика
    distance = distance_sensor.getValue()
    print(f"Расстояние до препятствия: {distance:.2f} м")
    
    if 0.1 < distance < 5.0:
        print("✅ Ультразвуковой датчик работает")
    else:
        print("❌ Проблема с ультразвуковым датчиком")
    
    # Тест камеры
    image = camera.getImage()
    if image is not None:
        print("✅ Камера работает")
    else:
        print("❌ Проблема с камерой")

⭐ Для любознательных: Продвинутое тестирование

Статистическое тестирование:

import statistics

def statistical_testing(num_tests=10):
    """Проводим серию тестов и анализируем результаты"""
    
    results = {
        'mission_times': [],
        'success_count': 0,
        'collision_count': [],
        'path_lengths': []
    }
    
    for test_num in range(num_tests):
        print(f"\n🧪 Тест {test_num + 1}/{num_tests}")
        
        # Сброс в исходное состояние
        reset_robot_to_start()
        
        # Запуск миссии
        start_time = time.time()
        collisions = 0
        path_length = 0
        
        mission_success = run_transport_mission()
        end_time = time.time()
        
        # Сбор метрик
        mission_time = end_time - start_time
        results['mission_times'].append(mission_time)
        
        if mission_success:
            results['success_count'] += 1
        
        results['collision_count'].append(get_collision_count())
        results['path_lengths'].append(get_path_length())
    
    # Статистический анализ
    print("\n📊 СТАТИСТИКА ТЕСТИРОВАНИЯ:")
    print(f"Успешность: {results['success_count']}/{num_tests} ({results['success_count']/num_tests*100:.1f}%)")
    
    if results['mission_times']:
        avg_time = statistics.mean(results['mission_times'])
        std_time = statistics.stdev(results['mission_times']) if len(results['mission_times']) > 1 else 0
        print(f"Среднее время: {avg_time:.1f}±{std_time:.1f} сек")
        print(f"Лучшее время: {min(results['mission_times']):.1f} сек")
        print(f"Худшее время: {max(results['mission_times']):.1f} сек")
    
    avg_collisions = statistics.mean(results['collision_count'])
    print(f"Среднее количество столкновений: {avg_collisions:.1f}")
    
    return results

def calculate_confidence_interval(data, confidence=0.95):
    """Вычисляем доверительный интервал"""
    import scipy.stats as stats
    
    n = len(data)
    mean = statistics.mean(data)
    std_error = statistics.stdev(data) / (n ** 0.5)
    
    # t-распределение для малых выборок
    t_value = stats.t.ppf((1 + confidence) / 2, n - 1)
    margin_error = t_value * std_error
    
    return mean - margin_error, mean + margin_error

# Benchmark разных алгоритмов
def benchmark_algorithms():
    """Сравниваем производительность разных алгоритмов"""
    
    algorithms = [
        ("Простое избежание", simple_obstacle_avoidance),
        ("Правая рука", right_hand_rule),
        ("Потенциальные поля", potential_fields_navigation),
        ("A* планирование", astar_navigation)
    ]
    
    results = {}
    
    for name, algorithm in algorithms:
        print(f"\n🔬 Тестируем алгоритм: {name}")
        
        times = []
        success_rate = 0
        
        for _ in range(5):  # 5 прогонов каждого алгоритма
            reset_environment()
            
            start_time = time.time()
            success = algorithm()
            end_time = time.time()
            
            if success:
                times.append(end_time - start_time)
                success_rate += 1
        
        results[name] = {
            'avg_time': statistics.mean(times) if times else float('inf'),
            'success_rate': success_rate / 5 * 100,
            'best_time': min(times) if times else float('inf')
        }
        
        print(f"  Успешность: {success_rate}/5 ({success_rate/5*100:.0f}%)")
        if times:
            print(f"  Среднее время: {statistics.mean(times):.1f} сек")
            print(f"  Лучшее время: {min(times):.1f} сек")
    
    # Ранжирование алгоритмов
    print("\n🏆 РЕЙТИНГ АЛГОРИТМОВ:")
    sorted_algorithms = sorted(results.items(), 
                              key=lambda x: (x[1]['success_rate'], -x[1]['avg_time']), 
                              reverse=True)
    
    for i, (name, metrics) in enumerate(sorted_algorithms, 1):
        print(f"{i}. {name}: {metrics['success_rate']:.0f}% успех, {metrics['avg_time']:.1f}с время")
    
    return results

Метрики качества навигации:

Эффективность пути:

\[\eta_{path} = \frac{L_{optimal}}{L_{actual}}\]

Плавность движения:

\[\sigma_{smooth} = \frac{1}{N-1} \sum_{i=1}^{N-1} |\omega_{i+1} - \omega_i|\]

Интегральная оценка качества:

\[Q = w_1 \eta_{path} + w_2 e^{-\sigma_{smooth}} + w_3 \frac{T_{target}}{T_{actual}}\]

где $w_1 + w_2 + w_3 = 1$

🏃 Физкультминутка: Робот-симулятор

🤖 Упражнение “Программируем друг друга”

Правила игры:

  1. Разделитесь на пары: “программист” и “робот”
  2. “Робот” закрывает глаза и может выполнять только команды
  3. “Программист” дает команды голосом

Доступные команды:

  • move_forward(шаги) - двигаться вперед на N шагов
  • turn_left(90) - повернуться налево на 90°
  • turn_right(90) - повернуться направо на 90°
  • stop() - остановиться
  • beep() - издать звук (робот говорит “пип”)

Задание: “Роботу” нужно дойти от парты до доски, не столкнувшись с препятствиями (другими учениками).

⭐ Усложнение для любознательных: Добавьте команду if(sensor_obstacle, command1, command2) - если датчик обнаруживает препятствие, выполни команду1, иначе команду2.

🎤 Демонстрация результатов

📊 Формат презентации

Время на демонстрацию: 1.5 минуты на пару

План выступления:

  1. Показ модели (30 сек)

    • Как выглядит ваш робот
    • Какие датчики использовали
    • Особенности конструкции
  2. Демонстрация программы (30 сек)

    • Ключевые функции кода
    • Алгоритм поведения робота
    • Интересные решения
  3. Тестовый прогон (30 сек)

    • Выполнение транспортной задачи
    • Комментарии к действиям робота

🏆 Критерии оценки

Базовая оценка (20 баллов):

  • ✅ Робот создан и стабильно работает (5 баллов)
  • ✅ Программа выполняет основные функции (5 баллов)
  • ✅ Робот избегает препятствия (5 баллов)
  • ✅ Успешное выполнение транспортной задачи (5 баллов)

⭐ Дополнительные баллы (до 10 баллов):

  • 🌟 Оригинальные алгоритмы (+3 балла)
  • 🌟 Оптимизация производительности (+2 балла)
  • 🌟 Дополнительная функциональность (+3 балла)
  • 🌟 Качественная презентация (+2 балла)

Шкала оценивания:

  • 5 (отлично): 25-30 баллов
  • 4 (хорошо): 20-24 балла
  • 3 (удовлетворительно): 15-19 баллов

🎯 Примеры выдающихся решений

🏅 Решение 1: “Умный поиск груза”

def spiral_cargo_search():
    """Систематический поиск груза по расширяющейся спирали"""
    
    search_radius = 0.5  # начальный радиус поиска
    angle_step = 30      # шаг поворота в градусах
    max_radius = 3.0     # максимальный радиус поиска
    
    while search_radius <= max_radius:
        print(f"Поиск в радиусе {search_radius:.1f} м")
        
        # Полный оборот на текущем радиусе
        for angle in range(0, 360, angle_step):
            turn_to_angle(angle)
            
            # Проверяем, видим ли груз
            cargo_direction = find_red_cargo()
            if cargo_direction == "move_forward":
                print("🎯 Груз обнаружен!")
                return approach_cargo()
        
        # Увеличиваем радиус поиска
        move_forward_distance(0.3)
        search_radius += 0.3
    
    print("❌ Груз не найден в зоне поиска")
    return False

def approach_cargo():
    """Точный подход к грузу с корректировкой"""
    
    approach_attempts = 0
    max_attempts = 10
    
    while approach_attempts < max_attempts:
        cargo_direction = find_red_cargo()
        distance = distance_sensor.getValue()
        
        if distance < 0.15:  # достаточно близко для захвата
            return pickup_cargo()
        
        elif cargo_direction == "move_forward":
            move_forward_slowly()
        elif cargo_direction == "turn_left":
            turn_left()
            time.sleep(0.2)
        elif cargo_direction == "turn_right":
            turn_right()
            time.sleep(0.2)
        else:
            # Груз потерялся, делаем небольшой поиск
            for _ in range(4):
                turn_right()
                time.sleep(0.5)
                if find_red_cargo() != "search":
                    break
        
        approach_attempts += 1
        robot.step(timestep)
    
    return False

🏅 Решение 2: “Адаптивное управление скоростью”

class AdaptiveSpeedController:
    def __init__(self):
        self.base_speed = 2.0
        self.current_speed = self.base_speed
        self.obstacle_history = []
        self.max_history = 10
        
    def calculate_optimal_speed(self, front_distance, side_distances):
        """Вычисляем оптимальную скорость на основе окружения"""
        
        # Базовая скорость зависит от расстояния до препятствий
        min_distance = min(front_distance, min(side_distances))
        
        if min_distance > 2.0:
            target_speed = self.base_speed  # полная скорость
        elif min_distance > 1.0:
            target_speed = self.base_speed * 0.7  # средняя скорость
        elif min_distance > 0.5:
            target_speed = self.base_speed * 0.4  # медленная скорость
        else:
            target_speed = 0.2  # очень медленно
        
        # Учитываем историю препятствий
        self.obstacle_history.append(min_distance)
        if len(self.obstacle_history) > self.max_history:
            self.obstacle_history.pop(0)
        
        # Если часто встречаем препятствия, снижаем базовую скорость
        avg_distance = sum(self.obstacle_history) / len(self.obstacle_history)
        if avg_distance < 1.0:
            target_speed *= 0.8  # адаптивное снижение
        
        # Плавное изменение скорости
        speed_diff = target_speed - self.current_speed
        self.current_speed += speed_diff * 0.3  # коэффициент сглаживания
        
        return self.current_speed
    
    def emergency_brake(self, distance):
        """Экстренное торможение при критическом сближении"""
        if distance < 0.2:  # критическая дистанция
            return 0  # полная остановка
        elif distance < 0.3:
            return self.current_speed * 0.1  # резкое замедление
        else:
            return self.current_speed

🤔 Рефлексия: что мы узнали

🎯 Основные достижения

Что мы научились делать:

  • ✅ Создавать виртуальные модели роботов
  • ✅ Программировать базовые алгоритмы движения
  • ✅ Обрабатывать данные от датчиков
  • ✅ Решать задачи автономной навигации
  • ✅ Тестировать и отлаживать программы

Что мы поняли:

  • 🧠 Как роботы “видят” мир через датчики
  • 🔧 Как простые команды создают сложное поведение
  • 📊 Важность тестирования для надежной работы
  • 🔄 Как итеративно улучшать алгоритмы

🔍 Вопросы для размышления

Обсуждаем в классе:

  1. Какие проблемы возникли при создании робота?
  2. Чем виртуальный робот отличается от реального?
  3. Какие задачи было труднее всего запрограммировать?
  4. Где в реальной жизни используются похожие роботы?

⭐ Для любознательных: Философия робототехники

Этические вопросы автономных систем:

  1. Проблема принятия решений:

    • Должен ли робот-автомобиль выбирать, кого спасать при неизбежной аварии?
    • Кто несет ответственность за действия автономного робота?
  2. Влияние на общество:

    • Заменят ли роботы людей на рабочих местах?
    • Как сохранить человеческие навыки в мире роботов?
  3. Конфиденциальность и безопасность:

    • Могут ли роботы с камерами нарушать приватность?
    • Как защитить роботов от взлома?

Будущее человеко-роботного взаимодействия:

# Псевдокод этического алгоритма для робота
def ethical_decision_making(situation):
    """Этический алгоритм принятия решений"""
    
    # Приоритет 1: Безопасность человека
    if human_safety_at_risk(situation):
        return prioritize_human_safety()
    
    # Приоритет 2: Минимизация вреда
    options = generate_possible_actions(situation)
    harm_scores = [calculate_potential_harm(option) for option in options]
    best_option = options[harm_scores.index(min(harm_scores))]
    
    # Приоритет 3: Уважение к человеческой автономии
    if requires_human_consent(best_option):
        return request_human_approval(best_option)
    
    return best_option

# Принципы этичного ИИ:
ETHICAL_PRINCIPLES = [
    "Прозрачность: действия робота должны быть объяснимы",
    "Справедливость: отсутствие дискриминации",
    "Ответственность: четкое определение ответственных лиц",
    "Приватность: защита персональных данных",
    "Благополучие: максимизация пользы для общества"
]

Карьерные перспективы в робототехнике:

  • Инженер-робототехник - проектирование и создание роботов
  • Специалист по машинному обучению - обучение роботов новым навыкам
  • Этик ИИ - разработка этических стандартов для роботов
  • UX-дизайнер для роботов - проектирование взаимодействия человек-робот
  • Специалист по кибербезопасности роботов - защита от взлома

🏠 Домашнее задание

📋 Базовый уровень (для всех)

1. Отчет о практической работе Напишите краткий отчет (1-2 страницы), включающий:

  • Описание вашей модели робота
  • Основные функции программы
  • Трудности, с которыми столкнулись
  • Что получилось лучше всего

2. Поиск роботов в реальной жизни Найдите 5 примеров роботов, которые работают в реальном мире:

  • Где они используются?
  • Какие задачи выполняют?
  • Какие датчики у них есть?
  • Чем похожи на нашего виртуального робота?

🎯 Повышенный уровень (по желанию)

3. Улучшение алгоритма Выберите один из вариантов для доработки:

  • Добавить поиск груза по спирали
  • Реализовать запоминание карты препятствий
  • Создать энергосберегающий режим
  • Добавить работу в команде из нескольких роботов

4. Исследовательский проект Выберите тему для мини-исследования:

  • “Роботы в медицине: помощники или заменители врачей?”
  • “Этические проблемы автономных автомобилей”
  • “Роботы и рабочие места: друзья или конкуренты?”
  • “Как роботы изучают космос?”

⭐ Для школьных аспирантов

5. Продвинутые алгоритмы

Вариант А: Алгоритм A*

def implement_astar():
    """Реализуйте алгоритм A* для поиска оптимального пути"""
    
    # Задача: создать функцию, которая находит кратчайший путь
    # от стартовой точки до цели, обходя препятствия
    
    # Подсказки:
    # 1. Используйте эвристическую функцию (например, Манхэттенское расстояние)
    # 2. Ведите списки открытых и закрытых узлов
    # 3. Для каждого узла храните g(n), h(n) и f(n) = g(n) + h(n)
    
    pass  # Ваша реализация

Вариант Б: ПИД-регулятор

def tune_pid_controller():
    """Настройте ПИД-регулятор для точного следования по линии"""
    
    # Задача: найти оптимальные коэффициенты Kp, Ki, Kd
    # для следования робота по черной линии
    
    # Критерии качества:
    # - Минимальное отклонение от линии
    # - Отсутствие колебаний
    # - Быстрая реакция на повороты
    
    kp_range = [0.5, 1.0, 1.5, 2.0]
    ki_range = [0.0, 0.1, 0.2, 0.3]
    kd_range = [0.0, 0.05, 0.1, 0.15]
    
    # Проведите серию экспериментов и найдите лучшие параметры
    pass  # Ваша реализация

6. Математическое моделирование

Задача: Модель энергопотребления Создайте математическую модель энергопотребления робота:

\[E_{total} = E_{motion} + E_{sensors} + E_{processing} + E_{idle}\]

где:

  • $E_{motion}$ - энергия на движение
  • $E_{sensors}$ - энергия датчиков
  • $E_{processing}$ - энергия вычислений
  • $E_{idle}$ - базовое потребление

Исследуйте зависимости:

  • Как скорость влияет на энергопотребление?
  • Какой режим работы датчиков оптимален?
  • Как планировать маршрут для экономии энергии?

🎉 Заключение

🏆 Что мы достигли сегодня

Практические навыки:

  • ✅ Создали функционального виртуального робота
  • ✅ Запрограммировали автономное поведение
  • ✅ Решили реальную транспортную задачу
  • ✅ Научились тестировать и отлаживать код

Понимание принципов:

  • 🧠 Как работают современные роботы
  • 📡 Роль датчиков в робототехнике
  • 💻 Связь программирования и реального поведения
  • 🔧 Итеративный процесс разработки

🚀 Дальнейшие шаги

На следующих уроках мы изучим:

  • Работу с реальными робототехническими наборами
  • Создание многороботных систем
  • Машинное обучение для роботов
  • Интеграцию роботов с интернетом вещей

🌟 Главное открытие

“Робототехника - это не только программирование или конструирование. Это искусство создания систем, которые могут действовать автономно в реальном мире!”

🤖 Поздравляем! Вы сделали первый шаг к профессии будущего!

📚 Дополнительные ресурсы

🔗 Полезные ссылки

Для продолжения изучения:

Соревнования и олимпиады:

  • РобоКап - международные соревнования роботов
  • WRO - Всемирная олимпиада роботов
  • FIRST Robotics - молодежные робототехнические соревнования

📖 Рекомендуемая литература

Для школьников:

  • “Робототехника для детей и родителей” - С.А. Филиппов
  • “Программирование роботов на языке Python” - А.В. Корягин
  • “Искусственный интеллект для школьников” - М.И. Беляев

⭐ Для углубленного изучения:

  • “Introduction to Robotics” - John Craig
  • “Robotics: Modelling, Planning and Control” - Siciliano
  • “Probabilistic Robotics” - Thrun, Burgard, Fox

Удачи в изучении робототехники! 🚀🤖✨