Commit 85a0d4aa authored by drallensmith's avatar drallensmith

Revise feedback with enum, use of ACTION_STATUS_UNKNOWN when appropriate

parent 2be132c1
No preview for this file type
......@@ -622,13 +622,13 @@ Team. unum invalid & Y & Y & Y & Y & Y & Y & Y & Y & Y & Y & N &
Opponent loc invalid & Y & Y & Y & Y & Y & Y & Y? & Y & N & Y? & Y & Y? & Y & Y & Y & Y & N \\
Opp. unum invalid & Y & Y & Y & Y & Y & Y & Y & Y & Y & Y & Y & Y & Y & Y & Y & Y & N \\
\hline
Ball kickable & Y & Y & Y & Y & Y & Y & Y & ? & * & Y & Y & Y & Y & ? & ? & ? & Y \\
Ball kickable & Y & Y & Y & Y & Y & Y & Y & N & * & Y & Y & Y & Y & ? & ? & N & Y \\
Ball not kickable & Y & Y & Y & N & N & Y & Y & Y & Y & N & N & N & Y & Y & Y & Y & Y \\
\hline
Frozen & N & N & N & N & N & N & N? & N & N? & N & N & Y & N? & N & N & N & N \\
Colliding w/ball & Y & Y & ? & ? & ? & Y? & ? & ? & ? & ? & ? & ? & ? & ? & ? & ? & ? \\
Colliding w/ball & Y & Y & ? & N & Y & Y & Y & Y & ? & ? & ? & ? & ? & ? & ? & N & ? \\
Colliding w/player & Y & Y? & ? & N? & N? & Y? & ? & Y? & ? & ? & ? & Y? & ? & ? & ? & Y? & ? \\
Colliding w/post & Y & Y & N? & N? & N? & Y & ? & Y & ? & ? & ? & ? & ? & ? & ? & Y & ? \\
Colliding w/post & Y & Y & N? & N? & N? & Y & Y & Y & Y & ? & ? & Y & ? & Y & Y & Y & Y \\
\hline
Offense & Y & Y & N & Y & Y & Y & Y & Y & Y & Y & Y & Y & N & N & N & Y & N \\
Defense, not goalie & Y & Y & Y & N? & N? & Y & N & Y & Y & N & N & N & N & Y & ? & Y & Y \\
......
......@@ -284,7 +284,7 @@ def get_abs_x_y_pos(abs_angle, dist, self_x_pos, self_y_pos, warn=True, of_what=
if dist < 10:
raise RuntimeError("\n".join(error_strings))
else:
if warn or (dist < 60):
if warn or (dist < 50):
print("\n".join(error_strings), file=sys.stderr)
sys.stderr.flush()
return (None, None)
......@@ -641,9 +641,36 @@ def evaluate_previous_action(hfo_env,
action_status_observed = hfo.ACTION_STATUS_UNKNOWN # NOTE: Check intent + other bitflags!
if namespace.action == hfo.DASH:
if (namespace.intent !=
INTENT_GOAL_COLLISION) and namespace.prestate_bit_list[3] and (not bit_list[3]):
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent !=
INTENT_BALL_COLLISION) and namespace.prestate_bit_list[2] and (not bit_list[2]):
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent == INTENT_BALL_KICKABLE) and (not namespace.prestate_bit_list[4]) and bit_list[4]:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent == INTENT_GOAL_COLLISION) and (not namespace.prestate_bit_list[3]) and bit_list[3]:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent == INTENT_BALL_COLLISION) and (((not namespace.prestate_bit_list[2]) and bit_list[2]) or
((not namespace.prestate_bit_list[4]) and bit_list[4])):
action_status_observed = hfo.ACTION_STATUS_MAYBE
else:
pass # TODO
elif namespace.action == hfo.TURN:
if (namespace.prestate_self_dict['body_angle'] is not None) and (self_dict['body_angle'] is not None):
if (namespace.intent !=
INTENT_GOAL_COLLISION) and namespace.prestate_bit_list[3] and (not bit_list[3]):
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent !=
INTENT_BALL_COLLISION) and namespace.prestate_bit_list[2] and (not bit_list[2]):
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent == INTENT_BALL_KICKABLE) and (not namespace.prestate_bit_list[4]) and bit_list[4]:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent == INTENT_GOAL_COLLISION) and (not namespace.prestate_bit_list[3]) and bit_list[3]:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent == INTENT_BALL_COLLISION) and (((not namespace.prestate_bit_list[2]) and bit_list[2]) or
((not namespace.prestate_bit_list[4]) and bit_list[4])):
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.prestate_self_dict['body_angle'] is not None) and (self_dict['body_angle'] is not None):
intended_body_angle = namespace.prestate_self_dict['body_angle'] + namespace.action_params[0]
if get_angle_diff(namespace.prestate_self_dict['body_angle'],
intended_body_angle) > get_angle_diff(self_dict['body_angle'],
......@@ -652,6 +679,14 @@ def evaluate_previous_action(hfo_env,
else:
action_status_observed = hfo.ACTION_STATUS_BAD
elif namespace.action == hfo.KICK:
if bit_list[4]:
if namespace.prestate_bit_list[2] and (not bit_list[2]):
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif namespace.prestate_bit_list[3] and (not bit_list[3]):
action_status_observed = hfo.ACTION_STATUS_MAYBE
else:
action_status_observed = hfo.ACTION_STATUS_BAD
else:
pass # TODO
elif namespace.action == hfo.KICK_TO:
if (namespace.prestate_ball_dict['x_pos'] is not None) and (ball_dict['x_pos'] is not None):
......@@ -665,10 +700,30 @@ def evaluate_previous_action(hfo_env,
namespace.action_params[1])
if dist_before > dist_after:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif bit_list[4]:
if namespace.prestate_bit_list[2] and (not bit_list[2]):
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif namespace.prestate_bit_list[3] and (not bit_list[3]):
action_status_observed = hfo.ACTION_STATUS_MAYBE
else:
action_status_observed = hfo.ACTION_STATUS_BAD
else:
action_status_observed = hfo.ACTION_STATUS_BAD
elif namespace.action == hfo.MOVE_TO:
if (namespace.prestate_self_dict['x_pos'] is not None) and (self_dict['x_pos'] is not None):
if (namespace.intent !=
INTENT_GOAL_COLLISION) and namespace.prestate_bit_list[3] and (not bit_list[3]):
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent !=
INTENT_BALL_COLLISION) and namespace.prestate_bit_list[2] and (not bit_list[2]):
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent == INTENT_BALL_KICKABLE) and (not namespace.prestate_bit_list[4]) and bit_list[4]:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent == INTENT_GOAL_COLLISION) and (not namespace.prestate_bit_list[3]) and bit_list[3]:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent == INTENT_BALL_COLLISION) and (((not namespace.prestate_bit_list[2]) and bit_list[2]) or
((not namespace.prestate_bit_list[4]) and bit_list[4])):
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.prestate_self_dict['x_pos'] is not None) and (self_dict['x_pos'] is not None):
dist_before = get_dist_real(namespace.prestate_self_dict['x_pos'],
namespace.prestate_self_dict['y_pos'],
namespace.action_params[0],
......@@ -685,6 +740,10 @@ def evaluate_previous_action(hfo_env,
if namespace.prestate_bit_list[4]:
if not bit_list[4]:
action_status_observed = hfo.ACTION_STATUS_BAD
elif namespace.prestate_bit_list[3] and (not bit_list[3]): # goal collision
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif namespace.prestate_bit_list[2] and (not bit_list[2]): # ball collision
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.prestate_self_dict['x_pos'] is not None) and (self_dict['x_pos'] is not None):
dist_before = get_dist_real(namespace.prestate_self_dict['x_pos'],
namespace.prestate_self_dict['y_pos'],
......@@ -700,6 +759,10 @@ def evaluate_previous_action(hfo_env,
action_status_observed = hfo.ACTION_STATUS_BAD
elif bit_list[4]:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif namespace.prestate_bit_list[3] and (not bit_list[3]): # goal collision
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif namespace.prestate_bit_list[2] and (not bit_list[2]): # ball collision
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif namespace.prestate_ball_dict['dist'] > ball_dict['dist']:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif namespace.prestate_ball_dict['dist'] < ball_dict['dist']:
......@@ -709,11 +772,20 @@ def evaluate_previous_action(hfo_env,
elif (namespace.action == hfo.INTERCEPT) or (namespace.action == hfo.GO_TO_BALL):
if namespace.prestate_bit_list[4]:
if bit_list[4]:
if (namespace.intent != INTENT_BALL_COLLISION) and bit_list[2]:
action_status_observed = hfo.ACTION_STATUS_BAD
elif (namespace.intent != INTENT_GOAL_COLLISION) and bit_list[3]:
action_status_observed = hfo.ACTION_STATUS_BAD
else:
action_status_observed = hfo.ACTION_STATUS_MAYBE
else:
action_status_observed = hfo.ACTION_STATUS_BAD
elif bit_list[4]:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif namespace.prestate_bit_list[3] and (not bit_list[3]): # goal collision
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif (namespace.intent == INTENT_BALL_COLLISION) and (not namespace.prestate_bit_list[2]) and bit_list[2]:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif namespace.prestate_ball_dict['dist'] > ball_dict['dist']:
action_status_observed = hfo.ACTION_STATUS_MAYBE
elif namespace.prestate_ball_dict['dist'] < ball_dict['dist']:
......@@ -759,13 +831,15 @@ def evaluate_previous_action(hfo_env,
namespace.struct_tried[pack_action_bit_list(namespace.action,namespace.prestate_bit_list)] += 1
# further analysis...
if action_status_guessed == hfo.ACTION_STATUS_MAYBE:
# further analysis...
if namespace.prestate_bit_list[3] and (namespace.action in (hfo.DASH, hfo.MOVE_TO)) and (action_status_guessed == hfo.ACTION_STATUS_MAYBE):
if namespace.prestate_bit_list[3] and (namespace.action in (hfo.KICK, hfo.KICK_TO)):
print("OK status from {0!s} despite goal collision in prestate (poststate: {1!s})".format(
action_string, bit_list[3]))
sys.stdout.flush()
if namespace.prestate_bit_list[2] and (namespace.action in (hfo.DASH, hfo.TURN, hfo.MOVE_TO)) and (action_status_guessed == hfo.ACTION_STATUS_MAYBE):
if namespace.prestate_bit_list[2] and (namespace.action in (hfo.KICK, hfo.MOVE_TO,
hfo.GO_TO_BALL)):
print("OK status from {0!s} despite ball collision in prestate (poststate: {1!s})".format(
action_string, bit_list[2]))
sys.stdout.flush()
......@@ -886,6 +960,8 @@ def do_intent(hfo_env,
poss_actions_list.append(hfo.TURN)
if abs(ball_rel_angle) < 1.0:
poss_actions_list.append(hfo.DASH)
if bit_list[0] and (ball_dict['x_pos'] is not None):
poss_actions_list.append(hfo.MOVE_TO)
action = determine_which_action(poss_actions_list, namespace, bit_list)
......@@ -899,6 +975,11 @@ def do_intent(hfo_env,
hfo_env.act(*save_action_prestate(action=hfo.DASH,
action_params=[80, ball_rel_angle],
**prestate_dict))
elif action == hfo.MOVE_TO:
hfo_env.act(*save_action_prestate(action=hfo.MOVE_TO,
action_params=[ball_dict['x_pos'],
ball_dict['y_pos']],
**prestate_dict))
else:
raise RuntimeError("Unknown action {0!r}".format(action))
......@@ -1023,13 +1104,15 @@ def do_next_action(hfo_env,
# figure out what to do next
if not (bit_list[2] or bit_list[3] or bit_list[4]):
if not (bit_list[2] or bit_list[3]):
poss_intent_set = set([INTENT_BALL_KICKABLE,INTENT_BALL_COLLISION,INTENT_GOAL_COLLISION])
if not bit_list[5]:
poss_intent_set.remove(INTENT_BALL_KICKABLE)
poss_intent_set.remove(INTENT_BALL_COLLISION)
if not bit_list[0]:
poss_intent_set.remove(INTENT_GOAL_COLLISION)
if bit_list[4]:
poss_intent_set.remove(INTENT_BALL_KICKABLE)
if not poss_intent_set:
raise NotImplementedError("Not yet set up for self+ball location invalid")
......@@ -1044,14 +1127,22 @@ def do_next_action(hfo_env,
return do_intent(hfo_env, state, namespace)
elif bit_list[4]: # kickable
actions_want_check = set([hfo.INTERCEPT, hfo.GO_TO_BALL])
if bit_list[2] or bit_list[3]:
actions_want_check |= set([hfo.KICK, hfo.KICK_TO])
else: # colliding
actions_want_check = set([hfo.DASH, hfo.TURN, hfo.KICK, hfo.KICK_TO,
hfo.MOVE_TO, hfo.DRIBBLE_TO, hfo.INTERCEPT,
hfo.GO_TO_BALL])
## elif bit_list[4]: # kickable
## actions_want_check = set([hfo.INTERCEPT, hfo.GO_TO_BALL])
## if bit_list[2] or bit_list[3]:
## actions_want_check |= set([hfo.KICK, hfo.KICK_TO])
elif bit_list[2]: # colliding with ball
actions_want_check = set([hfo.GO_TO_BALL])
if bit_list[3]: # colliding with goal
actions_want_check |= set([hfo.KICK, hfo.KICK_TO, hfo.DRIBBLE_TO])
else: # colliding with goal
actions_want_check = set([hfo.KICK, hfo.KICK_TO, hfo.DRIBBLE_TO])
if prior_intent is not None:
print("INTENT: WAS {}".format(INTENT_DICT[prior_intent]))
else:
print("INTENT: NONE")
sys.stdout.flush()
if bit_list[4] and (prior_intent not in (None, INTENT_BALL_KICKABLE)):
namespace.intent_done[INTENT_BALL_KICKABLE] += 1
......
......@@ -68,9 +68,6 @@ STATUS_STRINGS = {IN_GAME: "InGame",
OUT_OF_TIME: "OutOfTime",
SERVER_DOWN: "ServerDown"}
"""Possible sides."""
RIGHT, NEUTRAL, LEFT = list(range(-1,2))
"""Possible action result statuses."""
ACTION_STATUS_UNKNOWN, ACTION_STATUS_BAD, ACTION_STATUS_MAYBE = list(range(-1,2))
ACTION_STATUS_MAYBE_OK = ACTION_STATUS_MAYBE # typos
......@@ -78,6 +75,9 @@ ACTION_STATUS_STRINGS = {ACTION_STATUS_UNKNOWN: "Unknown",
ACTION_STATUS_BAD: "Bad",
ACTION_STATUS_MAYBE: "MaybeOK"}
"""Possible sides."""
RIGHT, NEUTRAL, LEFT = list(range(-1,2))
class Player(Structure): pass
Player._fields_ = [
('side', c_int),
......
......@@ -123,7 +123,7 @@ int HFOEnvironment::getNumOpponents() {
return agent->getNumOpponents();
}
int HFOEnvironment::getLastActionStatus(action_t last_action) {
action_status_t HFOEnvironment::getLastActionStatus(action_t last_action) {
return agent->getLastActionStatus(last_action);
}
......
......@@ -55,7 +55,7 @@ class HFOEnvironment {
// Returns the number of opponents
virtual int getNumOpponents();
virtual int getLastActionStatus(action_t last_action);
virtual action_status_t getLastActionStatus(action_t last_action);
// Get the current player holding the ball
virtual Player playerOnBall();
......
......@@ -153,7 +153,7 @@ Agent::Agent()
// setup last_action variables
last_action_with_status = NOOP;
last_action_status = -1;
last_action_status = ACTION_STATUS_UNKNOWN;
}
Agent::~Agent() {
......@@ -166,20 +166,27 @@ int Agent::getUnum() {
return world().self().unum();
}
int Agent::getLastActionStatus(action_t last_action) {
action_status_t Agent::getLastActionStatus(action_t last_action) {
if (last_action == last_action_with_status) {
return last_action_status;
} else {
return -1;
return ACTION_STATUS_UNKNOWN;
}
}
void Agent::addLastActionStatus(action_t last_action, bool action_status) {
void Agent::addLastActionStatus(action_t last_action, action_status_t action_status) {
last_action_with_status = last_action;
if (action_status) {
last_action_status = 1;
last_action_status = action_status;
}
void Agent::addLastActionStatusCollision(action_t last_action, bool may_fix, bool likely_success) {
last_action_with_status = last_action;
if (likely_success) {
last_action_status = ACTION_STATUS_MAYBE;
} else if (may_fix) {
last_action_status = ACTION_STATUS_UNKNOWN;
} else {
last_action_status = 0;
last_action_status = ACTION_STATUS_BAD;
}
}
......@@ -268,42 +275,55 @@ void Agent::actionImpl() {
<< " parameters, given " << params.size() << std::endl;
exit(1);
}
// For now let's not worry about turning the neck or setting the vision.
// But do the settings now, so that doesn't override any set by the actions below.
// TODO: Add setViewActionDefault, setNeckActionDefault to librcsc that only set if not already set.
this->setViewAction(new View_Tactical());
this->setNeckAction(new Neck_TurnToBallOrScan());
const WorldModel & wm = this->world();
bool may_fix = wm.self().collidesWithPost();
switch(requested_action) {
case DASH:
addLastActionStatus(DASH, this->doDash(params[0], params[1]));
addLastActionStatusCollision(DASH, may_fix, this->doDash(params[0], params[1]));
break;
case TURN:
addLastActionStatus(TURN, this->doTurn(params[0]));
addLastActionStatusCollision(TURN, may_fix, this->doTurn(params[0]));
break;
case TACKLE:
addLastActionStatus(TACKLE, this->doTackle(params[0], false));
addLastActionStatus(TACKLE, BooleanToActionStatus(this->doTackle(params[0], false)));
break;
case KICK:
addLastActionStatus(KICK, this->doKick(params[0], params[1]));
addLastActionStatus(KICK, BooleanToActionStatus(this->doKick(params[0], params[1])));
break;
case KICK_TO:
if (feature_extractor != NULL) {
addLastActionStatus(KICK_TO, Body_SmartKick(Vector2D(feature_extractor->absoluteXPos(params[0]),
addLastActionStatus(KICK_TO,
BooleanToActionStatus(Body_SmartKick(Vector2D(feature_extractor->absoluteXPos(params[0]),
feature_extractor->absoluteYPos(params[1])),
params[2], params[2] * 0.99, 3).execute(this));
params[2], params[2] * 0.99, 3).execute(this)));
}
break;
case MOVE_TO:
if (feature_extractor != NULL) {
addLastActionStatus(MOVE_TO, Body_GoToPoint(Vector2D(feature_extractor->absoluteXPos(params[0]),
addLastActionStatusCollision(MOVE_TO, may_fix,
Body_GoToPoint(Vector2D(feature_extractor->absoluteXPos(params[0]),
feature_extractor->absoluteYPos(params[1])), 0.25,
ServerParam::i().maxDashPower()).execute(this));
}
break;
case DRIBBLE_TO:
if (feature_extractor != NULL) {
addLastActionStatus(DRIBBLE_TO, Body_Dribble(Vector2D(feature_extractor->absoluteXPos(params[0]),
addLastActionStatusCollision(DRIBBLE_TO, may_fix,
Body_Dribble(Vector2D(feature_extractor->absoluteXPos(params[0]),
feature_extractor->absoluteYPos(params[1])), 1.0,
ServerParam::i().maxDashPower(), 2).execute(this));
}
break;
case INTERCEPT:
addLastActionStatus(INTERCEPT, Body_Intercept().execute(this));
addLastActionStatusCollision(INTERCEPT, may_fix, Body_Intercept().execute(this));
break;
case MOVE:
addLastActionStatus(MOVE, this->doMove());
......@@ -318,7 +338,7 @@ void Agent::actionImpl() {
addLastActionStatus(DRIBBLE, this->doDribble());
break;
case CATCH:
addLastActionStatus(CATCH, this->doCatch());
addLastActionStatus(CATCH, BooleanToActionStatus(this->doCatch()));
break;
case NOOP:
break;
......@@ -343,9 +363,7 @@ void Agent::actionImpl() {
<< requested_action << std::endl;
exit(1);
}
// For now let's not worry about turning the neck or setting the vision.
this->setViewAction(new View_Tactical());
this->setNeckAction(new Neck_TurnToBallOrScan());
}
void
......@@ -723,7 +741,7 @@ Agent::doPreprocess()
/*!
*/
bool
action_status_t
Agent::doShoot()
{
const WorldModel & wm = this->world();
......@@ -738,21 +756,23 @@ Agent::doShoot()
// reset intention
this->setIntention( static_cast< SoccerIntention * >( 0 ) );
return true;
return ACTION_STATUS_MAYBE;
}
return false;
return ACTION_STATUS_BAD;
}
bool
action_status_t
Agent::doSmartKick()
{
const ShootGenerator::Container & cont =
ShootGenerator::instance().courses(this->world(), false);
ShootGenerator::Container::const_iterator best_shoot
= std::min_element(cont.begin(), cont.end(), ShootGenerator::ScoreCmp());
return Body_SmartKick(best_shoot->target_point_, best_shoot->first_ball_speed_,
best_shoot->first_ball_speed_ * 0.99, 3).execute(this);
return BooleanToActionStatus(Body_SmartKick(best_shoot->target_point_,
best_shoot->first_ball_speed_,
best_shoot->first_ball_speed_ * 0.99,
3).execute(this));
}
......@@ -769,19 +789,19 @@ Agent::doPass()
return true;
}
bool
action_status_t
Agent::doPassTo(int receiver)
{
Force_Pass pass;
pass.get_pass_to_player(this->world(), receiver);
return pass.execute(this);
return BooleanToActionStatus(pass.execute(this));
}
/*-------------------------------------------------------------------*/
/*!
*/
bool
action_status_t
Agent::doDribble()
{
bool success = false;
......@@ -795,9 +815,9 @@ Agent::doDribble()
success = doPreprocess();
ActionChainHolder::instance().update( world() );
if (Bhv_ChainAction(ActionChainHolder::instance().graph()).execute(this)) {
return true;
return ACTION_STATUS_MAYBE;
} else {
return success;
return BooleanToActionStatus(success);
}
}
......@@ -805,19 +825,19 @@ Agent::doDribble()
/*!
*/
bool
action_status_t
Agent::doMove()
{
Strategy::instance().update( world() );
int role_num = Strategy::i().roleNumber(world().self().unum());
return Bhv_BasicMove().execute(this);
int role_num = Strategy::i().roleNumber(world().self().unum()); // Unused?
return Bhv_BasicMove().action_execute(this);
}
/*-------------------------------------------------------------------*/
/*!
* This Action marks the player with the specified uniform number.
*/
bool Agent::doMarkPlayer(int unum) {
action_status_t Agent::doMarkPlayer(int unum) {
const WorldModel & wm = this->world();
Vector2D kicker_pos = Vector2D :: INVALIDATED;
Vector2D player_pos = Vector2D :: INVALIDATED;
......@@ -841,19 +861,27 @@ bool Agent::doMarkPlayer(int unum) {
if (!player_pos.isValid()) {
//Player to be marked not found
return false;
return ACTION_STATUS_BAD;
}
if (!kicker_pos.isValid()) {
//Kicker not found
return false;
return ACTION_STATUS_BAD;
}
if (unum == kicker_unum || kicker_pos.equals(player_pos)) {
//Player to be marked is kicker
return false;
return ACTION_STATUS_BAD;
}
double x = player_pos.x + (kicker_pos.x - player_pos.x)*0.1;
double y = player_pos.y + (kicker_pos.y - player_pos.y)*0.1;
return Body_GoToPoint(Vector2D(x,y), 0.25, ServerParam::i().maxDashPower()).execute(this);
bool may_fix = wm.self().collidesWithPost();
if (Body_GoToPoint(Vector2D(x,y), 0.25, ServerParam::i().maxDashPower()).execute(this)) {
return ACTION_STATUS_MAYBE;
} else if (may_fix) {
return ACTION_STATUS_UNKNOWN;
} else {
return ACTION_STATUS_BAD;
}
}
/*-------------------------------------------------------------------*/
......@@ -867,7 +895,7 @@ bool compare_y_pos (PlayerObject* i, PlayerObject* j) {
return i->pos().y < j->pos().y;
}
bool Agent::doReduceAngleToGoal() {
action_status_t Agent::doReduceAngleToGoal() {
const WorldModel & wm = this->world();
Vector2D goal_pos1( -ServerParam::i().pitchHalfLength(), ServerParam::i().goalHalfWidth() );
Vector2D goal_pos2( -ServerParam::i().pitchHalfLength(), -ServerParam::i().goalHalfWidth() );
......@@ -876,7 +904,7 @@ bool Agent::doReduceAngleToGoal() {
const BallObject& ball = wm.ball();
if (! ball.rposValid()) {
return false;
return ACTION_STATUS_BAD;
}
Vector2D ball_pos = ball.pos();
......@@ -945,23 +973,30 @@ bool Agent::doReduceAngleToGoal() {
double dist_to_end2 = targetLineEnd2.dist2(ball_pos);
double ratio = dist_to_end2/(dist_to_end1+dist_to_end2);
Vector2D target = targetLineEnd1 * ratio + targetLineEnd2 * (1-ratio);
return Body_GoToPoint(target, 0.25, ServerParam::i().maxDashPower()).execute(this);
bool may_fix = wm.self().collidesWithPost();
if (Body_GoToPoint(target, 0.25, ServerParam::i().maxDashPower()).execute(this)) {
return ACTION_STATUS_MAYBE;
} else if (may_fix) {
return ACTION_STATUS_UNKNOWN;
} else {
return ACTION_STATUS_BAD;
}
}
/*-------------------------------------------------------------------*/
/*!
*
* This action cuts off the angle between the shooter and the goal the players always moves on a fixed line.
* This action cuts off the angle between the shooter and the goal; the player always moves on a fixed line.
*/
bool Agent::doDefendGoal() {
action_status_t Agent::doDefendGoal() {
const WorldModel & wm = this->world();
Vector2D goal_pos1( -ServerParam::i().pitchHalfLength() + ServerParam::i().goalAreaLength(), ServerParam::i().goalHalfWidth() );
Vector2D goal_pos2( -ServerParam::i().pitchHalfLength() + ServerParam::i().goalAreaLength(), -ServerParam::i().goalHalfWidth() );
const BallObject& ball = wm.ball();
if (! ball.rposValid()) {
return false;
return ACTION_STATUS_BAD;
}
Vector2D ball_pos = ball.pos();
......@@ -969,7 +1004,15 @@ bool Agent::doDefendGoal() {
double dist_to_post2 = goal_pos2.dist2(ball_pos);
double ratio = dist_to_post2/(dist_to_post1+dist_to_post2);
Vector2D target = goal_pos1 * ratio + goal_pos2 * (1-ratio);
return Body_GoToPoint(target, 0.25, ServerParam::i().maxDashPower()).execute(this);
bool may_fix = wm.self().collidesWithPost();
if (Body_GoToPoint(target, 0.25, ServerParam::i().maxDashPower()).execute(this)) {
return ACTION_STATUS_MAYBE;
} else if (may_fix) {
return ACTION_STATUS_UNKNOWN;
} else {
return ACTION_STATUS_BAD;
}
}
/*-------------------------------------------------------------------*/
......@@ -980,13 +1023,13 @@ bool Agent::doDefendGoal() {
*/
bool Agent::doGoToBall() {
action_status_t Agent::doGoToBall() {
const WorldModel & wm = this->world();
const BallObject& ball = wm.ball();
if (! ball.rposValid()) {
return false;
return ACTION_STATUS_BAD;
}
return Body_GoToPoint(ball.pos(), 0.25, ServerParam::i().maxDashPower()).execute(this);
return BooleanToActionStatus(Body_GoToPoint(ball.pos(), 0.25, ServerParam::i().maxDashPower()).execute(this));
}
/*-------------------------------------------------------------------*/
......
// -*-c++-*-
#ifndef AGENT_H
#define AGENT_H
......@@ -64,7 +66,7 @@ protected:
int num_teammates; // Number of teammates
int num_opponents; // Number of opponents
hfo::action_t last_action_with_status; // Last action with a recorded return status
int last_action_status; // Recorded return status of last action (1 = true, 0 = false, -1 = not available)
hfo::action_status_t last_action_status; // Recorded return status of last action
public:
inline const std::vector<float>& getState() { return state; }
......@@ -74,7 +76,7 @@ protected:
int getUnum(); // Returns the uniform number of the player
inline int getNumTeammates() { return num_teammates; }
inline int getNumOpponents() { return num_opponents; }
int getLastActionStatus(hfo::action_t last_action); // if last_action is correct, returns status if available
hfo::action_status_t getLastActionStatus(hfo::action_t last_action); // if last_action is correct, returns status if available
inline void setFeatureSet(hfo::feature_set_t fset) { feature_set = fset; }
inline std::vector<float>* mutable_params() { return &params; }
......@@ -83,21 +85,22 @@ protected:
private:
bool doPreprocess();
bool doSmartKick();
bool doShoot();
hfo::action_status_t doSmartKick();
hfo::action_status_t doShoot();
bool doPass();
bool doPassTo(int receiver);
bool doDribble();
bool doMove();
hfo::action_status_t doPassTo(int receiver);
hfo::action_status_t doDribble();
hfo::action_status_t doMove();
bool doForceKick();
bool doHeardPassReceive();
bool doMarkPlayer(int unum);
hfo::action_status_t doMarkPlayer(int unum);
bool doMarkPlayerNearIndex(int near_index);
bool doReduceAngleToGoal();
bool doDefendGoal();
bool doGoToBall();
hfo::action_status_t doReduceAngleToGoal();
hfo::action_status_t doDefendGoal();
hfo::action_status_t doGoToBall();
bool doNewAction1();
void addLastActionStatus(hfo::action_t last_action, bool action_status);
void addLastActionStatus(hfo::action_t last_action, hfo::action_status_t action_status);
void addLastActionStatusCollision(hfo::action_t last_action, bool may_fix, bool likely_success);
Communication::Ptr M_communication;
......
......@@ -48,25 +48,36 @@
#include <rcsc/common/server_param.h>
#include "neck_offensive_intercept_neck.h"
#include "common.hpp"
using namespace rcsc;
bool
Bhv_BasicMove::execute( PlayerAgent * agent )
{
if (Bhv_BasicMove::action_execute(agent) == hfo::ACTION_STATUS_MAYBE) {
return true;
} else {
return false;
}
}
/*-------------------------------------------------------------------*/
/*!
*/
bool
Bhv_BasicMove::execute( PlayerAgent * agent )
hfo::action_status_t
Bhv_BasicMove::action_execute( PlayerAgent * agent )
{
dlog.addText( Logger::TEAM,
__FILE__": Bhv_BasicMove" );
bool success = true;
hfo::action_status_t success = hfo::ACTION_STATUS_UNKNOWN;
//-----------------------------------------------
// tackle
if ( Bhv_BasicTackle( 0.8, 80.0 ).execute( agent ) )
{
return true;
return hfo::ACTION_STATUS_MAYBE;
}
const WorldModel & wm = agent->world();
......@@ -85,9 +96,8 @@ Bhv_BasicMove::execute( PlayerAgent * agent )
{
dlog.addText( Logger::TEAM,
__FILE__": intercept" );
success = Body_Intercept().execute( agent );
success = hfo::BooleanToActionStatus(Body_Intercept().execute( agent ));
agent->setNeckAction( new Neck_OffensiveInterceptNeck() );
return success;
}
......@@ -96,7 +106,9 @@ Bhv_BasicMove::execute( PlayerAgent * agent )
const BallObject& ball = wm.ball();
if (! ball.rposValid()) {
success = false;
if (! wm.self().collidesWithPost()) {
success = hfo::ACTION_STATUS_BAD;
}
}
double dist_thr = ball.distFromSelf() * 0.1;
......@@ -115,8 +127,10 @@ Bhv_BasicMove::execute( PlayerAgent * agent )
).execute( agent ) )
{
if (! Body_TurnToBall().execute( agent )) {
success = false;
success = hfo::ACTION_STATUS_BAD;
}
} else if (success != hfo::ACTION_STATUS_BAD) {
success = hfo::ACTION_STATUS_MAYBE;
}
if ( wm.existKickableOpponent() &&
......
......@@ -29,6 +29,7 @@
#include <rcsc/geom/vector_2d.h>
#include <rcsc/player/soccer_action.h>
#include "common.hpp"
class Bhv_BasicMove
: public rcsc::SoccerBehavior {
......@@ -37,6 +38,7 @@ public:
{ }
bool execute( rcsc::PlayerAgent * agent );
hfo::action_status_t action_execute( rcsc::PlayerAgent * agent );
private:
double getDashPower( const rcsc::PlayerAgent * agent );
......
......@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <vector>
namespace hfo {
......@@ -40,7 +41,7 @@ enum action_t
GO_TO_BALL
};
// Status of a HFO game
// Status of an HFO game
enum status_t
{
IN_GAME, // Game is currently active
......@@ -51,6 +52,24 @@ enum status_t
SERVER_DOWN // Server is not alive
};
// Action status
enum action_status_t {
ACTION_STATUS_UNKNOWN = -1, // cannot tell or invalid action # in status request
ACTION_STATUS_BAD = 0, // definitely not OK
ACTION_STATUS_MAYBE = 1, // may be OK, may not
};
/**
* Translates from boolean false (bad) or true (maybe OK) to action status
*/
inline action_status_t BooleanToActionStatus(const bool status) {
if (status) {
return ACTION_STATUS_MAYBE;
} else{
return ACTION_STATUS_BAD;
}
}
// Configuration of the HFO domain including the team names and player
// numbers for each team. This struct is populated by ParseConfig().
struct Config {
......@@ -171,7 +190,7 @@ inline std::string ActionToString(action_t action) {
};
/**
* Returns a string representation of a game_status.
* Returns a string representation of a game status.
*/
inline std::string StatusToString(status_t status) {
switch (status) {
......@@ -192,6 +211,22 @@ inline std::string StatusToString(status_t status) {
}
};
/**
* Returns a string representation of an action status.
*/
inline std::string ActionStatusToString(action_status_t status) {
switch (status) {
case ACTION_STATUS_BAD:
return "Bad";
case ACTION_STATUS_MAYBE:
return "MaybeOK";
case ACTION_STATUS_UNKNOWN:
return "Unknown";
default:
return "Invalid";
}
}
/**
* Parse a Trainer message to populate config. Returns a bool
* indicating if the struct was correctly parsed.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment