Desbravando o PyBricks: Programando o SPIKE Prime em Python do Zero
Aula

Objetivo da aula

  • Executar curvas suaves controlando velocidade linear e taxa de giro.
  • Fazer giros controlados (em graus) com repetibilidade.
  • Entender a relação entre raio da curva, largura do eixo e distância percorrida.
  • Implementar uma função utilitária para curvas por raio + ângulo.

1) Conceitos-chave

  • Velocidade linear (mm/s): quão rápido o robô avança.
  • Taxa de giro (°/s): quão rápido o robô gira o corpo em torno do centro.
  • Raio da curva (mm): distância do centro do robô até o centro do arco percorrido.
Intuição: aumentar a taxa de giro mantém a curva mais fechada; reduzir a taxa de giro abre a curva. Diminuir a velocidade linear melhora a precisão.

2) Curvas suaves com drive()

O DriveBase permite “dirigir” contínuo definindo a velocidade linear e a taxa de giro.
Use drive(v_mm_s, turn_deg_s) e controle a duração com wait() ou drive_time().

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import Motor
from pybricks.parameters import Port, Stop
from pybricks.robotics import DriveBase
from pybricks.tools import wait

hub = PrimeHub()
mE, mD = Motor(Port.A), Motor(Port.B)
robot = DriveBase(mE, mD, 56, 120)  # 56mm roda, 120mm entre rodas (ajuste ao seu robô)

robot.settings(straight_speed=250, turn_rate=90)
robot.drive(200, 45)   # 200 mm/s avançando, virando 45°/s (curva suave à direita)
wait(1500)             # curva por 1,5s
robot.stop(Stop.BRAKE)

Para definir a duração diretamente, utilize drive_time(v, turn, tempo_ms) (quando disponível), mantendo a mesma lógica de parâmetros.

3) Giros controlados com turn()

Para giros “sobre o eixo” (turn-in-place) com ângulo exato, use turn(ângulo_em_graus).

robot.settings(turn_rate=120)  # taxa angular padrão para giros
robot.turn(90)                 # gira 90° para a direita
robot.turn(-45)                # gira 45° para a esquerda
robot.stop(Stop.HOLD)
Boas práticas: giros muito rápidos tendem a ultrapassar o alvo. Use turn_rate menor para precisão.

4) Curva por raio e ângulo (função utilitária)

Em missões, é útil descrever uma curva por raio R (mm) e ângulo θ (°) — por exemplo, “curvar 60° num raio de 140 mm”.
Abaixo, uma função que aproxima essa curva usando drive() por um tempo calculado:

  1. Comprimento do arco: L = (π·R·θ)/180
  2. Com velocidade linear v (mm/s), o tempo é t = L / v (s)
  3. Taxa de giro constante = θ / t (°/s)
from math import pi

def curva_por_raio(robot, R_mm, theta_graus, v_mm_s=180):
    if R_mm <= 0:
        raise ValueError("Raio deve ser > 0")
    L = (pi * R_mm * theta_graus) / 180    # arco em mm
    t_s = abs(L / v_mm_s)                  # duração em segundos
    turn_deg_s = theta_graus / t_s         # taxa de giro em °/s (sinal controla direção)

    robot.drive(v_mm_s * (1 if theta_graus >= 0 else 1), turn_deg_s)
    from pybricks.tools import wait
    wait(int(t_s * 1000))
    robot.stop(Stop.BRAKE)

# Exemplo: curva de 60° num raio de 140 mm
curva_por_raio(robot, R_mm=140, theta_graus=60, v_mm_s=160)

Ajuste v_mm_s para ganhar precisão (menor = mais preciso). Se a curva ficar “fechada/aberta” demais, ajuste o raio ou o axle_track do robô.

5) Suavizando entradas e saídas de curva

Entrar e sair de curvas de forma brusca pode causar derrapagem. Use uma pequena “rampa” de giro:

robot.drive(180, 0)         # inicia reto
for k in range(0, 46, 5):   # rampa até 45°/s
    robot.drive(180, k)
    wait(60)

wait(600)                   # mantém curva por 0,6s

for k in range(45, -1, -5): # rampa de saída
    robot.drive(180, k)
    wait(60)

robot.stop(Stop.BRAKE)

6) Curvas por sequência (micro-turns)

Outra técnica é intercalar pequenos trechos retos e giros parciais para “desenhar” uma curva:

for _ in range(6):
    robot.straight(60)
    robot.turn(10)     # 6×(60mm + 10°) ≈ arco suave
robot.stop(Stop.HOLD)
Quando usar: útil em mesas emborrachadas/irregulares, quando o drive() contínuo oscila; dá mais controle em pontos de checagem.

7) Ajustes finos e calibração

  • Reduza straight_speed e turn_rate para aumentar a precisão.
  • Garanta simetria mecânica (rodas bem fixas, peso balanceado, cabos sem puxar).
  • Recalibre wheel_diameter e axle_track se as curvas estiverem sempre “abrindo” ou “fechando”.
  • Se houver IMU disponível e estável, combine com correções leves em curvas longas.

Erros comuns

  • Curva muito rápida: derrapagem e ultrapassagem do alvo — reduza v e turn_rate.
  • Raio incoerente: valores de axle_track errados distorcem as curvas.
  • Parada errada: para precisão, finalize com Stop.HOLD quando necessário.

Atividade prática

  1. Implemente uma curva de 90° com R = 120 mm usando a função curva_por_raio.
  2. Repita a mesma curva com drive() + rampas de giro (entrada/saída) e compare a repetibilidade.
  3. Use a técnica de “micro-turns” para contornar um obstáculo desenhando um arco de ~180°.