Escolar Documentos
Profissional Documentos
Cultura Documentos
v1( t ) + v2 ( t ) v1( t ) − v2 ( t )
v( t ) = ( t ) =
2 b
d (i ) + d 2 (i ) d1 (i ) − d 2 (i )
d (i ) = 1 (i ) =
2 b
ESTIMATIVA DA POSE DO ROBÔ BASEADA NA
ODOMETRIA
(i )
x(i + 1) = x(i ) + d (i ) cos (i ) +
2
(i )
y(i + 1) = y(i ) + d (i ) sin (i ) +
2
(i +1) = (i ) + (i )
Trabalho Laboratorial #1 – Odometria e equações de movimento de um robô
Assinalado a vermelho podem ver o endereço IP com que o robô ficou depois
de se ligar à rede sem fios. Este endereço será diferente em todos os robôs.
Deve aparecer o quadro seguinte onde no item “Ports (COM & LPT)
poderemos ver a porta série, neste caso a COM4:
Introduzindo-se esse valor no campo “COM Port” e pressionando o botão
“Open” deveremos ter a ligação ao robô por cabo. Antes de efetuar esta
ligação deve fechar o programa Visual Studio Code” para que este liberte a
porta série.
ii) Escrever um valor para “PMW 1” e “PMW 2” na coluna “Write”, por exemplo
-30 e -30. Pressionar depois “Set PWM”.
iii) Pressionar “Set State” ao lado de “201”, colocando o robô no estado 201
que aplica ops valores de PWM nos motores. Para parar pressionar “Set
State” ao lado de “200”.
Usando os valores “Senc 1” e “Senc 2” calcule a constante que relaciona os
impulsos com a distância percorrida (ver equações da cinemática).
Para atuar no robô de alguma forma deve utilizar o código presente no ficheiro
“control.cpp” onde pode criar estados com as atuações pretendidas e, através do
programa no computador, colocar o robô nesse estado.
Será também útil ver o código presente no procedimento “real_loop”, dentro do ficheiro
main.cpp. Este código é executado periodicamente, a uma frequência muito elevada, e
chama os procedimentos e funções referidas anteriormente.
3. Controlo em malha fechada da velocidade de cada roda.
Encontre a relação média entre o valor do PWM aplicado e a velocidade linear do robô
em metros por segundo.
if (robot.control_mode == cm_pid) {
if (robot.v1ref != 0) {
robot.v1_PWM = PID1.calc(robot.v1ref, robot.v1e);
} else {
robot.v1_PWM = 0;
PID1.Se = 0;
}
if (robot.v2ref != 0) {
robot.v2_PWM = PID2.calc(robot.v2ref, robot.v2e);
} else {
robot.v2_PWM = 0;
PID2.Se = 0;
}
}
Como se pode observar para estados 200 a 255 o PWM enviado para o
motor é o determinado no “control(.)” em “comtrol.cpp” e para estados 0 a
199 o PWM é calculado com o controlador PID+FEEDFORWARD. Repare
que quando a referência de velocidade é zero se coloca o PWM e a variável
relacionada com a integração a zero. Isto porque, devido à zona morta do
motor é possível ter o motor parado com algum PWM o que não é desejável
(pode testar alterando o código). Desta forma o motor pára rapidamente
devido ao atrito. Noutras situações, pode não ser o mais adequado (por
exemplo querer manter o robô parado mesmo numa descida ou subida).
ii) Calcule para uma velocidade linear de 0,05 m/s qual o número de
impulso por ciclo que deve ter em cada roda. Introduza agora um
valor para o ganho, por exemplo Kp = 300. Observe o valor obtido em
regime permanente para os impulsos por ciclo para diferentes valores
de ganho. Repare que neste robô a diferente entre ter as rodas no ar
e pousadas não é significativa (não é sempre assim em todos os
robôs). Suba o ganho em passos de 300 a 500 e observe os
diferentes valores em regime permanente e as oscilações quando se
passa de uma referência 0 m/s para 0.05 m/s. Quando começar a
oscilar bastante anote o valor. Assuma um valor bastante mais baixo
(seja ¼ deste valor) para se ter uma boa margem de segurança.
iv) Introduza agora novamente o valor de Kf. Observe que agora temos
uma sobre elongação forte. Introduzindo um peque valor em Kd
(cerca de 10) diminui essa sobre elongação mas rapidamente
começa a gerar oscilações. Diminua a sobre elongação diminuindo
simultaneamente Ki e Kf.
a. Comece, por exemplo, por usar apenas os dois sensores de cada extremidade
e um novo estado 100.
b. Aumente a velocidade linear até ao limite máximo que conseguir sem que o robô
perca a linha.
c. Observando os valores das leituras dos sensores repare que existe uma
pequena zona na transição entre preto e branco que o sensor dá uma leitura
intermédia entre os valores de branco e preto. Usando este facto faça agora um
controlador que use o sensor do meio e siga a borda interior da linha,
5. Crie agora um estado 99 para apenas inicializar a posição e orientação do robô,
variáveis robot.x, robot.y e robot.theta no valor zero correspondente ao início da primeira
reta mais longa, ou seja estamos a considerar que o referencial cartesiano tem o eixo X
coincidente com essa reta e a origem nesse ponto. De seguida passa logo para o estado
100.
6. Aproveitando o facto de saber em que parte da pista está o robô pode, nas retas, ter
alguma certeza sobre o ângulo e uma das coordenadas, usando os impulsos apenas
para estimar a outra coordenada. Veja o procedimento “odometry” e actue em
conformidade.
7. Teste agora, em alguns estados, movimentar o robô sem usar a linha, ou seja, por
exemplo quando entrar num estado correspondente a uma curva, aplicar uma
velocidade linear e angular constantes e com um valor que leve o robô ao início da
próxima reta, ignorando os sensores de linha. Teste a sua eficiência tapando a linha
com uma folha.
9. Utilize o procedimento da alínea anterior para navegar em zonas sem linhas ou com
as linhas interrompidas.