Change entry for 2024 scouting
Signed-off-by: Emily Markova <emily.markova@gmail.com>
Change-Id: I37ffab8a4e80628c0c50361a4c8ae69900c5b0b9
diff --git a/scouting/www/entry/BUILD b/scouting/www/entry/BUILD
index 2884f23..98b457b 100644
--- a/scouting/www/entry/BUILD
+++ b/scouting/www/entry/BUILD
@@ -12,7 +12,7 @@
":node_modules/@angular/forms",
"//scouting/webserver/requests/messages:error_response_ts_fbs",
"//scouting/webserver/requests/messages:request_all_matches_response_ts_fbs",
- "//scouting/webserver/requests/messages:submit_actions_ts_fbs",
+ "//scouting/webserver/requests/messages:submit_2024_actions_ts_fbs",
"//scouting/www/rpc",
"@com_github_google_flatbuffers//ts:flatbuffers_ts",
],
diff --git a/scouting/www/entry/entry.component.css b/scouting/www/entry/entry.component.css
index 38e9072..246887c 100644
--- a/scouting/www/entry/entry.component.css
+++ b/scouting/www/entry/entry.component.css
@@ -11,15 +11,10 @@
touch-action: manipulation;
}
-#switchFldbtn {
- width: 15%;
- display: block;
- margin: 0 auto;
- box-shadow: 2px 2px 1px #ccc;
- max-width: 105px;
- text-align: center;
+.row ul div span {
+ padding: 0px;
}
-.row ul div span {
+input label {
padding: 0px;
}
diff --git a/scouting/www/entry/entry.component.ts b/scouting/www/entry/entry.component.ts
index 5a93251..b3e1e92 100644
--- a/scouting/www/entry/entry.component.ts
+++ b/scouting/www/entry/entry.component.ts
@@ -11,19 +11,19 @@
import {Builder, ByteBuffer} from 'flatbuffers';
import {ErrorResponse} from '../../webserver/requests/messages/error_response_generated';
import {
- ObjectType,
- ScoreLevel,
- SubmitActions,
StartMatchAction,
+ ScoreType,
+ StageType,
+ Submit2024Actions,
MobilityAction,
- AutoBalanceAction,
- PickupObjectAction,
- PlaceObjectAction,
+ PenaltyAction,
+ PickupNoteAction,
+ PlaceNoteAction,
RobotDeathAction,
EndMatchAction,
ActionType,
Action,
-} from '../../webserver/requests/messages/submit_actions_generated';
+} from '../../webserver/requests/messages/submit_2024_actions_generated';
import {Match} from '../../webserver/requests/messages/request_all_matches_response_generated';
import {MatchListRequestor} from '@org_frc971/scouting/www/rpc';
@@ -62,23 +62,14 @@
mobility: boolean;
}
| {
- type: 'autoBalanceAction';
+ type: 'pickupNoteAction';
timestamp?: number;
- docked: boolean;
- engaged: boolean;
- balanceAttempt: boolean;
- }
- | {
- type: 'pickupObjectAction';
- timestamp?: number;
- objectType: ObjectType;
auto?: boolean;
}
| {
- type: 'placeObjectAction';
+ type: 'placeNoteAction';
timestamp?: number;
- objectType?: ObjectType;
- scoreLevel: ScoreLevel;
+ scoreType: ScoreType;
auto?: boolean;
}
| {
@@ -87,10 +78,14 @@
robotOn: boolean;
}
| {
+ type: 'penaltyAction';
+ timestamp?: number;
+ penalties: number;
+ }
+ | {
type: 'endMatchAction';
- docked: boolean;
- engaged: boolean;
- balanceAttempt: boolean;
+ stageType: StageType;
+ trapNote: boolean;
timestamp?: number;
}
| {
@@ -98,6 +93,12 @@
// It is used for undoing purposes.
type: 'endAutoPhase';
timestamp?: number;
+ }
+ | {
+ // This is not a action that is submitted,
+ // It is used for undoing purposes.
+ type: 'endTeleopPhase';
+ timestamp?: number;
};
@Component({
@@ -110,8 +111,7 @@
// of radio buttons.
readonly COMP_LEVELS = COMP_LEVELS;
readonly COMP_LEVEL_LABELS = COMP_LEVEL_LABELS;
- readonly ObjectType = ObjectType;
- readonly ScoreLevel = ScoreLevel;
+ readonly ScoreType = ScoreType;
section: Section = 'Team Selection';
@Input() matchNumber: number = 1;
@@ -127,10 +127,10 @@
errorMessage: string = '';
autoPhase: boolean = true;
mobilityCompleted: boolean = false;
- lastObject: ObjectType = null;
preScouting: boolean = false;
matchStartTimestamp: number = 0;
+ penalties: number = 0;
teamSelectionIsValid = false;
@@ -192,6 +192,20 @@
return false;
}
+ addPenalty(): void {
+ this.penalties += 1;
+ }
+
+ removePenalty(): void {
+ if (this.penalties > 0) {
+ this.penalties -= 1;
+ }
+ }
+
+ addPenalties(): void {
+ this.addAction({type: 'penaltyAction', penalties: this.penalties});
+ }
+
addAction(action: ActionT): void {
if (action.type == 'startMatchAction') {
// Unix nanosecond timestamp.
@@ -202,27 +216,17 @@
action.timestamp = Date.now() * 1e6 - this.matchStartTimestamp;
}
+ if (action.type == 'endMatchAction') {
+ // endMatchAction occurs at the same time as penaltyAction so add to its timestamp to make it unique.
+ action.timestamp += 1;
+ }
+
if (action.type == 'mobilityAction') {
this.mobilityCompleted = true;
}
- if (action.type == 'autoBalanceAction') {
- // Timestamp is a unique index in the database so
- // adding one makes sure it dosen't overlap with the
- // start teleop action that is added at the same time.
- action.timestamp += 1;
- }
-
- if (
- action.type == 'pickupObjectAction' ||
- action.type == 'placeObjectAction'
- ) {
+ if (action.type == 'pickupNoteAction' || action.type == 'placeNoteAction') {
action.auto = this.autoPhase;
- if (action.type == 'pickupObjectAction') {
- this.lastObject = action.objectType;
- } else if (action.type == 'placeObjectAction') {
- action.objectType = this.lastObject;
- }
}
this.actionList.push(action);
}
@@ -233,14 +237,23 @@
switch (lastAction?.type) {
case 'endAutoPhase':
this.autoPhase = true;
- case 'pickupObjectAction':
+ this.section = 'Pickup';
+ case 'pickupNoteAction':
this.section = 'Pickup';
break;
- case 'placeObjectAction':
+ case 'endTeleopPhase':
+ this.section = 'Pickup';
+ break;
+ case 'placeNoteAction':
this.section = 'Place';
break;
case 'endMatchAction':
- this.section = 'Pickup';
+ this.section = 'Endgame';
+ case 'mobilityAction':
+ this.mobilityCompleted = false;
+ break;
+ case 'startMatchAction':
+ this.section = 'Init';
break;
case 'robotDeathAction':
// TODO(FILIP): Return user to the screen they
@@ -254,12 +267,12 @@
}
}
- stringifyObjectType(objectType: ObjectType): String {
- return ObjectType[objectType];
+ stringifyScoreType(scoreType: ScoreType): String {
+ return ScoreType[scoreType];
}
- stringifyScoreLevel(scoreLevel: ScoreLevel): String {
- return ScoreLevel[scoreLevel];
+ stringifyStageType(stageType: StageType): String {
+ return StageType[stageType];
}
changeSectionTo(target: Section) {
@@ -276,7 +289,7 @@
this.header.nativeElement.scrollIntoView();
}
- async submitActions() {
+ async submit2024Actions() {
const builder = new Builder();
const actionOffsets: number[] = [];
@@ -307,49 +320,42 @@
mobilityActionOffset
);
break;
- case 'autoBalanceAction':
- const autoBalanceActionOffset =
- AutoBalanceAction.createAutoBalanceAction(
- builder,
- action.docked,
- action.engaged,
- action.balanceAttempt
- );
+ case 'penaltyAction':
+ const penaltyActionOffset = PenaltyAction.createPenaltyAction(
+ builder,
+ action.penalties
+ );
actionOffset = Action.createAction(
builder,
BigInt(action.timestamp || 0),
- ActionType.AutoBalanceAction,
- autoBalanceActionOffset
+ ActionType.PenaltyAction,
+ penaltyActionOffset
);
break;
-
- case 'pickupObjectAction':
- const pickupObjectActionOffset =
- PickupObjectAction.createPickupObjectAction(
+ case 'pickupNoteAction':
+ const pickupNoteActionOffset =
+ PickupNoteAction.createPickupNoteAction(
builder,
- action.objectType,
action.auto || false
);
actionOffset = Action.createAction(
builder,
BigInt(action.timestamp || 0),
- ActionType.PickupObjectAction,
- pickupObjectActionOffset
+ ActionType.PickupNoteAction,
+ pickupNoteActionOffset
);
break;
- case 'placeObjectAction':
- const placeObjectActionOffset =
- PlaceObjectAction.createPlaceObjectAction(
- builder,
- action.objectType,
- action.scoreLevel,
- action.auto || false
- );
+ case 'placeNoteAction':
+ const placeNoteActionOffset = PlaceNoteAction.createPlaceNoteAction(
+ builder,
+ action.scoreType,
+ action.auto || false
+ );
actionOffset = Action.createAction(
builder,
BigInt(action.timestamp || 0),
- ActionType.PlaceObjectAction,
- placeObjectActionOffset
+ ActionType.PlaceNoteAction,
+ placeNoteActionOffset
);
break;
@@ -367,9 +373,8 @@
case 'endMatchAction':
const endMatchActionOffset = EndMatchAction.createEndMatchAction(
builder,
- action.docked,
- action.engaged,
- action.balanceAttempt
+ action.stageType,
+ action.trapNote
);
actionOffset = Action.createAction(
builder,
@@ -383,6 +388,10 @@
// Not important action.
break;
+ case 'endTeleopPhase':
+ // Not important action.
+ break;
+
default:
throw new Error(`Unknown action type`);
}
@@ -394,21 +403,21 @@
const teamNumberFb = builder.createString(this.teamNumber);
const compLevelFb = builder.createString(this.compLevel);
- const actionsVector = SubmitActions.createActionsListVector(
+ const actionsVector = Submit2024Actions.createActionsListVector(
builder,
actionOffsets
);
- SubmitActions.startSubmitActions(builder);
- SubmitActions.addTeamNumber(builder, teamNumberFb);
- SubmitActions.addMatchNumber(builder, this.matchNumber);
- SubmitActions.addSetNumber(builder, this.setNumber);
- SubmitActions.addCompLevel(builder, compLevelFb);
- SubmitActions.addActionsList(builder, actionsVector);
- SubmitActions.addPreScouting(builder, this.preScouting);
- builder.finish(SubmitActions.endSubmitActions(builder));
+ Submit2024Actions.startSubmit2024Actions(builder);
+ Submit2024Actions.addTeamNumber(builder, teamNumberFb);
+ Submit2024Actions.addMatchNumber(builder, this.matchNumber);
+ Submit2024Actions.addSetNumber(builder, this.setNumber);
+ Submit2024Actions.addCompLevel(builder, compLevelFb);
+ Submit2024Actions.addActionsList(builder, actionsVector);
+ Submit2024Actions.addPreScouting(builder, this.preScouting);
+ builder.finish(Submit2024Actions.endSubmit2024Actions(builder));
const buffer = builder.asUint8Array();
- const res = await fetch('/requests/submit/submit_actions', {
+ const res = await fetch('/requests/submit/submit_2024_actions', {
method: 'POST',
body: buffer,
});
diff --git a/scouting/www/entry/entry.ng.html b/scouting/www/entry/entry.ng.html
index 43575cd..9490237 100644
--- a/scouting/www/entry/entry.ng.html
+++ b/scouting/www/entry/entry.ng.html
@@ -81,7 +81,7 @@
<h2>Select Starting Position</h2>
<img
id="field_starting_positions_image"
- src="/sha256/b71def525fb78486617a8b350c0ba6907e8ea25f78d4084a932cba8ae922528c/pictures/field/field.jpg"
+ src="/sha256/bb83d2c976c1496bb470371821d1d1882d6baf31178009a6f6cba579880c6a03/pictures/field/2024_field.png"
alt="Starting Positions Image"
class="img-fluid"
/>
@@ -129,15 +129,9 @@
</button>
<button
class="btn btn-warning"
- (click)="changeSectionTo('Place'); addAction({type: 'pickupObjectAction', objectType: ObjectType.kCone});"
+ (click)="changeSectionTo('Place'); addAction({type: 'pickupNoteAction'});"
>
- CONE
- </button>
- <button
- class="btn btn-primary"
- (click)="changeSectionTo('Place'); addAction({type: 'pickupObjectAction', objectType: ObjectType.kCube});"
- >
- CUBE
+ NOTE
</button>
<button
*ngIf="autoPhase && !mobilityCompleted"
@@ -146,49 +140,35 @@
>
Mobility
</button>
- <!-- 'Balancing' during auto. -->
- <div *ngIf="autoPhase" class="d-grid gap-2">
- <label>
- <input
- #docked
- type="radio"
- id="option1"
- name="docked_engaged"
- value="docked"
- />
- Docked (on the charging station)
- </label>
- <label>
- <input
- #engaged
- type="radio"
- id="option2"
- name="docked_engaged"
- value="dockedengaged"
- />
- Docked & Engaged (level & station lights on)
- </label>
- <label>
- <input
- #attempted
- type="radio"
- id="option3"
- name="docked_engaged"
- value="failed"
- />
- Attempted to dock and engage but failed
- </label>
+ <div style="display: flex">
+ <h5>Penalties :</h5>
<button
- class="btn btn-dark"
- (click)="autoPhase = false; addAction({type: 'endAutoPhase'}); addAction({type: 'autoBalanceAction', docked: docked.checked, engaged: engaged.checked, balanceAttempt: attempted.checked});"
+ class="btn-light"
+ style="width: 40px; margin-right: 15px"
+ (click)="removePenalty()"
>
- Start Teleop
+ -
+ </button>
+ <p>{{this.penalties}}</p>
+ <button
+ class="btn-light"
+ style="width: 40px; margin-left: 15px"
+ (click)="addPenalty()"
+ >
+ +
</button>
</div>
<button
+ *ngIf="autoPhase"
+ class="btn btn-dark"
+ (click)="autoPhase = false; addAction({type: 'endAutoPhase'});"
+ >
+ Start Teleop
+ </button>
+ <button
*ngIf="!autoPhase"
class="btn btn-info"
- (click)="changeSectionTo('Endgame')"
+ (click)="changeSectionTo('Endgame'); addAction({type: 'endTeleopPhase'});"
>
Endgame
</button>
@@ -212,23 +192,62 @@
>
DEAD
</button>
+ <div *ngIf="!autoPhase" class="d-grid gap-1" style="padding: 0">
+ <div
+ style="
+ display: flex-wrap;
+ padding: 0;
+ justify-content: center;
+ text-align: center;
+ align-content: center;
+ margin: 0;
+ "
+ >
+ <button
+ class="btn btn-success"
+ (click)="changeSectionTo('Pickup'); addAction({type: 'placeNoteAction', scoreType: ScoreType.kAMP});"
+ style="width: 48%; height: 12vh; margin: 0px 10px 10px 0px"
+ >
+ AMP
+ </button>
+
+ <button
+ class="btn btn-warning"
+ (click)="changeSectionTo('Pickup'); addAction({type: 'placeNoteAction', scoreType: ScoreType.kAMP_AMPLIFIED});"
+ style="width: 48%; height: 12vh; margin: 0px 0px 10px 0px"
+ >
+ AMP AMPLIFIED
+ </button>
+ <button
+ class="btn btn-success"
+ (click)="changeSectionTo('Pickup'); addAction({type: 'placeNoteAction', scoreType: ScoreType.kSPEAKER});"
+ style="width: 48%; height: 12vh; margin: 0px 10px 0px 0px"
+ >
+ SPEAKER
+ </button>
+ <button
+ class="btn btn-warning"
+ (click)="changeSectionTo('Pickup'); addAction({type: 'placeNoteAction', scoreType: ScoreType.kSPEAKER_AMPLIFIED});"
+ style="width: 48%; height: 12vh; margin: 0px 0px 0px 0px"
+ >
+ SPEAKER AMPLIFIED
+ </button>
+ </div>
+ </div>
+
<button
+ *ngIf="autoPhase"
class="btn btn-success"
- (click)="changeSectionTo('Pickup'); addAction({type: 'placeObjectAction', scoreLevel: ScoreLevel.kHigh});"
+ (click)="changeSectionTo('Pickup'); addAction({type: 'placeNoteAction', scoreType: ScoreType.kAMP});"
>
- HIGH
+ AMP
</button>
<button
+ *ngIf="autoPhase"
class="btn btn-warning"
- (click)="changeSectionTo('Pickup'); addAction({type: 'placeObjectAction', scoreLevel: ScoreLevel.kMiddle});"
+ (click)="changeSectionTo('Pickup'); addAction({type: 'placeNoteAction', scoreType: ScoreType.kSPEAKER});"
>
- MID
- </button>
- <button
- class="btn btn-danger"
- (click)="changeSectionTo('Pickup'); addAction({type: 'placeObjectAction', scoreLevel: ScoreLevel.kLow});"
- >
- LOW
+ SPEAKER
</button>
<button
*ngIf="autoPhase && !mobilityCompleted"
@@ -237,58 +256,35 @@
>
Mobility
</button>
- <!-- Impossible to place supercharged pieces in auto. -->
- <div *ngIf="autoPhase == false" class="d-grid gap-2">
+ <div style="display: flex">
+ <h5>Penalties :</h5>
<button
- class="btn btn-dark"
- (click)="changeSectionTo('Pickup'); addAction({type: 'placeObjectAction', scoreLevel: ScoreLevel.kSupercharged});"
+ class="btn-light"
+ style="width: 40px; margin-right: 15px"
+ (click)="removePenalty()"
>
- SUPERCHARGED
+ -
</button>
- </div>
- <!-- 'Balancing' during auto. -->
- <div *ngIf="autoPhase" class="d-grid gap-1">
- <label>
- <input
- #docked
- type="radio"
- id="option1"
- name="docked_engaged"
- value="docked"
- />
- Docked (on the charging station)
- </label>
- <label>
- <input
- #engaged
- type="radio"
- id="option2"
- name="docked_engaged"
- value="dockedengaged"
- />
- Docked & Engaged (level & station lights on)
- </label>
- <label>
- <input
- #attempted
- type="radio"
- id="option3"
- name="docked_engaged"
- value="failed"
- />
- Attempted to dock and engage but failed
- </label>
+ <p>{{this.penalties}}</p>
<button
- class="btn btn-dark"
- (click)="autoPhase = false; addAction({type: 'endAutoPhase'}); addAction({type: 'autoBalanceAction', docked: docked.checked, engaged: engaged.checked, balanceAttempt: attempted.checked});"
+ class="btn-light"
+ style="width: 40px; margin-left: 15px"
+ (click)="addPenalty()"
>
- Start Teleop
+ +
</button>
</div>
<button
+ class="btn btn-dark"
+ *ngIf="autoPhase"
+ (click)="autoPhase = false; addAction({type: 'endAutoPhase'});"
+ >
+ Start Teleop
+ </button>
+ <button
*ngIf="!autoPhase"
class="btn btn-info"
- (click)="changeSectionTo('Endgame')"
+ (click)="changeSectionTo('Endgame'); addAction({type: 'endTeleopPhase'});"
>
Endgame
</button>
@@ -298,7 +294,7 @@
<h6 class="text-muted">
Last Action: {{actionList[actionList.length - 1].type}}
</h6>
- <div class="d-grid gap-5">
+ <div class="d-grid gap-4">
<button class="btn btn-secondary" (click)="undoLastAction()">UNDO</button>
<button
class="btn btn-danger"
@@ -306,40 +302,68 @@
>
DEAD
</button>
- <label>
+ <label style="padding: 0">
<input
- #docked
+ #park
type="radio"
id="option1"
- name="docked_engaged"
- value="docked"
+ name="endgameaction"
+ value="park"
/>
- Docked (on the charging station)
+ Park
</label>
- <label>
+ <label style="padding: 0">
<input
- #engaged
+ #onStage
type="radio"
id="option2"
- name="docked_engaged"
- value="dockedengaged"
+ name="endgameaction"
+ value="onStage"
/>
- Docked & Engaged (level & station lights on)
+ On Stage
</label>
- <label>
+ <label style="padding: 0">
<input
- #attempted
+ #harmony
type="radio"
id="option3"
- name="docked_engaged"
- value="failed"
+ name="endgameaction"
+ value="harmony"
/>
- Attempted to dock and engage but failed
+ Harmony
</label>
+ <label style="padding: 0">
+ <input
+ #trapNote
+ type="checkbox"
+ id="trapnote"
+ name="trapnote"
+ value="trapNote"
+ />
+ Trap Note
+ </label>
+ <div style="display: flex">
+ <h5>Penalties :</h5>
+ <button
+ class="btn-light"
+ style="width: 40px; margin-right: 15px"
+ (click)="removePenalty()"
+ >
+ -
+ </button>
+ <p>{{this.penalties}}</p>
+ <button
+ class="btn-light"
+ style="width: 40px; margin-left: 15px"
+ (click)="addPenalty()"
+ >
+ +
+ </button>
+ </div>
<button
*ngIf="!autoPhase"
class="btn btn-info"
- (click)="changeSectionTo('Review and Submit'); addAction({type: 'endMatchAction', docked: docked.checked, engaged: engaged.checked, balanceAttempt: attempted.checked});"
+ (click)="changeSectionTo('Review and Submit'); addPenalties(); addAction({type: 'endMatchAction', park: park.checked, onStage: onStage.checked, harmony: harmony.checked, trapNote: trapNote.checked});"
>
End Match
</button>
@@ -354,12 +378,6 @@
>
Revive
</button>
- <button
- class="btn btn-info"
- (click)="changeSectionTo('Review and Submit'); addAction({type: 'endMatchAction', docked: docked.checked, engaged: engaged.checked});"
- >
- End Match
- </button>
</div>
</div>
<div *ngSwitchCase="'Review and Submit'" id="Review" class="container-fluid">
@@ -374,21 +392,14 @@
<span *ngSwitchCase="'startMatchAction'">
Started match at position {{action.position}}
</span>
- <span *ngSwitchCase="'pickupObjectAction'">
- Picked up {{stringifyObjectType(action.objectType)}}
- </span>
- <span *ngSwitchCase="'placeObjectAction'">
- Placed at {{stringifyScoreLevel(action.scoreLevel)}}
- </span>
- <span *ngSwitchCase="'autoBalanceAction'">
- Docked: {{action.docked}}, engaged: {{action.engaged}}, attempted
- to balance and engage: {{action.balanceAttempt}}
+ <span *ngSwitchCase="'pickupNoteAction'">Picked up Note</span>
+ <span *ngSwitchCase="'placeNoteAction'">
+ Placed at {{stringifyScoreType(action.scoreType)}}
</span>
<span *ngSwitchCase="'endAutoPhase'">Ended auto phase</span>
<span *ngSwitchCase="'endMatchAction'">
- Ended Match; docked: {{action.docked}}, engaged:
- {{action.engaged}}, attempted to dock and engage:
- {{action.balanceAttempt}}
+ Ended Match; park: {{action.park}}, onStage: {{action.onStage}},
+ harmony: {{action.harmony}}, trapNote: {{action.trapNote}}
</span>
<span *ngSwitchCase="'robotDeathAction'">
Robot on: {{action.robotOn}}
@@ -397,13 +408,18 @@
Mobility: {{action.mobility}}
</span>
<span *ngSwitchDefault>{{action.type}}</span>
+ <span *ngSwitchCase="'penaltyAction'">
+ Penalties: {{action.penalties}}
+ </span>
</div>
</li>
</ul>
</div>
<div class="d-grid gap-5">
<button class="btn btn-secondary" (click)="undoLastAction()">UNDO</button>
- <button class="btn btn-warning" (click)="submitActions();">Submit</button>
+ <button class="btn btn-warning" (click)="submit2024Actions();">
+ Submit
+ </button>
</div>
</div>
<div *ngSwitchCase="'Success'" id="Success" class="container-fluid">