Skip to content
This repository has been archived by the owner on Mar 7, 2021. It is now read-only.

Latest commit

 

History

History
201 lines (190 loc) · 7 KB

3.org

File metadata and controls

201 lines (190 loc) · 7 KB

Skills, Tactics, Plays - Beginner

Skills, Tactics, Plays - 2 {#t20163}

Questions about Plays?

  • Last meeting was pretty dense
    • We NEED to have 1 on 1 time with each of you, so it is your responsibility to waive us over if you’re stuck!
  • Topics Covered:
    • Python
    • State Machines
    • Play/Skill/Tactic Structure
  • And today, we’re going into…

Additional Information

  • See the previous slide deck and docs for more information, they should be a pretty comprehensive overview of our play system.

Subbehaviors!

  • A Behavior is a generic name for any skill, play, or tactic.
  • Last meeting we learned about Plays/Skills/Tactics
    • How do we put them together?
  • Subbehaviors allow you to reuse our behaviors in many plays.
    • Example: We have one move play, used by kicker tactics, passing tactics, goalie, etc.

Examples of Subbehaviors

  • Offense Play contains Passing Tactics, and Move Skills
  • Passing Tactic Contains Move and Kick Skills

Behavior Tree!

Basic122::running
    Mark::running[robot=4]
        move(0.767296, 6.51286)
        endVelocity(0, 0)
        face(0.160718, 9.15305)
    PivotKick::capturing
        Capture::course_approach[robot=2]
            face(0.160718, 9.15305)
            avoidBall(-1)
            move(0.176939, 9.114)
            endVelocity(0, 0)
    Mark::running[robot=1]
        move(-0.829012, 6.03814)
        endVelocity(0, 0)
        face(0.160718, 9.15305)

Details

  • Here we have a tree of all the behaviors running
  • We have a basic122 play running
  • It is running 2 Marks, and a PivotKick in this frame
  • The marks are directly running robot commands, like move, and face.
  • The PivotKick is running a capture skill, which is running robot commands, like face, move, etc.

Behavior Tree! (cont.)

Basic122::running
    Defense::defending
        SubmissiveDefender::marking
            Move::completed[robot=5]
                face(0.160718, 9.15305)
        SubmissiveDefender::marking
            Move::completed[robot=3]
                face(0.160718, 9.15305)
        SubmissiveGoalie::block
            Move::running[robot=0]
                face(0.160718, 9.15305)
                move(0.290916, 0.14)
                endVelocity(0, 0)

Details

  • Pretty much same thing here
  • We’ve got a Defense tactic running, with SubmissiveDefender and Goalie Skills
  • These skills actually run robot commands.

How do I use subbehaviors?

Adding Subbehaviors

self.add_subbehavior(skill_object,
                     "Name of Subbehavior",
                     required=False or True
                     priority=10) # A higher number is higher priority

Details

  • For more docs on this entire section see this link.
  • These subbehaviors show up in the behavior tree when you run your program.
  • This can be extremely useful when debugging state transitions or subbehavior assignments.

Removing Subbehaviors

self.remove_subbehavior('string name')

self.remove_all_subbehaviors()

Getting Subbehavior Plays

a_subbheavior = self.subbehavior_with_name('string name')

Real Examples

CoordinatedPass Tactic

def on_enter_running(self):
    receiver = skills.pass_receive.PassReceive()
    receiver.receive_point = self.receive_point
    self.add_subbehavior(receiver,
                         'receiver',
                         required=self.receiver_required)

def on_exit_running(self):
    self.remove_subbehavior('receiver')

Line Up Tactic

  • First State Machine is set up, then:
# Triggered whenever the line changes
self.remove_all_subbehaviors()
for i in range(6):
    pt = self._line.get_pt(0) + (self.diff * float(i))
    self.add_subbehavior(
        skills.move.Move(pt),
        name="robot" + str(i),
        required=False,
        priority=6 - i)
def execute_running(self):
    for i in range(6):
        pt = self._line.get_pt(0) + (self.diff * float(i))
        self.subbehavior_with_name("robot" + str(i)).pos = pt

RoboCup Pro Tip

  • Find some code doing something like what you want
  • Tweak it until it works
  • It’s less effective than working everything out, but it’s great for beginners!

How do I get MY Robot?!?

Dynamic Assignment

  • Our role assignment system picks the best robot for the task
  • You define your constraints, and we’ll give you a robot if we can!
  • It’s also some black magic…

But I want Robot X!

  • Override Role Requirements to add your constraints!
  • This next section is Extra Credit…
    • And it’s a massive oversimplification
    • See role_assignment.py for more information.

Get the closest robot

# From Move
def role_requirements(self):
    reqs = super().role_requirements()
    # Destination Shape is used for distances to points or segments
    reqs.destination_shape = self.pos
    return reqs

Get the robot with all the hardware

def role_requirements(self):
    reqs = super().role_requirements()
    reqs.require_kicking = True
    # try to be near the ball
    if main.ball().valid:
        reqs.destination_shape = main.ball().pos
    return reqs

I really, really, want MY Robot!

# From Goalie
def role_requirements(self):
    reqs = super().role_requirements()

    # This iteration is needed if we have
    # subbehaviors we want to have applied as well.
    for req in role_assignment \
        .iterate_role_requirements_tree_leaves(reqs):

        req.required_shell_id \
            = self.shell_id if self.shell_id != None else -1
    return reqs

Assignment

  • Create a binary clock play
  • Display the current minute in binary on the field
    • Use a robot to represent a 1, and lack of a robot to represent a 0
  • Starter code is in soccer/gameplay/plays/skel/binary_clock.py.
  • Move it to soccer/gameplay/plays/training to begin.

Tips

import time
mins =  time.localtime().tm_min
binary = format(mins, '06b')
print(binary)
# Index with binary[0-6]
# THIS INDEX IS A CHARACTER VALUE, NOT AN INT
# USE == '1', not == 1

#+RESULTS[2cdccf696e363d1f51ce50c0b895bf17a58a9b55]:

010011