Skip to content

Commit

Permalink
Calculate botSubstitutionTimeLeft centrally and distribute it via ref…
Browse files Browse the repository at this point in the history
…Msg and remote-control
  • Loading branch information
g3force committed Mar 30, 2024
1 parent 7fd47ef commit 9945902
Show file tree
Hide file tree
Showing 15 changed files with 314 additions and 226 deletions.
5 changes: 5 additions & 0 deletions frontend/src/proto/ssl_gc_referee_message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,8 @@ export interface Referee_TeamInfo {
botSubstitutionAllowed?: boolean;
/** The number of bot substitutions left by the team in this halftime */
botSubstitutionsLeft?: number;
/** The number of microseconds left for current bot substitution */
botSubstitutionTimeLeft?: number;
}

/**
Expand Down Expand Up @@ -576,6 +578,7 @@ export const Referee_TeamInfo = {
: false,
botSubstitutionAllowed: isSet(object.botSubstitutionAllowed) ? Boolean(object.botSubstitutionAllowed) : false,
botSubstitutionsLeft: isSet(object.botSubstitutionsLeft) ? Number(object.botSubstitutionsLeft) : 0,
botSubstitutionTimeLeft: isSet(object.botSubstitutionTimeLeft) ? Number(object.botSubstitutionTimeLeft) : 0,
};
},

Expand Down Expand Up @@ -603,6 +606,8 @@ export const Referee_TeamInfo = {
(obj.ballPlacementFailuresReached = message.ballPlacementFailuresReached);
message.botSubstitutionAllowed !== undefined && (obj.botSubstitutionAllowed = message.botSubstitutionAllowed);
message.botSubstitutionsLeft !== undefined && (obj.botSubstitutionsLeft = Math.round(message.botSubstitutionsLeft));
message.botSubstitutionTimeLeft !== undefined &&
(obj.botSubstitutionTimeLeft = Math.round(message.botSubstitutionTimeLeft));
return obj;
},
};
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/proto/ssl_gc_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ export interface TeamInfo {
challengeFlags?: number;
botSubstitutionAllowed?: boolean;
botSubstitutionsLeft?: number;
botSubstitutionTimeLeft?: Duration;
}

export interface State {
Expand Down Expand Up @@ -429,6 +430,9 @@ export const TeamInfo = {
challengeFlags: isSet(object.challengeFlags) ? Number(object.challengeFlags) : 0,
botSubstitutionAllowed: isSet(object.botSubstitutionAllowed) ? Boolean(object.botSubstitutionAllowed) : false,
botSubstitutionsLeft: isSet(object.botSubstitutionsLeft) ? Number(object.botSubstitutionsLeft) : 0,
botSubstitutionTimeLeft: isSet(object.botSubstitutionTimeLeft)
? Duration.fromJSON(object.botSubstitutionTimeLeft)
: undefined,
};
},

Expand Down Expand Up @@ -471,6 +475,9 @@ export const TeamInfo = {
message.challengeFlags !== undefined && (obj.challengeFlags = Math.round(message.challengeFlags));
message.botSubstitutionAllowed !== undefined && (obj.botSubstitutionAllowed = message.botSubstitutionAllowed);
message.botSubstitutionsLeft !== undefined && (obj.botSubstitutionsLeft = Math.round(message.botSubstitutionsLeft));
message.botSubstitutionTimeLeft !== undefined && (obj.botSubstitutionTimeLeft = message.botSubstitutionTimeLeft
? Duration.toJSON(message.botSubstitutionTimeLeft)
: undefined);
return obj;
},
};
Expand Down
3 changes: 3 additions & 0 deletions internal/app/engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@ func initializeAddedTeamInfoFields(teamInfo *state.TeamInfo) {
if teamInfo.BotSubstitutionsLeft == nil {
teamInfo.BotSubstitutionsLeft = new(int32)
}
if teamInfo.BotSubstitutionTimeLeft == nil {
teamInfo.BotSubstitutionTimeLeft = durationpb.New(0)
}
}

// Stop stops the go routine that processes the change queue
Expand Down
20 changes: 8 additions & 12 deletions internal/app/engine/process_bot_substitution.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,19 @@ package engine

import (
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/state"
"time"
"google.golang.org/protobuf/types/known/durationpb"
)

func (e *Engine) processBotSubstitution() {
if e.currentState.GameState.IsHalted() {
for _, team := range state.BothTeams() {
if !*e.currentState.TeamInfo(team).BotSubstitutionAllowed {
continue
}
events := e.currentState.FindGameEventsByTeam(state.GameEvent_BOT_SUBSTITUTION, team)
if len(events) == 0 {
continue
}
botSubstitutionEvent := events[len(events)-1]
eventCreated := time.UnixMicro(int64(*botSubstitutionEvent.CreatedTimestamp))
if e.timeProvider().Sub(eventCreated) > e.gameConfig.BotSubstitutionTime {
e.Enqueue(createBotSubstitutionEventChange(team))
if *e.currentState.TeamInfo(team).BotSubstitutionAllowed {
if e.currentState.TeamInfo(team).BotSubstitutionTimeLeft.AsDuration() <= 0 {
e.Enqueue(createBotSubstitutionEventChange(team))
e.currentState.TeamInfo(team).BotSubstitutionTimeLeft = durationpb.New(e.gameConfig.BotSubstitutionTime)
}
} else {
e.currentState.TeamInfo(team).BotSubstitutionTimeLeft = durationpb.New(0)
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions internal/app/engine/process_tick.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,16 @@ func (e *Engine) processTick() {
}
}

if e.countCardTime() {
for _, teamState := range e.currentState.TeamState {
for _, teamState := range e.currentState.TeamState {
if e.countCardTime() {
e.updateYellowCardTimes(teamState, delta)
}
if *teamState.BotSubstitutionAllowed {
addDur(teamState.BotSubstitutionTimeLeft, -delta)
if teamState.BotSubstitutionTimeLeft.AsDuration() < 0 {
*teamState.BotSubstitutionTimeLeft = *durationpb.New(0)
}
}
}

if *e.currentState.Command.Type == state.Command_TIMEOUT {
Expand Down
5 changes: 3 additions & 2 deletions internal/app/publish/messagegenerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func updateTeam(teamInfo *state.Referee_TeamInfo, teamState *state.TeamInfo) {
teamInfo.YellowCardTimes = mapYellowCardTimes(teamState.YellowCards)
*teamInfo.YellowCards = unsigned(len(teamState.YellowCards))
*teamInfo.Timeouts = unsigned32(*teamState.TimeoutsLeft)
*teamInfo.TimeoutTime = mapTime(teamState.TimeoutTimeLeft.AsDuration())
*teamInfo.Goalkeeper = unsigned32(*teamState.Goalkeeper)
*teamInfo.FoulCounter = unsigned(len(teamState.Fouls))
*teamInfo.BallPlacementFailures = unsigned32(*teamState.BallPlacementFailures)
Expand All @@ -138,8 +139,7 @@ func updateTeam(teamInfo *state.Referee_TeamInfo, teamState *state.TeamInfo) {
*teamInfo.BotSubstitutionIntent = teamState.RequestsBotSubstitutionSince != nil
*teamInfo.BotSubstitutionAllowed = *teamState.BotSubstitutionAllowed
*teamInfo.BotSubstitutionsLeft = unsigned32(*teamState.BotSubstitutionsLeft)
timeoutTime := teamState.TimeoutTimeLeft.AsDuration()
*teamInfo.TimeoutTime = mapTime(timeoutTime)
*teamInfo.BotSubstitutionTimeLeft = mapTime(teamState.BotSubstitutionTimeLeft.AsDuration())
}

func newRefereeMessage() (m *state.Referee) {
Expand Down Expand Up @@ -176,6 +176,7 @@ func newTeamInfo() (t *state.Referee_TeamInfo) {
t.BotSubstitutionIntent = new(bool)
t.BotSubstitutionAllowed = new(bool)
t.BotSubstitutionsLeft = new(uint32)
t.BotSubstitutionTimeLeft = new(uint32)
return
}

Expand Down
28 changes: 16 additions & 12 deletions internal/app/rcon/server_remotecontrol.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,21 +154,25 @@ func (c *RemoteControlClient) replyWithState(reply *ControllerReply) {
robotsOnField := c.gcEngine.TrackerState().NumTeamRobots(*c.team)
timeoutTimeLeft := float32(teamState.TimeoutTimeLeft.AsDuration().Seconds())
canSubstituteRobot := c.canSubstituteRobot()
botSubstitutionsLeft := uint32(*teamState.BotSubstitutionsLeft)
botSubstitutionTimeLeft := float32(teamState.BotSubstitutionTimeLeft.AsDuration().Seconds())

response := &ControllerToRemoteControl{
State: &RemoteControlTeamState{
Team: c.team,
KeeperId: teamState.Goalkeeper,
AvailableRequests: availableRequests,
ActiveRequests: activeRequests,
EmergencyStopIn: &emergencyStopIn,
TimeoutsLeft: teamState.TimeoutsLeft,
TimeoutTimeLeft: &timeoutTimeLeft,
ChallengeFlagsLeft: teamState.ChallengeFlags,
MaxRobots: teamState.MaxAllowedBots,
RobotsOnField: &robotsOnField,
YellowCardsDue: yellowCardsDue,
CanSubstituteRobot: &canSubstituteRobot,
Team: c.team,
KeeperId: teamState.Goalkeeper,
AvailableRequests: availableRequests,
ActiveRequests: activeRequests,
EmergencyStopIn: &emergencyStopIn,
TimeoutsLeft: teamState.TimeoutsLeft,
TimeoutTimeLeft: &timeoutTimeLeft,
ChallengeFlagsLeft: teamState.ChallengeFlags,
MaxRobots: teamState.MaxAllowedBots,
RobotsOnField: &robotsOnField,
YellowCardsDue: yellowCardsDue,
CanSubstituteRobot: &canSubstituteRobot,
BotSubstitutionsLeft: &botSubstitutionsLeft,
BotSubstitutionTimeLeft: &botSubstitutionTimeLeft,
},
ControllerReply: reply,
}
Expand Down
59 changes: 42 additions & 17 deletions internal/app/rcon/ssl_gc_rcon_remotecontrol.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9945902

Please sign in to comment.