Skip to content

Commit 57a9b4f

Browse files
Merge pull request #9 from twisterjafla/main
2 parents b89407b + f2143a0 commit 57a9b4f

18 files changed

+976
-130
lines changed

yagsl/java/swervelib/simulation/ironmaple/simulation/Goal.java

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
package swervelib.simulation.ironmaple.simulation;
22

3+
import static edu.wpi.first.units.Units.Degrees;
4+
35
import edu.wpi.first.math.geometry.Pose3d;
46
import edu.wpi.first.math.geometry.Rotation3d;
57
import edu.wpi.first.math.geometry.Translation3d;
68
import edu.wpi.first.units.Units;
79
import edu.wpi.first.units.measure.Angle;
810
import edu.wpi.first.units.measure.Distance;
9-
import org.dyn4j.geometry.Rectangle;
10-
import org.dyn4j.geometry.Vector2;
1111
import swervelib.simulation.ironmaple.simulation.gamepieces.GamePiece;
1212

1313
import java.util.List;
14-
15-
import static edu.wpi.first.units.Units.Degrees;
14+
import org.dyn4j.geometry.Rectangle;
15+
import org.dyn4j.geometry.Vector2;
1616

1717
/**
1818
*
@@ -35,6 +35,11 @@ public abstract class Goal implements SimulatedArena.Simulatable {
3535
protected Rotation3d pieceAngle = null;
3636
protected Angle pieceAngleTolerance = Angle.ofBaseUnits(15, Degrees);
3737

38+
protected final double minZ;
39+
protected final double maxZ;
40+
41+
protected final boolean allowGrounded;
42+
3843
/**
3944
*
4045
*
@@ -52,14 +57,15 @@ public static Rotation3d flipRotation(Rotation3d toFlip) {
5257
*
5358
* <h2>Creates a goal object </h2>
5459
*
55-
* @param arena The host arena of this goal
56-
* @param xDimension The x dimension of the default box collider.
57-
* @param yDimension The y dimension of the default box collider.
58-
* @param height The height or z dimension of the default box collider.
60+
* @param arena The host arena of this goal
61+
* @param xDimension The x dimension of the default box collider.
62+
* @param yDimension The y dimension of the default box collider.
63+
* @param height The height or z dimension of the default box collider.
5964
* @param gamePieceType the string game piece type to be handled by this goal.
60-
* @param position The position of this goal.
61-
* @param isBlue Wether this is a blue goal or a red one.
62-
* @param max How many pieces can be scored in this goal.
65+
* @param position The position of this goal.
66+
* @param isBlue Wether this is a blue goal or a red one.
67+
* @param max How many pieces can be scored in this goal.
68+
* @param allowsGrounded Wether or not grounded pieces can be scored in this goal
6369
*/
6470
public Goal(
6571
SimulatedArena arena,
@@ -69,7 +75,8 @@ public Goal(
6975
String gamePieceType,
7076
Translation3d position,
7177
boolean isBlue,
72-
int max) {
78+
int max,
79+
boolean allowGrounded) {
7380

7481
xyBox = new Rectangle(xDimension.in(Units.Meters), yDimension.in(Units.Meters));
7582
this.height = height;
@@ -80,6 +87,11 @@ public Goal(
8087
this.elevation = position.getMeasureZ();
8188
this.isBlue = isBlue;
8289

90+
this.allowGrounded = allowGrounded;
91+
92+
minZ = elevation.in(Units.Meters);
93+
maxZ = minZ + height.in(Units.Meters);
94+
8395
xyBox.translate(new Vector2(position.getX(), position.getY()));
8496
}
8597

@@ -88,13 +100,14 @@ public Goal(
88100
*
89101
* <h2>Creates a goal object with no scoring max.</h2>
90102
*
91-
* @param arena The host arena of this goal.
92-
* @param xDimension The x dimension of the default box collider.
93-
* @param yDimension The y dimension of the default box collider.
94-
* @param height The height or z dimension of the default box collider.
103+
* @param arena The host arena of this goal.
104+
* @param xDimension The x dimension of the default box collider.
105+
* @param yDimension The y dimension of the default box collider.
106+
* @param height The height or z dimension of the default box collider.
95107
* @param gamePieceType the string game piece type to be handled by this goal.
96-
* @param position The position of this goal.
97-
* @param isBlue Wether this is a blue goal or a red one.
108+
* @param position The position of this goal.
109+
* @param isBlue Wether this is a blue goal or a red one.
110+
* @param allowsGrounded Wether or not grounded pieces can be scored in this goal
98111
*/
99112
public Goal(
100113
SimulatedArena arena,
@@ -103,8 +116,9 @@ public Goal(
103116
Distance height,
104117
String gamePieceType,
105118
Translation3d position,
106-
boolean isBlue) {
107-
this(arena, xDimension, yDimension, height, gamePieceType, position, isBlue, 99999);
119+
boolean isBlue,
120+
boolean allowsGrounded) {
121+
this(arena, xDimension, yDimension, height, gamePieceType, position, isBlue, 99999, allowsGrounded);
108122
}
109123

110124
/**
@@ -118,7 +132,7 @@ public void simulationSubTick(int subTickNum) {
118132
/// Use list filtering for more efficient bulk checking.
119133
// Get all pieces of our type as a list.
120134
arena.getGamePiecesByType(gamePieceType).stream()
121-
.filter(gamePiece -> !checkGrounded(gamePiece))
135+
.filter(gamePiece -> checkGrounded(gamePiece))
122136
.filter(this::checkValidity)
123137
.limit(max - gamePieceCount) // Only score what we can
124138
.forEach(
@@ -134,7 +148,7 @@ public void simulationSubTick(int subTickNum) {
134148
*
135149
* <h2>Sets the angle to be used when checking game piece rotation.
136150
*
137-
* @param angle The angle that pieces should have when interacting with this goal
151+
* @param angle The angle that pieces should have when interacting with this goal
138152
* @param angleTolerance The tolerance to be used in checking said angle.
139153
*/
140154
public void setNeededAngle(Rotation3d angle, Angle angleTolerance) {
@@ -176,20 +190,20 @@ protected boolean checkValidity(GamePiece gamePiece) {
176190
/**
177191
*
178192
*
179-
* <h2>Checks whether the submitted game piece is grounded </h2>
193+
* <h2>Checks whether the submitted game piece is grounded and if this is acceptable </h2>
180194
*
181195
* @param gamePiece The game piece to have its groundedness checked.
182-
* @return Whether the piece is grounded.
196+
* @return Whether the piece is acceptable for this goal.
183197
*/
184198
protected boolean checkGrounded(GamePiece gamePiece) {
185-
return gamePiece.isGrounded();
199+
return allowGrounded || !gamePiece.isGrounded();
186200
}
187201

188202
/**
189203
*
190204
*
191205
* <h2>Checks wether or not the submitted game piece has a rotation able to be scored in this goal </h2>
192-
* <p>
206+
*
193207
* By default the rotation needed and tolerance may be set using the {@link Goal#setNeededAngle(Rotation3d, Angle)}
194208
* function. However rotation checks may be handled differently by some children making this not apply. Additionally
195209
* be aware that this function only supports pitch and yaw, not role. If support for roll is needed a custom
@@ -208,13 +222,13 @@ protected boolean checkRotation(GamePiece gamePiece) {
208222
flipRotation(gamePiece.getPose3d().getRotation()).minus(pieceAngle);
209223

210224
return new Rotation3d(Degrees.of(0), normalDiff.getMeasureZ(), normalDiff.getMeasureZ())
211-
.getMeasureAngle()
212-
.in(Degrees)
213-
< pieceAngleTolerance.in(Degrees)
225+
.getMeasureAngle()
226+
.in(Degrees)
227+
< pieceAngleTolerance.in(Degrees)
214228
|| new Rotation3d(Degrees.of(0), flippedDiff.getMeasureZ(), flippedDiff.getMeasureZ())
215-
.getMeasureAngle()
216-
.in(Degrees)
217-
< pieceAngleTolerance.in(Degrees);
229+
.getMeasureAngle()
230+
.in(Degrees)
231+
< pieceAngleTolerance.in(Degrees);
218232
}
219233

220234
/**
@@ -228,8 +242,6 @@ protected boolean checkRotation(GamePiece gamePiece) {
228242
protected boolean checkCollision(GamePiece gamePiece) {
229243
// Call our values just once.
230244
var pose = gamePiece.getPose3d();
231-
double minZ = elevation.in(Units.Meters);
232-
double maxZ = minZ + height.in(Units.Meters);
233245

234246
return xyBox.contains(new Vector2(pose.getX(), pose.getY())) && pose.getZ() >= minZ && pose.getZ() <= maxZ;
235247
}
@@ -238,7 +250,7 @@ protected boolean checkCollision(GamePiece gamePiece) {
238250
*
239251
*
240252
* <h2>Function to check wether the velocity of potential game pieces is acceptable.</h2>
241-
* <p>
253+
*
242254
* The default implementation of this function always returns true so any velocity checks will need to be
243255
* implemented by children classes.
244256
*
@@ -273,7 +285,7 @@ public boolean isFull() {
273285
*
274286
*
275287
* <h2>Adds points when a piece has been successfully scored in this goal</h2>
276-
* <p>
288+
*
277289
* Since this function is the only trigger called when a piece is scored it may handle other small things outside of
278290
* adding points.
279291
*/
@@ -285,7 +297,7 @@ public boolean isFull() {
285297
* <h2>Displays game pieces to advantage scope if applicable.</h2>
286298
*
287299
* @param drawList a list of {@link Pose3d} objects used to visualize the positions of the game pieces on
288-
* AdvantageScope
300+
* AdvantageScope
289301
*/
290302
public abstract void draw(List<Pose3d> drawList);
291303

yagsl/java/swervelib/simulation/ironmaple/simulation/IntakeSimulation.java

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
package swervelib.simulation.ironmaple.simulation;
22

3+
import static edu.wpi.first.units.Units.Meters;
4+
35
import edu.wpi.first.math.MathUtil;
46
import edu.wpi.first.units.measure.Distance;
7+
import swervelib.simulation.ironmaple.simulation.drivesims.AbstractDriveTrainSimulation;
8+
import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation;
9+
import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.ReefscapeCoralAlgaeStack;
10+
11+
import java.util.ArrayDeque;
12+
import java.util.Objects;
13+
import java.util.Queue;
14+
import java.util.function.Predicate;
515
import org.dyn4j.collision.CollisionBody;
616
import org.dyn4j.collision.Fixture;
717
import org.dyn4j.dynamics.Body;
@@ -13,16 +23,6 @@
1323
import org.dyn4j.geometry.Vector2;
1424
import org.dyn4j.world.ContactCollisionData;
1525
import org.dyn4j.world.listener.ContactListener;
16-
import swervelib.simulation.ironmaple.simulation.drivesims.AbstractDriveTrainSimulation;
17-
import swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation;
18-
import swervelib.simulation.ironmaple.simulation.seasonspecific.reefscape2025.ReefscapeCoralAlgaeStack;
19-
20-
import java.util.ArrayDeque;
21-
import java.util.Objects;
22-
import java.util.Queue;
23-
import java.util.function.Predicate;
24-
25-
import static edu.wpi.first.units.Units.Meters;
2626

2727
/**
2828
*
@@ -43,9 +43,9 @@
4343
* <p>A game piece is collected if the following conditions are met:
4444
*
4545
* <ul>
46-
* <li>1. The type of the game piece ({@link swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation#type})
46+
* <li>1. The type of the game piece ({@link org.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation#type})
4747
* matches {@link #targetedGamePieceType}.
48-
* <li>2. The {@link swervelib.simulation.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation} is in contact with the intake
48+
* <li>2. The {@link org.ironmaple.simulation.gamepieces.GamePieceOnFieldSimulation} is in contact with the intake
4949
* (and not other parts of the robot).
5050
* <li>3. The intake is turned on via {@link #startIntake()}.
5151
* <li>4. The number of game pieces in the intake ({@link #gamePiecesInIntakeCount}) is less than {@link #capacity}.
@@ -79,10 +79,10 @@ public enum IntakeSide {
7979
* <p>This typically represents an In-The-Frame (ITF) Intake.
8080
*
8181
* @param targetedGamePieceType the type of game pieces that this intake can collect
82-
* @param driveTrainSimulation the chassis to which this intake is attached
83-
* @param width the width of the intake
84-
* @param side the side of the chassis where the intake is attached
85-
* @param capacity the maximum number of game pieces that the intake can hold
82+
* @param driveTrainSimulation the chassis to which this intake is attached
83+
* @param width the width of the intake
84+
* @param side the side of the chassis where the intake is attached
85+
* @param capacity the maximum number of game pieces that the intake can hold
8686
*/
8787
public static IntakeSimulation InTheFrameIntake(
8888
String targetedGamePieceType,
@@ -101,11 +101,11 @@ public static IntakeSimulation InTheFrameIntake(
101101
* <p>This typically represents an Over-The-Bumper (OTB) Intake.
102102
*
103103
* @param targetedGamePieceType the type of game pieces that this intake can collect
104-
* @param driveTrainSimulation the chassis to which this intake is attached
105-
* @param width the valid width of the intake
106-
* @param lengthExtended the length the intake extends out from the chassis when activated
107-
* @param side the side of the chassis where the intake is attached
108-
* @param capacity the maximum number of game pieces that the intake can hold
104+
* @param driveTrainSimulation the chassis to which this intake is attached
105+
* @param width the valid width of the intake
106+
* @param lengthExtended the length the intake extends out from the chassis when activated
107+
* @param side the side of the chassis where the intake is attached
108+
* @param capacity the maximum number of game pieces that the intake can hold
109109
* @return a new instance of {@link IntakeSimulation} that extends over the bumper
110110
*/
111111
public static IntakeSimulation OverTheBumperIntake(
@@ -154,9 +154,9 @@ private static Rectangle getIntakeRectangle(
154154
* <p>This constructor initializes an intake with a custom shape that is used when the intake is fully extended.
155155
*
156156
* @param targetedGamePieceType the type of game pieces that this intake can collect
157-
* @param driveTrainSimulation the chassis to which this intake is attached
158-
* @param shape the shape of the intake when fully extended, represented as a {@link Convex} object
159-
* @param capacity the maximum number of game pieces that the intake can hold
157+
* @param driveTrainSimulation the chassis to which this intake is attached
158+
* @param shape the shape of the intake when fully extended, represented as a {@link Convex} object
159+
* @param capacity the maximum number of game pieces that the intake can hold
160160
*/
161161
public IntakeSimulation(
162162
String targetedGamePieceType,
@@ -257,6 +257,22 @@ public boolean addGamePieceToIntake() {
257257

258258
return toReturn;
259259
}
260+
/**
261+
*
262+
*
263+
* <h2>Adds a number of game pieces to the intake.</h2>
264+
*
265+
* If the number of pieces added would drive the intake above capacity the intake will only add pieces up to max.
266+
*
267+
* @param piecesToAdd The number of pieces to add too the intake.
268+
* @return Wether or not all game pieces could be added to the intake. Just because this returns false does not mean
269+
* that no pieces were added.
270+
*/
271+
public boolean addGamePiecesToIntake(int piecesToAdd) {
272+
boolean toReturn = gamePiecesInIntakeCount + piecesToAdd <= capacity;
273+
gamePiecesInIntakeCount = Math.max(gamePiecesInIntakeCount + piecesToAdd, capacity);
274+
return toReturn;
275+
}
260276

261277
/**
262278
*
@@ -318,28 +334,22 @@ private void flagGamePieceForRemoval(GamePieceOnFieldSimulation gamePiece) {
318334

319335
/* functions not used */
320336
@Override
321-
public void persist(ContactCollisionData collision, Contact oldContact, Contact newContact) {
322-
}
337+
public void persist(ContactCollisionData collision, Contact oldContact, Contact newContact) {}
323338

324339
@Override
325-
public void end(ContactCollisionData collision, Contact contact) {
326-
}
340+
public void end(ContactCollisionData collision, Contact contact) {}
327341

328342
@Override
329-
public void destroyed(ContactCollisionData collision, Contact contact) {
330-
}
343+
public void destroyed(ContactCollisionData collision, Contact contact) {}
331344

332345
@Override
333-
public void collision(ContactCollisionData collision) {
334-
}
346+
public void collision(ContactCollisionData collision) {}
335347

336348
@Override
337-
public void preSolve(ContactCollisionData collision, Contact contact) {
338-
}
349+
public void preSolve(ContactCollisionData collision, Contact contact) {}
339350

340351
@Override
341-
public void postSolve(ContactCollisionData collision, SolvedContact contact) {
342-
}
352+
public void postSolve(ContactCollisionData collision, SolvedContact contact) {}
343353
}
344354

345355
/**
@@ -405,7 +415,7 @@ public boolean isRunning() {
405415
* intake, and the intake is turned on, and it is the target game piece.
406416
*
407417
* @param customIntakeCondition a {@link Predicate} representing the custom condition for intake eligibility of game
408-
* pieces on the field
418+
* pieces on the field
409419
*/
410420
public void setCustomIntakeCondition(Predicate<GamePieceOnFieldSimulation> customIntakeCondition) {
411421
this.customIntakeCondition = customIntakeCondition;

0 commit comments

Comments
 (0)