-
Notifications
You must be signed in to change notification settings - Fork 0
Arms
- Introduction
- Enabling arms
- Center, up and down
- Raising and lowering
- Waving
- Relaxing and holding
- Mounting and angles
- Going lower: the ArmServos module
Arms drives the two optional arm servos of the Otto Humanoid build. It is a facade over the ArmServos module.
Arms::raiseBoth();
Arms::waveRight(3);
Arms::lowerBoth();Arms are off by default, because the classic biped does not have them. While they are off, every Arms call is a silent no-op -- so the same sketch runs on both builds without #ifdefs.
Either take the preset:
OttoFlow::start(Preset::Humanoid); // arms on pins 6 (left) and 7 (right)or enable them explicitly, which is also how you move them to different pins:
OttoConfig cfg = Preset::Humanoid;
cfg.arms.leftPin = 10;
cfg.arms.rightPin = 7;
OttoFlow::start(cfg);Check at runtime whether this build has working arms:
if (Arms::isActive()) Arms::waveRight();The three whole-body arm poses:
Arms::center(); // rest: both arms to 90 degrees
Arms::up(); // both arms straight up (left 180, right 0)
Arms::down(); // both arms at the sides (left 0, right 180)Arms::home() is an alias for center(), matching Legs::center().
The left and right servos face opposite directions, so the same physical pose needs mirrored angles -- that is why up() sends 180 to one arm and 0 to the other. center() is the exception: 90 mirrors to itself, which is also what makes it the right pose for mounting the horns.
Arms::raiseBoth(); // both arms up (left 160, right 20)
Arms::lowerBoth(); // both arms down (left 20, right 160)
Arms::raiseLeft(); // left arm only
Arms::raiseRight();raiseBoth() and lowerBoth() are the partial versions of up() and down() -- same mirroring, but you choose how far. The angle you pass is the left servo's; the right one gets 180 - degrees.
Each takes an explicit angle when the defaults do not suit your build:
Arms::raiseBoth(120);
Arms::raiseLeft(90);
Arms::lowerBoth(0);Note
raiseLeft()andraiseRight()take raw servo angles -- one arm, no mirroring, so they mean opposite physical directions.raiseRight(20)is the right arm's "up". UseArmServos::positionBothDegrees()if you ever want the same raw angle on both.
Angles are 0 to 180 degrees and values above 180 are clamped. The movement is immediate -- the servo travels at its own speed and the call returns at once. To hold a pose, simply do not command a new angle.
Arms::waveRight(); // two waves
Arms::waveLeft(4);A wave raises the arm high, drops it part way, repeats that for the number of times you asked, and finally lowers the arm. Both sides are mirrored, so waveRight() and waveLeft() look identical on the robot -- in raw servo angles that is 160 / 120 / 20 on the left and 20 / 60 / 160 on the right. It blocks for about 600 ms per wave.
A greeting that reads well:
Mouth::show(Icon::Happy);
Voice::play(Sound::Hello);
Arms::waveRight(2);Arms::relax(); // detach: stop driving the servos
Arms::hold(); // drive them again
bool active = Arms::isActive();A detached servo consumes no current and makes no noise, and you can move the arm by hand -- useful while you check clearances or judge a mounting angle. A held servo resists being moved and hums quietly.
Motion::disable() relaxes the arms along with the legs. Motion::enable() re-attaches them, but only if arms are enabled in the configuration.
Note
Arms::hold()on a build witharms.enabled = falsedoes nothing, andisActive()staysfalse. That is the check to use in the serial console or a sketch that must know whether the hardware really exists.
What "up" means depends entirely on how you pressed the servo horns onto the splines. OttoFlow assumes the standard Humanoid build, where the two servos face opposite ways -- so every both-arm call mirrors, and up() means 180 on the left, 0 on the right.
If up() lowers both arms, both horns are on 180 degrees out. If it raises one arm and lowers the other, one horn is. Either way:
- Pull the horn off, rotate it 180 degrees, and press it back on -- the mechanical fix, and the better one.
- Or swap the calls in your sketch: use
down()where you mean up, andraiseBoth(20)/lowerBoth(160).
Before mounting the horns, centre the servos so you can align them with the arm at rest:
Arms::center();ArmServos::attach();
ArmServos::detach();
bool attached = ArmServos::isAttached();
ArmServos::positionLeftDegrees(140);
ArmServos::positionRightDegrees(40);
ArmServos::positionBothDegrees(90); // same angle to both
ArmServos::positionBothMirroredDegrees(140); // left 140, right 40
ArmServos::center(); ArmServos::up(); ArmServos::down();
ArmServos::waveRight(2);
ArmServos::waveLeft(2);The module is driven by the standard Arduino Servo library, independently of OttoDIYLib -- which is why arm angles are plain servo angles with no trim applied. If you need arm calibration, add a constant offset in your own code.
OttoFlow is licensed under GPL-3.0 and wraps OttoDIYLib. Buy the kits at ottodiy.com.
Prologue
Getting Started
The Basics
Digging Deeper
- Bench Testing
- Serial Console
- Calibration
- Bluetooth and the Otto App
- Modules
- The Driver
- Extending OttoFlow
Reference