RoboJackets / robocup-software

Georgia Tech RoboJackets Software for the RoboCup Small Size League
Apache License 2.0
183 stars 187 forks source link

Expose Kick Detection to Soccer as a whole #1245

Open JNeiger opened 5 years ago

JNeiger commented 5 years ago

It's in the vision filter rn, but we should expose this to make life easy for some of the plays

JNeiger commented 5 years ago
kylestach commented 5 years ago

@JNeiger, do you have thoughts or additional details on implementation for this?

JNeiger commented 5 years ago

I have a few hours tomorrow that I was going to at least get a partial implementation. At worst, it won't compile or be complete, but it'll have enough that someone else can easily pick up. If that doesn't happen I'll write it out fully what needs to happen by Monday.

kylestach commented 5 years ago

What does the scope of this look like? I was thinking about using it as a new member project.

JNeiger commented 5 years ago

It's basically building a little logic and tuning the kick director already made in the vision code. Then pulling the metrics we want (described above) into a system state like container. Then building a python wrapper around it for easy access

JNeiger commented 5 years ago

If you want to do that, I'll describe it much more detailed with specific references to where I was thinking of adding stuff

JNeiger commented 5 years ago

I'mma edit this throughout the day as I have free time.

Description

As we move towards event based and matric based transitions on plays, a nonzero amount rely on the detection of a kick. This feature is already built into the vision filter due to some technical reasons. The goal of this issue is to expose the detection to python as well as build in a few simple utilities for users.

Requirements

Design

Link to design document

Implementation Background

Inside the vision filter there are two classes that detect a ball being kicked. Specifically the fast and slow kick detectors. Fast measures the past three frames looking for a few key factors that resemble a strong kick, like large velocity Delta's. This is done to detect a kick as quickly as possible for shots and that short of thing. It will be very noisy in terms of accuracy so the configuration limits are set for only extremely strong kicks.

Slow is used to accurately measure kicks in general. It uses 5 ish frames from the camera to make it's decision verses the 3 from the fast detector. It takes into account robot positions near the ball as well as a few other factors.

In general, for a fast kick it is very likely that the fast kick detector will trigger, then the slow will trigger, for the exact same kick. Care must be taken to make sure they refer to the same kick event irl and preference should always be given to the slow kick detector if there is a disagreement.

Implementation Hints

https://github.com/RoboJackets/robocup-software/blob/76acbb477b622304890b9caac532d8b1032eee83/soccer/vision/camera/World.cpp#L161

This is the location of all the logic about understanding how kicks are detected. Each kick detector is run and the "best" option is taken and saved to a class wide variable for the bestKick.

This is run every single vision iteration in a separate thread from the main soccer loop.

https://github.com/RoboJackets/robocup-software/blob/76acbb477b622304890b9caac532d8b1032eee83/soccer/vision/VisionFilter.cpp#L85

This interacts with processor currently to push the latest camera frames to the vision submodule and to pull the latest position estimates to the rest of soccer.

https://github.com/RoboJackets/robocup-software/blob/76acbb477b622304890b9caac532d8b1032eee83/soccer/Processor.cpp#L203

Something similar will happen for the kick detector->vision->processor pipe line. The vision filter class will convert the specific objects inside the vision modules version of kick event into what will be the system state version (more on that in a second). The most annoying will be converting the world robot into being on either the yellow or blue team robot The specific processing should happen either in the vision kick event class or the vision filter class depending on the exact context. For example, the Boolean flag that's toggled for a single frame should be in the vision filter and toggled on calling to that specific getter function while kicking robot and that should be in the kick event since it doesn't relay on specific calls.

This data should be thrown into a plain old data object. It shouldn't actually be system state, but a new object that is called FieldMetrics or something that better represents the data inside the context class. It's better to have specific classes containing the data rather than some generic container variable.

Once it gets exposed much like system state inside the context class, we will want to provide python access to this. This is done through the robocup-py.cpp file. Just scroll down and basically copy paste the system state / debug drawer access and add a python function for every single thing in the requirements.

An easy way to test this is to create a testing python play that draws the info on the screen. You'll probably have to tune the kick detector config values to properly detect kicks only once on a single kick, but one that is done, everything should work out.

JNeiger commented 5 years ago

Do you want me to pound it out, or would you like to use it as an intro issue?

I can provide even more instructions as well

kylestach commented 5 years ago

Thank you so much! I think the level of detail you have should be plenty for an intro issue.