You’ve worked with decisions, loops, functions, collections, and objects. Now use those ideas together with fewer instructions. You can look back at earlier lessons, but write down your intended behavior before opening the solution.
What you’re building¶
An intake is the mechanism that brings a game piece into the robot. For this project we’re modeling its decisions, not connecting a physical motor. Positive output means collect, negative output means release, and zero means stop.
Copy a fresh project with python tools/start_exercise.py intake-model.
Work in student-work/intake-model, where intake.py and main.py are provided.
The starter runs, but its intake is deliberately inactive. Your job is to implement
the behavior and add checks; “it runs” is not yet “it meets the requirements.”
Requirements¶
Intakestarts with no piece and output zero.update(request, enabled, detected)remembers the latest sensor state.Disabled output is always zero.
A detected piece blocks positive collection, but reverse release remains possible.
An allowed request is limited to [-1, 1].
stop()makes output zero without inventing a new sensor reading.A
Robotobject owns an Intake;main.pydemonstrates a sequence of updates.Two instances keep independent state. The logic is defined in one reusable file.
Plan, then build¶
Make a table of inputs and expected outputs. Include exactly zero, both bounds, out-of-range values, disabled requests, and detected/not-detected conditions. Implement one rule, run the program, and add an assertion. Repeat until the table is covered. Avoid changing all the rules at once when one check fails.
Which rule wins?
Check disabled first. Next check whether positive collection is blocked by a piece. Only then limit an otherwise allowed request. Store the sensor state on every update.
Compare with a completed model
The maintained solution lives in examples/intake_model/solution. Run it with
python examples/intake_model/solution/main.py after your own attempt.
class Intake:
def __init__(self):
self.has_piece = False
self.output = 0.0
def update(self, request, enabled, detected):
self.has_piece = detected
if not enabled:
self.output = 0.0
elif detected and request > 0:
self.output = 0.0
elif request > 1.0:
self.output = 1.0
elif request < -1.0:
self.output = -1.0
else:
self.output = request
def stop(self):
self.output = 0.0
Check your model¶
Run your checks for collection, detection, release, disable, and independent
instances. Explain each attribute and why a method uses self. Temporarily change
the piece-detection rule from request > 0 to request < 0. Your checks for
collection and reverse release should catch the mistake. Restore the comparison.
Now limit forward collection to 0.4 while still allowing reverse down to -1.0. Write the expected results for requests of 0.2, 0.8, and -0.8 before editing. With the intake enabled and no piece detected, those results should be 0.2, 0.4, and -0.8. Run your earlier checks too, updating only expectations affected by the new limit.
In student-work/intake-model/README.md, describe how to run your model, what it
represents, and one limitation. Commit and push. The next stage uses the same
decisions inside an actual RobotPy program.