Ana içeriğe geç

Görsel Servo ile Hedefleme

  1. Sadece bir limelight ve sürüş sisteminizi kullanarak robotunuzu doğru ve hızlı bir şekilde hedefleyebilirsiniz.
  2. Tüm bunlar 1 saatten kısa sürede gerçekleştirilebilir.

Yüksek kare hızlı görüntü takibi sayesinde, artık görüntü işleme hattını doğrudan robotunuzu veya kulenizi yönlendirmek için bir PID kontrol döngüsünde "sensör" olarak kullanmak mümkündür. Bu fikri test etmek için 2017 FRC robotumuza bir limelight ekledik ve sadece sürüş sistemini ve limelight tarafından raporlanan ağ tablosu verilerini kullanarak görüş hedeflerini hedeflemesini sağladık.

Bu örnekte, test adayımız colson tekerlekli 6 tekerlekli sürüş sistemine sahip 2017 FRC robotuydu. İşte bu testi yapmak için robota bir limelight eklediğimizin resmi.

CS_aim_limelight_mounted

Ardından sürücü joystick üzerindeki bir düğmeyi basılı tuttuğunda çalışacak kodu robota ekledik. Bu robot "tank" tarzı sürüş kullanıyordu, bu yüzden OperatorControl fonksiyonu sürüş sisteminin sol ve sağ taraflarını kontrol etmek için 'left_command' ve 'right_command' değerleri üretiyordu. Normal kontrol kodundan sonra, şöyle bir kod bloğu ekledik:

float Kp = -0.1f;  // Oransal kontrol sabiti

std::shared_ptr<NetworkTable> table = NetworkTable::GetTable("limelight");
float tx = table->GetNumber("tx");

if (joystick->GetRawButton(9))
{
float heading_error = tx;
steering_adjust = Kp * tx;

left_command+=steering_adjust;
right_command-=steering_adjust;
}

Başlangıçta, bu çoğunlukla işe yaradı. Düğmeyi basılı tuttuğunuzda robot otomatik olarak hedefin yönüne dönüyor. Hedefi hareket ettirirseniz, robot hedefi takip etmek için dönüyor. Ancak, gösterge panelindeki canlı video beslemesini kullanarak, büyük bir sorun olduğunu görebildik: Robot her zaman hedefle mükemmel şekilde hizalanmıyordu. Küçük hedefleri olan bazı oyunlarda (2016 ve 2017 gibi) bu yeterli olmayacaktı.

Şimdiye kadar uyguladığımız şey basit bir oransal kontrol döngüsüdür. Yön hatasını hesapladık ve bunu bir sabit ile çarptık, böylece hataya orantılı bir motor komutu oluşturduk. Hata sıfıra giderken, komutumuz da sıfıra gidecek. Sorun, robot dönmeye çalıştığında çok fazla sürtünme olmasıdır. Çok küçük komutlar robotu hiç döndürmeyecektir. Küçük açılarda, komut robotu hareket ettiremeyecek kadar küçük olabilir. Robotunuzun büyük bir hedefleme hatası ile başladığınızda hedefe iyi ulaştığını ancak çok yakından başlarsanız hiç hedefleyemediğini görebilirsiniz.

Bu sorunu çözmenin birkaç yolu var ama işte çok basit bir çözüm. "Minimum komut" kavramını kullandık. Hata belirli bir eşikten büyükse, motor komutunuza robotun gerçekten hareket etmesi için gereken minimum güç miktarını temsil eden sabit bir değer ekleyin (aslında bundan biraz daha azını kullanmak istersiniz). Yeni kod şöyle görünüyor:

float Kp = -0.1f;
float min_command = 0.05f;

std::shared_ptr<NetworkTable> table = NetworkTable::GetTable("limelight");
float tx = table->GetNumber("tx");

if (joystick->GetRawButton(9))
{
float heading_error = -tx;
float steering_adjust = 0.0f;
if (Math.abs(heading_error) > 1.0)
{
if (heading_error < 0)
{
steering_adjust = Kp*heading_error + min_command;
}
else
{
steering_adjust = Kp*heading_error - min_command;
}
}
left_command += steering_adjust;
right_command -= steering_adjust;
}

Dikkat edin, eğer Kp veya min_command değerini çok yüksek ayarlarsanız, robotunuz dengesiz hale gelebilir ve hedefi aşarken ileri geri salınım yapabilir:

CS_aim_bad

Kp ve min_command üzerinde biraz ayarlama yaptıktan sonra robotunuz hedefe çok doğru ve hızlı bir şekilde nişan almalıdır.

CS_aim_good