-
Notifications
You must be signed in to change notification settings - Fork 186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New gameplay passing #1644
New gameplay passing #1644
Changes from 7 commits
02a5b66
aeebbe4
cc59d58
c4105a6
41c02dc
352f9f2
01e4f41
3d56812
01ce151
0cdec0d
b172cf6
edecfe4
939eddf
7dd7a0d
09c45df
b3a0fdc
5d9eee2
adcc0a8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,9 @@ | |
import stp.action as action | ||
import numpy as np | ||
import stp.rc as rc | ||
from typing import Optional | ||
from rj_msgs.msg import RobotIntent, EmptyMotionCommand | ||
from rj_geometry_msgs.msg import Point | ||
|
||
|
||
class IKick(action.IAction, ABC): | ||
|
@@ -16,19 +19,22 @@ def done(self) -> bool: | |
class Kick(IKick): | ||
""" | ||
Kick action | ||
TODO: update with actions implementation | ||
""" | ||
def __init__(self, point: np.ndarray): | ||
self.point = point | ||
self.count = -1 | ||
#for stub | ||
|
||
def tick(self, robot: rc.Robot, ctx: action.Ctx) -> None: | ||
print('robot:', robot.id, 'kicking') | ||
self.count += 1 | ||
|
||
def done(self) -> bool: | ||
return self.count == 1 | ||
|
||
def fail(self): | ||
return False | ||
def __init__(self, robot_id:Optional[int]=None, chip:Optional[bool]=False, kick_speed:Optional[float]=255.0) -> None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You would want to lower the kick_speed here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
#TODO: Cahnge kick speed to use max_kick_speed param for default value | ||
HussainGynai marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self.robot_id = robot_id | ||
self.chip = chip | ||
self.kick_speed = kick_speed | ||
|
||
def tick(self, intent:RobotIntent) -> RobotIntent: | ||
new_intent = intent | ||
empty_command = EmptyMotionCommand() | ||
new_intent.motion_command.empty_command = [empty_command] | ||
intent.kick_speed = self.kick_speed | ||
new_intent.trigger_mode = 2 | ||
new_intent.shoot_mode = self.chip | ||
new_intent.is_active = True | ||
return new_intent | ||
|
||
def is_done(self, world_state:rc.WorldState) -> bool: | ||
return np.linalg.norm(world_state.ball.vel) > 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I really do not trust this condition at all... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I could make it check that the ball is going away from the kicking robot. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
"""This module contains the interface and action for receive.""" | ||
|
||
from abc import ABC, abstractmethod | ||
|
||
import stp.role as role | ||
import stp.action as action | ||
import stp.rc as rc | ||
import numpy as np | ||
from rj_msgs.msg import RobotIntent, SettleMotionCommand | ||
|
||
class Receive(action.IAction): | ||
""" | ||
Receive action | ||
""" | ||
|
||
def __init__(self, robot_id: int = None, one_touch_target:np.ndarray = None): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For a vanilla receive we don't need one touch target. There should be a separate action for one touches |
||
self.robot_id = robot_id | ||
self.one_touch_target = one_touch_target | ||
|
||
|
||
def tick(self, intent) -> None: | ||
settle_command = SettleMotionCommand() | ||
if self.one_touch_target is not None: | ||
settle_command.maybe_target = self.one_touch_target | ||
intent.motion_command.settle_command = [settle_command] | ||
intent.dribbler_speed = 1.0 | ||
intent.is_active = True | ||
|
||
return intent | ||
|
||
def is_done(self, world_state) -> bool: | ||
if np.linalg.norm(world_state.ball.vel) < 0.1: | ||
return True | ||
return False |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,53 @@ | ||||||
import stp.play as play | ||||||
import stp.tactic as tactic | ||||||
|
||||||
from rj_gameplay.tactic import pass_tactic | ||||||
import stp.skill as skill | ||||||
import stp.role as role | ||||||
from stp.role.assignment.naive import NaiveRoleAssignment | ||||||
import stp.rc as rc | ||||||
from typing import Dict, Generic, Iterator, List, Optional, Tuple, Type, TypeVar | ||||||
import numpy as np | ||||||
|
||||||
class PassPlay(play.IPlay): | ||||||
"""A play which lines up two robots, one on the right the one on the left | ||||||
kfu02 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
""" | ||||||
|
||||||
def __init__(self): | ||||||
self.target_point = np.array([1.0,1.0]) | ||||||
kfu02 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
self.pass_tactic = pass_tactic.Pass(self.target_point) | ||||||
self.role_assigner = NaiveRoleAssignment() | ||||||
|
||||||
|
||||||
def compute_props(self, prev_props): | ||||||
pass | ||||||
|
||||||
def tick( | ||||||
self, | ||||||
world_state: rc.WorldState, | ||||||
prev_results: role.assignment.FlatRoleResults, | ||||||
props, | ||||||
) -> Tuple[Dict[Type[tactic.SkillEntry], List[role.RoleRequest]], List[tactic.SkillEntry]]: | ||||||
# Get role requests from all tactics and put them into a dictionary | ||||||
role_requests: play.RoleRequests = {} | ||||||
if not self.pass_tactic.is_done(world_state): | ||||||
role_requests[self.pass_tactic] = self.pass_tactic.get_requests(world_state, None) | ||||||
else: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. delete this else |
||||||
pass | ||||||
# Flatten requests and use role assigner on them | ||||||
flat_requests = play.flatten_requests(role_requests) | ||||||
flat_results = self.role_assigner.assign_roles(flat_requests, world_state, prev_results) | ||||||
role_results = play.unflatten_results(flat_results) | ||||||
|
||||||
# Get list of all skills with assigned roles from tactics | ||||||
skill_dict = {} | ||||||
if not self.pass_tactic.is_done(world_state): | ||||||
skills = self.pass_tactic.tick(role_results[self.pass_tactic], world_state) | ||||||
skill_dict.update(role_results[self.pass_tactic]) | ||||||
else: | ||||||
skills = [] | ||||||
|
||||||
return (skill_dict ,skills) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
def is_done(self ,world_state): | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
lol just saw this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can directly click "Commit suggestion" on GH if you want, not sure if you were aware There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. bump |
||||||
return self.pass_tactic.is_done(world_state) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
from abc import ABC, abstractmethod | ||
|
||
import rj_gameplay.eval as eval | ||
import argparse | ||
import py_trees | ||
import sys | ||
import time | ||
import numpy as np | ||
from typing import Optional | ||
|
||
import stp.skill as skill | ||
import stp.role as role | ||
import stp.action as action | ||
from rj_gameplay.action import receive, capture | ||
from stp.skill.action_behavior import ActionBehavior | ||
from stp.skill.rj_sequence import RjSequence as Sequence | ||
import stp.rc as rc | ||
from rj_msgs import msg | ||
|
||
class IReceive(skill.ISkill, ABC): | ||
... | ||
|
||
|
||
""" | ||
A skill version of receive so that actions don't have to be called in tactics | ||
""" | ||
class Receive(IReceive): | ||
|
||
def __init__(self, | ||
robot:rc.Robot = None, | ||
one_touch_target:np.ndarray = None): | ||
|
||
self.robot = robot | ||
self.one_touch_target = one_touch_target | ||
if self.robot is not None: | ||
self.receive = receive.Receive(self.robot.id, self.one_touch_target) | ||
self.capture = capture.Capture(self.robot.id) | ||
else: | ||
self.receive = receive.Receive(self.robot, self.one_touch_target) | ||
self.capture = capture.Capture() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm confused by these constructors here. Why do we pass in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. self.robot is None is the else block so it works, I agree that it's confusing tho |
||
self.receive_behavior = ActionBehavior('Receive', self.receive) | ||
kylestach marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self.capture_behavior = ActionBehavior('Capture', self.capture) | ||
self.root = Sequence('Sequence') | ||
self.root.add_children([self.receive_behavior, self.capture_behavior]) | ||
self.root.setup_with_descendants() | ||
self.__name__ = 'receive skill' | ||
|
||
def tick(self, robot:rc.Robot, world_state:rc.WorldState): #returns dict of robot and actions | ||
self.robot = robot | ||
actions = self.root.tick_once(self.robot, world_state) | ||
return actions | ||
|
||
def is_done(self, world_state:rc.WorldState): | ||
return self.capture.is_done(world_state) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When will
robot_id
beNone
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when capture action is initialized we have to default all to None