-
Notifications
You must be signed in to change notification settings - Fork 0
homing
By default, the robot does not know it's own state. On boot, the first action a robot must take is determine what this is. In some cases, this can be accomplished right away through the use of sensors. In other cases, it must perform a controlled action until encountering a known condition.
Once a robot has been operated in a known way into this defined condition, you can now make assertions about the location. Then, you can more safely operate at higher powers, speeds, and using precise positional controls.
There's a number of routines that can generate effective homing routines.
In some cases, you can simply assert that at time of boot/power on, the robot is in a known state. This allows bypassing homing entirely.
While this is good enough for bringing and initial calibration, it's not robust or fault tolerant in actual gameplay.
Pros:
- Easy
- Bootup assertions can often be enforced by drive team's setup process.
- Bootup assertion is sometimes enforced by gravity, making the assertion pretty reliable
Cons:
- Hard stop changes will result in relative changes to the system.
- Deploying code or restarting the robot in unknown states can result in damage
For rotational systems, an absolute sensor allows direct reading of system state. This means homing is unnecessary for lower precision systems.
Due to Rev's handling of absolute encoder APIs and discontinuity locations, it may be advised to use the spark max's relative encoder for actual closed loop control; This means high precision systems will need to account for system backlash via motor control.
For linear systems, using a distance measuring sensor such as a Grapple LaserCAN or a string potentiometer can provide a known position.
Pros:
- Consistent
- Fast
- Robust against booting into unknown states
Cons:
- Does not handle system backlash or gear slop
- Requires controls/mechanical teams to preserve the sensor orientation relative to controlled system
Notes:
- For Rev Absolute encoders on the spark max, the encoder offset value must be saved in case of controller damage.
- For Rev Absolute encoders, watch out for the Periodic Frame Status; Absolute encoders are notably slower by default.
This is an active homing routine. For this, the system is driven in a known direction, until it encounters a hard stop. Once this occours, the motor changes from "free spin" or partly loaded current draw into stall current draw; Providing a sharp spike of power. By checking this power draw, you can assert the system state.
Pros:
- Very simple: No additional hardware
- Versatile, most systems with end-of-travel can be measured with current draw
- Slow; You do not want to home with high velocities.
- Relatively safe: By operating at a low current, you can easily move systems in unknown states safely.
Cons:
- Changes to system dynamics can change your "free spin" current draw. If this pushes the free spin above the expected stall current, the system will "home" instantly without motion.
- Current can be spikey, and for some systems filtering may be needed.
Notes:
- Pairs very well with known initial conditions that mitigate a need to travel. Being at a "zeroed" position makes this assertion virtually free.
This is an active homing routine. Power is provided, driving it at toward a hard stop/end of travel. Then, monitor an encoder for a specific rate of motion.
Pros:
- Same as Current limit, assuming operation is performed at a low permitted current.
Cons:
- Need to specifically check timers to ensure system motion is not caused by inertial factors
- Need to filter or debounce noisy velocity signals
Notes:
- Pairs very well with known initial conditions that mitigate a need to travel. Being at a "zeroed" position makes this assertion virtually free.
This is an active homing routine. In this case, once the robot is enabled, it is driven toward a known-good state, where it will encounter a limit switch at a defined position. Upon encountering the switch, you can assert the system state, defining a position and a fully homed system.
All routines should initially run at low power to avoid system damage.
For higher precision systems, you want to operate on the "edge" of the switch; This is usually done by discovering the switch with one motor direction to assert a rough location, then releasing the switch slowly and defining a precise location. However, this is very slow, and unlikely to be performed accurately during any other robot activity.
A similar method utilizes an Index switch; This is a switch that will be hit at a certain point in travel, but not strictly at an end. Index switches can be recover the position on systems with no end-of-travel (fully rotational systems). They can also be used in cases where you have end-of-travel but do not want to approach it; However, in those cases care must be provided to have a known startup state.
Pros:
- When set up on motor controllers, also serve as a "hard limit" switch; Ensuring that in loss of control, the motor stops even if not homed correctly.
- Can be used to trivially re-assert a known location at runtime. This allows continous correction for issues such as belt slip, validate other calibration, or upgrade less precise methods.
- Works for systems that cannot be
Cons:
- Requires additional hardware
- Troublesome to mount where needed, and getting precise locations is difficult
- Being located at the end of a motion, system faults are likely to break sensor.
- If sensors are not mounted or damaged, homing may fail entirely, leading to additional damage.
- Can be imprecise, as sensors may have a large trigger range.
- Can result in loss of range when used as hard limits as well.
- Requires some level of "known good" initial position to ensure you contact the switch efficiently
- Switch trigger position may not equal the desired zero state, and possibly require custom offsets.
- Usually requires end of travel to fully home.
Notes:
- When possible, using current limit routines is more practical, efficient, and requires doing less work.
This is an active calibration technique, with the goal of defining the position in a typical operating state, rather than just at bootup.
In most cases, complex gear trains have some amount of gap between gearing, creating a small amount of uncertainty. For belts and chain drives, this particular uncertainty can be relatively large. On angular systems, this can range from around 1/2 a degree on gear trains to around 5-10 for poorly maintained chains. This backlash will register as inconsistency between power cycles.
However, gravity will typically favor pushing on the gears in a specific way. By powering the motor to push the system up against gravity without disturbing it's position to a known homing point (a hard stop or absolute encoder), you can more precisely identify the system state, removing the uncertainty due to backlash, improving consistency and accuracy.
Pros:
- Mitigates the effect of wear on the robot
- Requires no additional hardware
- Relatively easy to implement
Cons:
- Potentially slow
- Likely cannot be performed in motion or during other active states
Notes:
- This is a task best handled at the very start of auto.
- In a pinch, an be handled with zero code without code by having a human turn the motor/gears during bootup to set backlash to desired position.
The following example showcases a complete homing routine declared as part of a subsystem.
SystemToHome extends Subsystem{
public boolean isHomed = false;
SystemToHome(){
//Register a trigger; Whenever we're enabled, but not homed, attempt to home.
new Trigger(Driverstation::isEnabled).and(isHomed==false).whileTrue(this.getHomingCommand());
}
private void setSystemAsNotHomed(){
isHomed = false;
motor.setCurrentLimits(4);
motor.enableBottomSoftLimits(false);
}
private void setSystemAsHomed(){
//Do any special logic, such as
motor.getEncoder().setPosition(3.7); // Assert known system state, whatever it is
motor.setCurrentLimits(40);
motor.enableBottomSoftLimits(true);
isHomed = true;
}
public Command getHomingCommand(){
return new FunctionalCommand(
()->{setSystemAsNotHomed()}, // reset the system state to allow the homing operation
()->{motor.set(-0.1);}, //drive system downward
(interrupted)->{if(!interrupted)setSystemAsHomed();}, //only set system as homed if the command successfully exited
()->{return currentdraw > 5}, // a condition that indicates we're at the known homing state
this
);
}The main structural notes are
- Use of a command declared in the subsystem. This is useful as it allows access to private functions and variables, allowing more flexibility and code clarity without additional passthrough operations.
- A trigger to manage homing. Triggers are great; Once declared, it'll register with the system EventLoop, and continously check the conditions, re-engaging the homing process until it successfully completes.
- A public boolean for
isHomed; Technically bad practice, but it's a low-overhead way to permit access to this variable to wait on completion of homing before doing a task (like a full auto sequence) -
setSystemAsHomedandsetSystemAsNotHomedhandle the logic to ensure the system is suited for operation in the known and unknown states.
A backlash compensation process is very similar. The primary difference is that you'd simply want to run your command against gravity at a known power for a set time, and perform any homing on completion. For an example, see (CalibrateShooter)[https://github.com/stormbots/Crescendo/blob/main/src/main/java/frc/robot/commands/CalibrateShooter.java]
An important consideration: It's wise to give drivers access to some level of homing operations, on a normally unused and difficult to press button. In the case of a failure or reset on the field, a "rehome the bot" button might be able to save the day, restoring expected operation to the bot and potentially prevent damage.