Ana içeriğe geç

Görsel Servo ile Nişan Alma

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

Yüksek kare hızlı görüş takibi kullanarak, artık robotunuzu veya taretinizi yönlendirmek için görüş hattını doğrudan 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 tahrik sistemi ile limelight tarafından raporlanan network table verilerini kullanarak görüş hedeflerine nişan almasını sağladık.

Bu örnekte, test adayımız colson tekerlekli 6 tekerlekli tahrik sistemi kullanan bir 2017 FRC robotuydu. İşte bu testi yapmak için robota limelight eklerken çektiğimiz bir fotoğraf.

CS_aim_limelight_mounted

Ardından, sürücü joystick üzerindeki bir düğmeyi basılı tuttuğunda çalışacak bir kod ekledik. Bu robot "tank" tarzı sürüş kullandığından, OperatorControl fonksiyonu tahrik sisteminin sol ve sağ taraflarını kontrol etmek için bir 'left_command' değeri ve bir 'right_command' değeri ü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;
}

İlk denemede bu büyük ölçüde çalıştı. Düğmeyi basılı tuttuğunuzda robot otomatik olarak hedef yönüne dönüyor. Hedefi hareket ettirirseniz, robot hedefi takip etmek için dönüyor. Ancak, dashboard üzerindeki canlı video akışını kullanarak büyük bir sorun olduğunu gördük: Robot her zaman hedefle mükemmel hizalanmayı başaramıyordu. Küçük hedeflerin olduğu bazı oyunlarda (2016 ve 2017 gibi) bu yeterli olmayacaktı.

Şu ana kadar uyguladığımız basit bir oransal kontrol döngüsüdür. Yön hatasını hesapladık ve bunu bir sabitle çarptık, böylece hataya orantılı bir motor komutu oluşturduk. Hata sıfıra yaklaştıkça, komutumuz da sıfıra gidecektir. Sorun şu ki, robot dönmeye çalışırken çok fazla sürtünme var. Çok küçük komutlar robotu hiç döndürmeyecektir. Küçük açılarda, komut robotu gerçekten hareket ettiremeyecek kadar küçük olabilir. Büyük bir nişan hatasıyla başladığınızda robotunuzun hedefine iyi ulaştığını, ancak gerçekten yakın başladığınızda hiç nişan alamadığını görebilirsiniz.

Bu sorunu çözmenin birkaç yolu var ama işte gerçekten 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ücü kabaca temsil eden bir sabit 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, Kp veya min_command'ı çok yüksek ayarlarsanız, robotunuz kararsız 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 robotunuzun hedefe çok doğru ve hızlı bir şekilde nişan almasını sağlamalısınız.

CS_aim_good