Tutorial · Intermediário · 40 min
Perfis de movimento: aceleração trapezoidal e curva em S
Por que um comando de posição faz com que motores percam passos e máquinas batam, como um perfil trapezoidal corrige isso e quanto uma curva em S custa.
Introdução
Diga a um motor para ir até uma posição e ele tentará chegar imediatamente. Não rapidamente — imediatamente. O comando não contém nenhuma informação sobre a velocidade, portanto a única interpretação disponível é “o mais rápido possível”, e o que acontece em seguida é decidido pelo primeiro recurso que acaba: torque, limite de corrente, tração ou a capacidade do motor de passo acompanhar.
Um perfil de movimento é a informação que falta. Ele transforma “vá até 100 mm” em um cronograma — onde o eixo deve estar em cada instante entre agora e a chegada — e entrega ao controlador uma referência que se move a uma velocidade que a máquina realmente consegue executar.
Esta é a diferença entre um braço de robô que chega e um que chega e para de tremer.
O que um comando de posição puro realmente pede
Considere um degrau: em t = 0, a referência salta de 0 mm para 100 mm.
Para seguir isso exatamente, o eixo precisaria de velocidade infinita, o que exige aceleração infinita, o que exige força infinita. Como isso não é possível, alguma coisa cede:
- Um motor de passo recebe uma taxa de passos que seu torque não consegue produzir naquela velocidade, sofre perda de passo e — operando em malha aberta — não tem ideia de que isso aconteceu. A posição agora está permanentemente errada. Entenda por que isso acontece e por que sempre são quatro passos de cada vez.
- Um motor CC com um loop PID vê um erro instantâneo enorme, satura a saída, acumula o termo integral e ultrapassa a referência.
- Um servo dispara para sua taxa máxima e chega com todo o mecanismo ainda em movimento.
Nada disso é um problema de ajuste. Todas são o mesmo problema: o comando era fisicamente impossível.
O perfil trapezoidal
A correção é comandar velocidade e alterá-la a uma taxa que o motor consiga sustentar. Acelere a uma taxa constante até uma velocidade de cruzeiro, mantenha-a e depois desacelere na mesma taxa. Plote a velocidade em função do tempo e você verá um trapézio, de onde vem o nome.
Três números o definem: a distância d, a velocidade máxima v_max e a aceleração a.
t_accel = v_max / a time spent ramping
d_accel = v_max² / (2a) distance used by one ramp
t_total = v_max / a + d / v_max whole move, if it reaches v_max
Para um movimento de 100 mm a 100 mm/s com a = 500 mm/s²: cada rampa leva 0,2 s e percorre 10 mm, deixando 80 mm de cruzeiro, para um total de 1,2 s.
Aqui está tudo em função do tempo — a posição que seu loop de controle deve perseguir no instante t:
// Target position t seconds into a trapezoidal move of `d` mm.
float profilePosition(float t, float d, float vMax, float a) {
float tAcc = vMax / a;
float dAcc = vMax * vMax / (2 * a);
if (2 * dAcc > d) { // too short to reach vMax
float tPeak = sqrtf(d / a); // triangular profile
if (t >= 2 * tPeak) return d;
if (t < tPeak) return 0.5f * a * t * t;
float left = 2 * tPeak - t;
return d - 0.5f * a * left * left;
}
float tCruise = (d - 2 * dAcc) / vMax;
float tTotal = 2 * tAcc + tCruise;
if (t >= tTotal) return d;
if (t < tAcc) return 0.5f * a * t * t;
if (t < tAcc + tCruise) return dAcc + vMax * (t - tAcc);
float left = tTotal - t;
return d - 0.5f * a * left * left;
}
Observe o que essa função não é: ela não é um controlador. Ela gera um valor de referência. O controlador que você já tinha — um agendador de passos de motor de passo, um loop PID ou uma escrita de servo — continua fazendo o que fazia. O perfil só muda aquilo que está sendo seguido.
O movimento solicitado nem sempre é o movimento obtido
O ramo 2 * dAcc > d é o primeiro caso com que as pessoas se deparam e que costumam diagnosticar errado.
Se o movimento for mais curto que a distância necessária para acelerar e desacelerar novamente, o eixo nunca alcança a velocidade configurada. A velocidade cresce linearmente até seu pico no ponto médio do movimento e, em seguida, decresce linearmente, formando um triângulo. A curva de posição não é triangular: ela é formada por dois segmentos parabólicos que se encontram com posição e velocidade contínuas.
O limite é d < v_max² / a. Para os números acima, isso dá 20 mm, então todo movimento menor que 20 mm atinge no máximo uma velocidade inferior a 100 mm/s, não importa o que você definir.
É por isso que aumentar v_max em uma máquina que faz muitos movimentos curtos não muda nada mensurável. Os movimentos nunca foram limitados por velocidade; eram limitados por aceleração. Uma impressora 3D que faz preenchimento denso é o exemplo do dia a dia.
Os cantos ainda são descontínuos
O perfil trapezoidal corrigiu a velocidade. Olhe para a aceleração e o problema apenas mudou de lugar.
Em t = 0, a aceleração salta de 0 para 500 mm/s² instantaneamente. No topo da rampa, ela volta a 0 instantaneamente. Cada uma dessas mudanças é um degrau na aceleração — e a taxa de variação da aceleração é o salto de aceleração (jerk); portanto, um degrau na aceleração corresponde a um impulso infinito de salto de aceleração.
Essa idealização não ocorre em uma máquina real; na prática, o movimento sofre:
- Um golpe audível no início e no fim de cada rampa.
- Ressonância — correias esticam, acoplamentos acumulam tensão e a estrutura tem complacência, então uma mudança repentina de força a excita e ela oscila depois. Em uma impressora, esse é o fantasma que aparece ao lado de detalhes nítidos.
- Picos de torque que fazem os limites de corrente dispararem, embora o torque médio indique que estavam dentro do aceitável.
A curva em S
Um perfil em curva em S limita o salto de aceleração, além de limitar a aceleração. Em vez de dar um degrau até a aceleração completa, ele faz rampa até ela durante um tempo de salto de aceleração t_j = a_max / j_max, mantém a aceleração e depois faz a rampa de saída. A curva de velocidade ganha cantos arredondados — daí o nome — e a aceleração se torna um trapézio por si só.
Um movimento completo em curva em S tem sete fases: rampa de entrada do salto de aceleração, aceleração constante, rampa de saída do salto de aceleração, cruzeiro e as três fases espelhadas para desacelerar e parar.
O custo: exatamente um t_j
Esta é a parte que vale memorizar, porque torna concreta a troca.
Quando os dois perfis alcançam o mesmo v_max e o mesmo a_max, o movimento em curva em S leva exatamente um t_j a mais — um tempo de salto de aceleração, não dois, independentemente da distância do movimento:
trapezoidal T = v_max/a + d/v_max
S-curve T = v_max/a + d/v_max + t_j where t_j = a_max / j_max
Para o movimento do exemplo: 1,2 s se tornam 1,3 s. Uma penalidade de 8% neste movimento e uma porcentagem menor em movimentos mais longos, em troca de um salto de aceleração limitado.
O motivo de ser um, e não dois: o segmento de aceleração da curva em S é mais longo, portanto percorre mais distância antes de chegar à velocidade de cruzeiro, encurta a fase de cruzeiro e devolve quase todo o tempo. Só o tempo de salto de aceleração em si é irrecuperável.
Há uma restrição escondida aí. A aceleração só alcança a_max se v_max ≥ a_max² / j_max. Abaixo disso, o movimento também nunca alcança a aceleração completa, e você obtém um perfil de aceleração triangular — a mesma história de “ficou sem distância”, uma derivada acima.
O que o firmware da impressora chama de jerk
Vale saber antes de começar a ajustar qualquer coisa, porque o vocabulário induz ativamente ao erro.
O DEFAULT_XJERK clássico do Marlin não é a derivada da aceleração. É a mudança instantânea máxima de velocidade permitida em uma junção entre dois movimentos, em mm/s — uma tolerância de curva que permite ao planejador fazer uma curva sem desacelerar até zero. É útil, mas é outra grandeza, com o nome e as unidades errados.
Os padrões mais recentes do Marlin usam Junction Deviation, que modela a curva como um arco com um desvio especificado, em mm. O Klipper usa square_corner_velocity — a velocidade com que uma curva de 90° é percorrida. As três respondem a “como faço para não parar em cada canto?”, e nenhuma delas é um limite de salto de aceleração no sentido físico.
Portanto, se uma publicação em um fórum disser para reduzir o jerk para parar a ressonância, verifique qual grandeza está sendo indicada. Reduzir a velocidade de junção reduz o choque nas curvas; não limita da/dt dentro de um único movimento.
Seu PID provavelmente está bom
Se você tem um eixo em malha fechada que ultrapassa a referência e oscila em todos os movimentos, o instinto é desajustá-lo — diminuir Kp, adicionar ação derivativa e combater a ultrapassagem.
Primeiro, aplique um perfil à referência.
Uma entrada em degrau pede uma saída infinita ao controlador PID. Seu termo de erro começa na distância total do movimento, o termo derivativo vê um salto instantâneo e o termo integral acumula enquanto a saída está saturada e o eixo não pode responder. Desajustar o controlador o torna lento em todo lugar para sobreviver a um único instante impossível.
Com um perfil, o erro permanece pequeno durante todo o movimento, porque a referência fica em algum lugar que o eixo realmente consegue alcançar. Os mesmos ganhos que eram inutilizáveis contra um degrau muitas vezes se comportam bem contra uma rampa — e agora o controlador está apenas corrigindo carga e atrito, que é para isso que ele serve. Você pode observar a diferença no simulador de PID comparando uma referência em degrau com uma gradual.
Onde você encontra isso em um robô real
- Motores de passo. As chamadas
setMaxSpeed()esetAcceleration()do AccelStepper fornecem um perfil trapezoidal e nada mais. Não há opção de curva em S; para isso, gere a referência você mesmo. - Servos hobby. Um SG90 tem um controlador interno que você não pode ver nem ajustar; portanto, aplicar um perfil significa comandar o ângulo gradualmente em vez de escrever a referência em uma única chamada — a mesma ideia aplicada por fora.
- Motores CC com encoders. Aplique um perfil à referência de posição e deixe o loop PID do encoder segui-la. Este é o arranjo em que aplicar um perfil mais compensa.
- Robôs móveis. O mesmo limite se aplica a
linear.xem uma ponte cmd_vel: comandar um degrau de velocidade faz as rodas derraparem, o que corrompe a odometria. Limite a taxa de variação do comando de movimento. - Impressoras e CNC. Marlin, Klipper e GRBL planejam movimentos trapezoidais com uma regra de passagem entre eles.
Quando dá errado
| Sintoma | Causa usual |
|---|---|
| O motor de passo perde a posição sob carga, silenciosamente | Não há perfil — a taxa comandada excede o torque de arranque |
| A máquina bate no início e no fim dos movimentos | Impulso de salto de aceleração no perfil trapezoidal; precisa de curva em S ou aceleração menor |
| Ressonância ao lado de detalhes nítidos | Ressonância estrutural excitada por degraus de aceleração |
| Movimentos curtos ignoram a configuração de velocidade | Perfil triangular — limitado por aceleração, não por velocidade |
| Ultrapassagem e oscilação em todos os movimentos | Referência em degrau em uma malha fechada; aplique um perfil antes de reduzir os ajustes |
| Aumentar a aceleração ajuda e depois de repente deixa de ajudar | Agora o limite é o torque, não o perfil |
| A odometria deriva muito durante as partidas | Derrapagem das rodas causada por um degrau de velocidade; limite a taxa do comando |
Aplicar um perfil de movimento é a maior melhoria barata disponível para a maioria dos sistemas de movimento hobby, porque custa uma função e nenhum componente adicional. O simulador de braço de robô é um bom lugar para entender por que isso importa no fim de um elo longo, onde um pequeno degrau de aceleração na base se transforma em uma oscilação visível na pinça. Em um robô móvel, o mesmo perfil é o que permite que um seguidor de caminho diminua a velocidade para uma curva mais fechada que seu raio de giro, em vez de falhar ao segui-la.
Explore o grafo
Faz parte destas montagens
Projetos e caminhos de aprendizagem que incluem este tutorial.
- ProjetoConstrua um plotter de caneta cartesiano de dois eixos
- ProjetoConstrua um robô de coleta e colocação que sabe quando falhou
- Caminho de aprendizagemAcionamento holonômico: mover-se de lado sem girar
- Caminho de aprendizagemControle de motores para robôs: roteiro de aprendizagem
- Caminho de aprendizagemMovimento preciso com motores de passo: roteiro de aprendizagem
- Caminho de aprendizagemPreensão e efetuadores finais: como realmente pegar o objeto
- Caminho de aprendizagemSeguimento de caminhos para robôs: roteiro de aprendizagem
Leitura complementar