Switch branches/tags
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
..
Failed to load latest commit information.
cmake.man.motion
debug
gaits
mathematica
octave
AbstractGait.cpp
AbstractGait.h
BaseFreezeCommand.cpp
BaseFreezeCommand.h
BodyJointCommand.cpp
BodyJointCommand.h
ChainQueue.cpp
ChainQueue.h
ChopShop.cpp
ChopShop.h
ChoppedCommand.cpp
ChoppedCommand.h
CoordHeadCommand.h
FreezeCommand.h
Gait.cpp
Gait.h
GaitCommand.h
GaitConstants.h
HeadJointCommand.cpp
HeadJointCommand.h
HeadMoves.py
HeadProvider.cpp
HeadProvider.h
JointCommand.h
LinearChoppedCommand.cpp
LinearChoppedCommand.h
Makefile
MetaGait.cpp
MetaGait.h
Motion.cpp
Motion.h
MotionCommand.h
MotionConstants.h
MotionConstants.py
MotionInterface.cpp
MotionInterface.h
MotionProvider.h
MotionSwitchboard.cpp
MotionSwitchboard.h
NullBodyProvider.h
NullHeadProvider.h
NullProvider.cpp
NullProvider.h
Observer.cpp
Observer.h
PreviewController.cpp
PreviewController.h
PyMotion.cpp
PyMotion.h
README.tex
RobotGaits.py
ScriptedProvider.cpp
ScriptedProvider.h
SensorAngles.cpp
SensorAngles.h
SetHeadCommand.h
SmoothChoppedCommand.cpp
SmoothChoppedCommand.h
SpringSensor.cpp
SpringSensor.h
Step.cpp
Step.h
StepCommand.h
StepGenerator.cpp
StepGenerator.h
StiffnessModes.py
SweetMoves.py
UnfreezeCommand.h
WalkCommand.h
WalkController.h
WalkProvider.cpp
WalkProvider.h
WalkingArm.cpp
WalkingArm.h
WalkingConstants.h
WalkingLeg.cpp
WalkingLeg.h
ZmpAccEKF.cpp
ZmpAccEKF.h
ZmpEKF.cpp
ZmpEKF.h
__init__.py
nao-motion.dia
switchmovesscript.py

README.tex

\documentclass[11pt]{article}
\usepackage{fullpage}
\usepackage{url}
\usepackage{hyperref}

\title{Documentation for the Northern Bites Motion Engine}
\author{Johannes Strom\\
\url{jstrom@gmail.com}}
\date{\today}

\begin{document}
\maketitle

\begin{abstract}
This README describes the architectural implementation of the motion engine for
the Northern Bites robot soccer team. This document's purpose is to show where
in the code you should look for the code that fulfills a particular function,
or which file might have instructions to lead you closer to that answer.

For information regarding the conceptual meaning of the algorithms and
architecture implemented here, I suggest you look at the following documents. TODO: put in links (currently available on the blog under 'Team History').
\begin{enumerate}
\item Dynamically Balanced Omnidirectional Humanoid Locomotion, by Johannes Strom
   Honors Thesis for the Bowdoin College Department of Computer Science, 2009
\url{http://robocup.bowdoin.edu/media/papers/theses/strom-humanoid-locomotion-2009.pdf}
\item  An Implementation of an Omnidirectional Walk Engine on a Nao Robot, by
   Johannes Strom, George Slavov and Eric Chown in RoboCup 2009, 2009
\url{http://robocup.bowdoin.edu/media/papers/strom-slavov-nao-omnidirectional-locomotion.pdf}
\item Northern Bites Team Report for the Standard Platform League, 2009 (to appear)
\item Presentation Slides: Biped Robot Locomotion.  \url{http://robocup.bowdoin.edu/public/docs/motion/nao-walking.pdf}.
\end{enumerate}

This PDF can be found at \url{http://robocup.bowdoin.edu/public/docs/motion/README.pdf}.
This version of the PDF was generated on \today.
\end{abstract}

\tableofcontents

\section{Motion Overview}
The motion system is tasked with controlling the motion of the robot. For other
modules in the code, access to this functionality is provided by sending
MotionCommands through the MotionInterface, which is provided on request.
There are many types of MotionCommands, an incomplete list is:
   WalkCommand, StepCommand, BodyJointCommand, HeadJointCommand, etc

Inside the motion system, the many ways of controlling the motion of the robot
are controlled by the MotionSwitchboard. This class presides over a (currently
small) set of MotionProviders, and determines which provider is currently the
provider that is controlling the motion of the robot.  Theoretically, there
could be multiple active providers at once: one for each of the robots chains
(limbs). In practice, there are only ever two simultaneously active providers:
one for head, and one for the 'Body' (which excludes the head)
Switching between providers occurs when a command associated with the non-active
provider is recieved by the MotionSwitchboard (usually through the
MotionInterface). This event causes a stop request to be sent to the active
provider, and the provider associated with the new request to become the
next provider.  When the active provider indicates it is no longer active,
the next provider becomes the current provider, and subsequently determines
the motion of the robot.

\section{MotionInterface}
As mentioned above, the MotionInterface provides access to motion functionality
for other parts of the code. Particularly, to Noggin and RoboGuardian.
The MotionInterface provides the ability to send commands to specific providers
as well as the ability to request stops on certain parts of the robot

\subsection{Wrapping into Python}
The file PyMotion.cpp houses all the wrapping code to allow access to the
various MotionCommands and the MotionInterface from within Python.  Duplicating
this functionality for a new type of MotionCommand should be relatively straight
forward by looking at the example code in that file.  Generally, it should be
sufficient to create a PyXXXCommand to wrap the Cxx version, and then also
to update the PyMotionInterface wrapper.

\section{WalkingProvider}
The WalkingProvider solves the locomotion problem. It takes as input several
types of MotionCommands, which are generally just desired directions of motion.
Its output is the sequence of joints which ideally causes the desired motion.

The WalkingProvider class is relatively empty - it constructs transition
commands which ensure that the robot is in the required motion stance before
beginning to walk. It also remembers the last motion command for each type
it handels.  When the WalkingProvider is asked for new joint values,
first processes any waiting commands which may have arrived since the last
time the walkprovider ran.  Then, it ticks through several of its children
classes, which do most of the actual work.

\subsection{StepGenerator}
The step generator's main job is to handle the regeneration of steps according
to the current motion vector. It also handles the crucial setup required to
start and stop walking.  In addition, it currently also handles tons of work
for the Controller and the Walking Leg, such as generating zmp reference values
and keeping track of how coordinate frames switch at the end of a double,single
support phase.

NOTE: My intention is to seriously reorganize parts of the Walking Architecture
soon.  Ideally, the step generator will become more of a glorified queue, and
zmp generation will be handled in the controller, etc. Also, since the walk
provider does so little right now, it is certainly possible to move the ticking
of the walkingleg and controller into there. This would also make it easier
to consolidate calls to inverse kinematics.

\subsection{Controller}
The controller's job is to generate com trajectories from zmp preview values.
Basically, this is just glorified matrix multiplication using some specially
generated matrices, which are hard coded into the class. Finding these
matrices can be done using octave (see the folder motion/octave).

First, you need to get Octave, which is open source. Then, you can open an
octave terminal by running the command ``octave'' in the terminal.
For starters, you can run the file setupobserver.m by typing
`source(setupobserver.m)' from the Octave terminal prompt.
This will generate all the appropriate
matrices, which you can access py simply typing their names. For example, the
state update matrix, $A_0$, can be accessed by typing `A0' on the octave
terminal.

The output of the controller is in a static world-centric I coordinate frame,
which needs to get translated to the F frame before it can be useful to walking.
This is currently handled by the StepGenerator. Ideally, eventually the I
coordinate frame will disapear entirely.

\subsection{WalkingLeg}
Using the locations of steps in the F (relative to support foot) coordinate
frame, the WalkingLeg determines the trajectories of the legs during the gait
cycle. For example, the way the swinging leg moves through the air is controlled
here, as is the mangitude of sensor feedback to the body posture.

The walking leg also handles instantaneous odometry reporting, which gets
compiled by the StepGenerator.

\subsection{Gaits}
A crucial part of the walking system is the tuning of the walking cylce by
storing constants in a Gait. This allows different tunings of the walk for
different robots, different speeds, or different purposes.

Each gait holds many constants which are organized into eight
different categories:

\begin{itemize}
\item The Robot's {\bf Stance} during walking
\item The size, speed, length of each {\bf Step}
\item The shape of the {\bf ZMP} preview curve
\item The magnitude of the joint {\bf Hack}
\item The nature of {\bf Sensor} feedback
\item The {\bf Stiffness} of the joints
\item Calibration of the {\bf Odo}metry
\item Movment of each {\bf Arm}
\end{itemize}

Each gait object is actually just a collection of static arrays. Each array
contains a varying number of parameters which each control a related aspect
of the walk. For example, the {\bf stance} array contains several constants
which determine the robot's stance while walking (body height from ground,
forward lean, etc).The size and
contents of these arrays are specified in GaitConstants.h -- be sure to read
(and keep up to date) the instructions at the top of the file for where you
need to make changes when adding a new gait parameter.

To handle switching between gaits, anytime a gait parameter is required,
this access is actually granted through the MetaGait, which manages the
gradual transition between the current and the next gait. It gets ticked
by the WalkProvider, and simply provides a linear interpolation between
the two, depending on the longest transtion time specified by the two gaits.

{\bf IMPORTANT!:} In order to tune the gait, it is CRUCIAL to understand how
the gait parameters are actually used in the code. While the relatively brief
descriptions of each parameter provided below may be helpful as a reference,
they do not provide a complete picture of what the gait parameters, and probably
most important, they will quickly become out of sync with exactly how the
constants are being used in the code. Thus, I STRONGLY encourage you to look
at the part of the code which is using the parameter you are tuning in order
to gain a complete understanding of what is happening.

{\bf IMPORTANT!:} Gait tuning is a finicky, {\bf NON-DETERMINISTIC}
process. This means, even with identical gait parameters, a robot will not
walk the same way each time, because of slight discrepancies in the flooring
or in the current given to each motor.  If you ever seriously begin tuning
the gait, there will most certainly come a time when for some reason or another
the changes you make to the gait are not actually being loaded by the robot (
this can happen for a wide variety of reasons: the code doesn't get uploaded,
you switched robots, and only were tuning a gait for a specific robot, etc).
In this case, you will at first think that the changes you are making help,
because that is what you want to believe. However, the robot's parameters are
not actually changing, and your preception is skewed!! To avoid falling
into this trap, small changes to the gait need to be tested over and over to
prove that modifying the parameter is actually helping. As with everything in
RoboCup: {\bf TEST TEST TEST TEST!}.


What follows is a more in depth description of each of the gait parameters
as of the 16th of July, 2009. Please note that these descriptions will quickly
become out of date. Also, please be aware of the unit conventions in the code
base. In Python, units are expressed in centimeters and degrees. In C++ they
are converted into units of mm and degrees.  This conversion is generally done
in the Python wrapping code. For Motion it is done in PyMotion.cpp.
The descriptions below are from the point of view of gait tuning, which is
generally done from Python, so we will discuss them in those units below.
For each constant, the idea is to explain physically what the constant
controls, and what the constant actually ``means'' (or does) to modify the
walking.

\subsubsection{Stance gait parameters}
The stance gait parameters control the default posture of the robot during
walking. Things like how far off the ground the robot is, how far the
legs are separated, etc.
\begin{itemize}
\item {\bf BODY HEIGHT} This is the constant height in cm of the
robot's origin from the
ground. Note that this is distinct from the height of the robot's center of mass
, and that after applying the 'Hacks' below in combination with potentially
lagging or unreliable motors means the height of the CoM might not actually be
constant in reality.

When the robot's origin is higher off the ground, the
joints in the legs need to move less during the course of step, but can't reach
as far. When the robot is closer to the ground, the robot can reach further,
but needs to move the joints faster to reach the same distance. In addition,
when the robot is closer to ground, the robot is stabler (a shorter preview
period is required).  Note: Theoretically, this constant needs to be consistent
with the one used to generate the controller using octave (see above). The
controller uses the height of the CoM to generate trajectories. Since the CoM
is not the same of the robot origin, this is currently incorrect in the code
base.  We use 31.0 cm for both constants.  In practice, the body height
value used in the controller simply shapes the curve the robot's center
follows, and it doesnt necessarily need to be exact since there are other
constants which need to be tuned as well to get the robot walking.


Note: We just picked 31 cm as a good guess for the constant and haven't changed
it. I believe this is a good value, and I think the other constants are far
more important in enabling a more stable walk. Also, I believe this constant
should never really be ``tweaked'' slightly to get a better walk.  However,
it may at some point be interesting to see if we can walk faster with the robot
closer to the ground.  The way this would probably work is to lower the CoM
so that the robot doesn't need to swing nearly as much, thereby reducing
(or maybe eliminating?) the double support phase entirely. This can allow
the motors to move at maximum speed to reach the maximum distance. There is of
course a tradeoff here, since as the robot is lowered, the motors need to move
faster to move the same distance anyway, so as you lower the robot, you would
need to achieve an equal reduction in the double support time to allow the
robot to still move as fast as it did when it was higher off the ground. This
of course presumes the limitation on the walk speed is that the maximum
velocity of the robot's joint is being reach and the walk is still stable. In
a test in Webots, I found that the kinematic limits of the robot will not allow
the robot to move faster than about 25cm/s in the forward directions when
the body height is 31cms, so I don't really think this constant is the limiting
factor right now.

\item {\bf BODY OFF X} This is the forward offset between the heel of the foot
and the robot's origin. The heel of the robot is the location directly below
the robot's ankle joints, and is not a good approximation of the center of
the foot in the forwrad direction. Thus, this constant should generally be
positive, and non zero to keep the robot's origin more centered over the
foot.  Note: This value is also used to initialize the controller correctly.
I think there may be a more elegant way to do this, since the controller
shouldn't need to care about the size of the robot's foot, etc.

Moving the body forwad relative to the feet keeps the robots weight centered
better, which results in a stabler walk.  When playing with the Y rotation
(see below), it is sometimes necessary to play with this constant.  Also,
if the robot is falling over backwards too much (such as in the dribble gait),
this constant may also need to be adjusted.


\item {\bf LEG SEPARATION Y}  This constant controls the horizontal separation
between the legs of the robot. Note!: this constant is not yet fully implemented
. In some places, it is used, in others it is not. It should be left at 5cm.

Theoretically, one could experiment with a wide more ``stable'' stance when
approaching the ball (to knock other robots over more easily), or with a
balance-beam type walk, which places the foot steps along a line. Right now,
this constant should not be changed.

\item {\bf BODY ROT Y} This constant controls the rotation of the robot about
the Y axis. This is forward lean of the robot. (Negative values are backward
 lean)

Rotating the body forward can greatly reduce the sway of the robot during
the walk because since the joints of the robot have some give in them. When the
robot is completely upright, the robot goes back and forth between on end of
this ``give'' and the other. By leaning the robot forward, the robot simply
pushes up against the forward direction of this give, and oscillates less.
On the other hand, leaning too far forward will cause the robot's feet to run
into the ground befor they reach their destination, which will cause serious
backlash, and create even greater oscialltions.

\item {\bf LEG ROT Z}  This constant controls the default rotation of the legs
relative to one another. The greater this constant, the more duck footed
the robot will walk.  The maximum value of this constant is about 90 degrees
at which point turning is impossible.  Theoretically, a pigeoned toed walk
is possible, but the values sent to the HYP angle are clipped at 0, so negative
values won't work.

\item {\bf TRANS TIME} The transition time defines how long it takes to switch
between gaits (in seconds). It is not clear exactly which category this
constant fits into, but it is obvious this constant needs to be increased
if the gait stance is different than normal.
\end{itemize}

\subsubsection{Step Gait Constants}
The following constants are (should be) associated directly with a step.
This means that there is no gradual transitioning when the gait is switched.
The next step generated after the new gait is set simply gets the StepConfig
attributes assigned to it.  The Step gait constants are the things which
determine how long, how far, how fast, etc a step occurs.

\begin{itemize}
\item {\bf DURATION}  The duration of the step is the inverse of the step
frequency. This determins the overall time taken for one double and single
support phase.

As the step duration is lowered, the distance that needs to be covered
in one gait cycle becomes less for a given input velocity. However, the
time allowed to move that distance also decreases, so the effect on the
speed of the legs is undetermined (depends of if the DBL SUPP P constant
changes of not).
\item {\bf DBL SUPP P} This constant determines the percent of the step
duration which is spent in double support.

The robot needs sufficient time to move the ZMP from the middle of one foot
to the next when the support foot changes. This occurs during double support.
When the absolute magntude of this time (DBL SUPP P times DURATION) becomes
smaller, the robot swings more violently. When the time is longer, the swing
is slower.  However, if the overal step duration is shorter, then a lower
time will still work because the ZMP doesn't need to stay in the middle of the
foot for as long. The end of effect of this strategy is that magnitude of
the swing is reduced.

With a shorter double support time, the robot has more overal time to spend
swinging the ``swinging'' leg to its destination, allowing it to move further
with the same velocity.  Since eventually, the velocities of the joints will
be the limiting factor in the walk speed, tuning this can be important.

\item {\bf STEP HEIGHT}  The step height controls how high the foot is lifted
from the ground during the single support phase of the walk.

Increasing this value can help stop the foot from running into the carpet
during the swinging. On the other hand, too large values of this can cause
more backlash if the robot falls onto the foot while it still has downward
velocity. This constant generally needs to be adjusted in tandem with the
hip hacks described below.

Also, I've made a note that this constant should probably be move to the
stance config section, but it could probably go both ways.

\item {\bf FOOT LIFT ANGLE} This is the maximum value of the angle that
we add to the Y-axis (approx. Ankle Pitch) for the swinging leg during
single support. The value is (currently) multiplied by a sine function
so the lift angle starts and ends at zero.

Increasing this value can help reduce the amount of step height, since
the foot is so long. It allows the front of the foot to lift higher above
the carpet, and allows walking over more uneven surfaces.  On the other hand,
this angle increase can also increase the likely-hood of the robot falling
over forwards or of the robot building up oscillation around the Y axis if
the robot falls onto its foot before the angle has reach zero.


\item {\bf MAX VEL X} This is the maximum forwad velocity of the robot in CM/s.
When a new step is created, its forward component is clipped according to
this constant.

Generally, moving faster is less stable than moving slowly.

\item {\bf MIN VEL X}This the maximum backward velocity of the robot. Note
 that this is not always the same as the negative of the forward maximum.
Note also that this is effectively the MINIMUM forward velocity, since it is
negative. (It is NOT the minumum MAGNITUDE of the velocity)

\item {\bf MAX VEL Y}
This is the maximum sideways velocity of the robot. The steps get clipped
according to both the positive and the negative of this constant. Note
that this constant should be positive or the clipping won't work right.

\item {\bf MAX VEL THETA}
This is maxmimum turning velocity of the robot in degrees/second.

\item {\bf MAX ACC X} This is the maximum forward
acceleration in cm/s per STEP.
The new step is compared to the last step, and clipped according to this.

\item {\bf MAX ACC Y}
This is the maximum sideways
acceleration in cm/s per STEP.
The new step is compared to the last step, and clipped according to this.
\item {\bf MAX ACC THETA}
This is the maximum turning acceleration of the robot in degs/s per STEP.
\item {\bf WALKING} This constant is supposed to decide if this gait is a
WALKING or NON-WALKING gait.  A value of 1.0 is walking, everything else is
not-walking.

The idea behind having gaits that are NON-WALKING is that transitioning to
and from them could supplant the need to switch to the ScriptedProvider in
certain circumstances. They would also allow testing things like sensor
feedback when the robot is not actually walkin (but the WalkingProvider is
still active). In practice, there were some implementation difficulties, so
this constant DOESNT WORK!  (but its still hooked up).

The idea was to only generate END STEPS when there is a NON-WALKING gait,
but there were two problems. This first is that the condition for quitting
out of the walking provider is decided based on END STEPS, so this gait
was always stopping after three steps. The other problem has something
to with the startStopScale in WalkingLeg, which also relies on END STEPS
This solution to this is possibly to make another type of STEP, which
doesnt do any walking (just double support).

\end{itemize}

A note about Elliptical Clipping.  We currently do ELLIPTICAL CLIPPING on the
gait vector in the Step class.  This means when we are only moving forward,
we can move at the maximum forward speed. When we also desire to move to the
side, we reduce proportionally the forward speed so the magnitude of the speed
in both X and Y axis does not lie outside the ellipse created by the MAX X and
MAX Y velocities.  Consider each desired velocity to be a 2D point in
cartesian space. Then, consider the ellipse  which is created by connecting the
point which has max. forward velocity and zero lateral velocity with the maximums in each sideways and also the backward direction. (This shape is actually egg like, since the max backward vel. is not always the same as the forward.)
This can of course also be extended into 3D to also include the turning. (Where
 the dimensions are: X-vel, Y-vel, Theta-vel.)

However, there is the fundamental problem that in order to determine an angle
from the XY velocity plane to the point in 3D space, it is necessary to
compare degreees to centimenters.  This is currently achieved by giving the
same weighting to the a turning velocity equal to maximum turn allowed by
the gait as to a forward velocity equal to the maximum forward speed allowed
by the gait.

In practice, there are two ways this needs to be improved. First, the ellipses
should become more square. This can be done by addin an addition to the radius
which depends on theta:
$xMax = [r + 1.1\sin(2\theta )]\cos(theta)$

Another thing which should probably change is that we need to measure
the maximum theta at full forward velocity. This may or may not be non zero
if it is non-zero, let this constant be $MFT$, then the new elipse might look
like:
$tMax = (r - MFT + \cdots)cos(\phi)$

\subsubsection{ZMP Gait Constants}
The ZMP Gait constants determine how we generate the ZMP preview required
by the controller.  The preview ZMP generated from each step determines
what the reference ZMP is, and thus what the CoM motion is when that planned
step becomes the support step.

\begin{itemize}
\item {\bf FOOT CENTER X}  This transitional constant currently determines
how long the ZMP should be extended over the support foot for a forward
step.  That is, when this constant is zero, the ZMP is targeted only at one
point, regardless if the robot is moving forward. When it is non zero (and
possitive), it spreads the ZMP preview over that length (in the forward dir.)
over the length of the step.

In practice, this was able to smooth out some oscillations when moving forward.
However, it causes some problems when there was no forward motion, so it
is currently not in a state to be used.

The name is also somewhat of a misnomer. I had intended to change this
constant to indicate where the center of the foot is (without moving the
location of the ZMP during the step). However, this is mostly already
accomplished by the BODY OFF X constant (above).

\item {\bf DBL SUP STATIC P}  This constant determines what percentage of
double support the ZMP preview remains static before and after the ZMP is
switched from the old support foot to the new one.

During double support, the ZMP is moved from one foot to the next using a
linear interpolation.  However, since it is not necessarily the case that
the foot has already touched down, and to increase overall stability, we can
wait to make this transition happen for just a bit.  In practice, we keep the
ZMP on the old support foot for half of this percentage of the double support
phase. Also, after transition the ZMP, we again wait half this percentage
with the ZMP on the other foot.

I'm not really sure if this constant is even important anymore. Theoretically,
it should help to make sure we wait to swing the body a bit longer so we dont
run the swinging foot into the ground during single support. On the other hand,
too large of value for this will cause more violent swinging.

\item {\bf L ZMP OFF Y, R ZMP OFF Y}  These constants determine how much extra
 to the left/right the ZMP reference is pushed to the side.

This constant helps to compensate for model inaccuracies, particularly for
the fact that the CoM is actually at 26.9cm, not 31.0 like we assume. In
addition, this constant also controls how far to the side we swing.
Controlling this is very important to getting a stable gait, and varies
considerably depending on the step duration. To get this adjustment right,
watch the robot as it walks. If the robot is not swinging enough to get the
feet off the ground for the entirety of the single support phase.
 
\item {\bf STRAFE ZMP OFF} This constant controls how far extra we swing
during strafing when we are going to bring the trailing foot next to the
leading foot. 

If the trailing foot is scraping the ground when it follows the leading foot,
it may be necessary to increase this constant.  Note that the constant is
multiplied agains the lateral component of the step destination. This means
that for larger (longer) lateral steps, the extra amoung we swing is greater.

Note: this does NOT control how much extra we swing when the leading foot
is strafing. That constant might be nice, but would be much harder to
implement.

Note: the units of this constant are a bit weird. First, they are NOT converted
when being sent between Python and C++. They are something like
mm / mm.
\item {\bf TURN ZMP OFF} This constant is similar to the strafe offset. It
controls how far extra we swing when bringing the trailing leg parrallel
during turning.

As for the strafe offeset, if the trailing leg is scraping the ground,
try increasing this constant.  The untis of the constant are something like mm/ rad.

\end{itemize}

A note about ZMP preview generation:  The fact that the ZMP moves so
discontontinuously from foot to foot is not really a big problem for the walk
because the control naturally smothes the trajectory of the CoM. However,
the Nao Devils claim using a bezir curve greatly increased the stabilit of
their walk. (They used it to make a smoother transition when moving the ZMP
from foot to foot).  We use  a linear interpolation during double support.

In practice, with a step duration of .4, a double support percentage of .25,
there are only 20 motion frames per gait cycle, and only 4 per double support
phase, so the exact method of moving the ZMP is probably not as imporant.

\subsubsection{Hack Gait Constants}
The hack layer on the Nao consists of a compensation on the hip joints
to make sure the leg is lifted correctly, compensating for the sag in the hip
joints.
\begin{itemize}
\item {\bf L HIP AMP, R HIP AMP}  This is angular value which directly added
to the hip pitch joint (or also the hip roll joint when turning). The amount
is added according to a trapezoid during the single support phase of walking.

This value should be adjusted to make sure the foot does not prematurely
collide with the ground during the swinging phase of the gait.
\end{itemize}
Note:  Jerome says there is an easy way to measure this hack for each robot,
by just making the robot stand (swung to the side, with one leg a bit higher)
, and then increase the hip
hack until the leg barely touches the ground.  Jerome also adds some portion
of the hip hack to the ankles. We do none of these things.

\subsubsection{Sensor Gait Constants}
The following constants control how sensor feedback is applied to the robot.
Both approaches detailed below try to use sensors to measure the posture of
the robot, and apply a compensation to the body tilt to reduce oscillation.

The basic idea is when the robot measures that it is not at the desired angle
it tries to first ``roll'' with the newly observed discrepancies. Then, it
tries to bring the robot back to the desired angle by reducing the amount of
compensation.

\begin{itemize}
\item {\bf FEEDBACK TYPE} This constant determines which type of sensor
feedback is used.  1.0 is spring modeled feedback, 0.0 is the old proportional
type.

The spring type models the amount of sensor feedback to angleX and angleY
as  a spring. Each motion frame, the acceleration of the system back to zero
is calculated according to a spring constant K, (see below).
This acceleration is then
factored into the velocity, and eventualy into the position (value) of the
amount of feedback.  The system is updated also with the difference between
the system and the measured value, multiplied by Gamma (below).

The proportional type applies a correction to angleX/Y whose magnitude is
a proportion of the difference between the desired angle and the measured.

Both types have a maximum amount of correction which can be applied.
\item {\bf GAMMA X, GAMMA Y} This is the constant percentage of the difference
between the measured and the desired angle which both models use as input.

For the spring model, when this constant is smaller, a smaller amount of
the measured difference is applied to the system, resulting in a slower
reaction to measured differences in the robot's posture from the sensors.

\item {\bf SPRING K X, SPRING K Y} This constant controls how much acceleration
is applied to the system depending on how far from equillibrium the system is.

When the constant is small, the robot will move back towards equillibrium much
more slowly or not all. When this constant is large, the robot should move
back to equillibrium more quickly, or potentially never apply any sensor
feedback at all.
\item {\bf MAX ANGLE X, MAX ANGLE Y} This determines the maximum magnitude
of compensation applied to angleX/Y.

When this value is large, the robot
will adjust its posture much more to compensate for large disturbances, but
depending on the other sensor constants above, it may never be able to
return to equillibrium.
\item {\bf MAX ANGLE VEL}
For the proportional mode only, this determines the maximum amount of change
in the amount of sensor feedback applied.

Lowering this constant will reduce the response of the robot to distrubances,
but higher values can keep the robot from applying too highly accelerating
feedback.
\end{itemize}

\subsubsection{Stiffness Gait Constants}

The following constants control the stiffness of the robot during walking.
They are static.
\begin{itemize}
\item {\bf HIP} Controls the Hip Roll, Hip Pitch and Hip Yaw Pitch joint
stiffness.
\item {\bf KP} Controls the Knee Pitch stiffness
\item {\bf AP} Controls the Ankle Pitch stiffness
\item {\bf AR} Controls the Ankle Roll Stiffness
\item {\bf ARM} Controls the Shoulder Roll, ElbowRoll, Elbow Yaw stiffness
\item {\bf ARM PITCH} Controls the ShouldPitch stiffness.
\end{itemize}

For the stiffness low in the leg, lowering them can increase the amount you
can absorb shock in the legs, especially when the robot falls onto its feet.

When the stiffnesses are too low, the robot loses the ability to acurately
follow the deisred trajectories.

Note: The current (no pun intended) convention is to use the ``pwm\_mode'' in
the file /opt/naoqi/preferences/DCM.xml instead of ``current\_mode''.

\subsubsection{Odometry Gait Constants}

The constants {\bf X SCALE,Y SCALE,THETA SCALE} can be used to scale the output
of the odometry measurements according to measured results in real life.
For example, if you tell the robot to move, and watch its localization, then
you could use this constant to fix any discrepancies between how far 
localization thinks you moved, and how far you actually moved.  This is useful
particularly if you have a gait which slips considerably relative to the 
ground. Note, that this should be measured over several trials.

A possible extension could be to also encode the variance of the walk in
a similar manner.

\subsubsection{Arm Gait Constants}
There is only one arm gait constants, {\bf AMPLITUDE}. It controls 
the magnitude of the forward/backward swing, in degrees of the arms during
the walk.

This can be increased to potentially help the robot avoid rotating about
the Z axis during walking. Note that if the stiffness in the Should Pitch is
too low, this won't do anything. Also, be careful since there is a relatively
low limit on how far back the robots arm can move. Setting the magnitude above
that might cause some odd behavior.

\subsection{Step}
The Step class holds several things related to taking a step. It holds
the x,y,theta destination of this step, as well as the number of motion
frames needed to to complete the step, as well as the number of the frames
in each single support and double support phase. The steps also
hold information such as which feet they should be taken with, as well
as a complete copy of the stepConfig, zmpConfig, and stanceConfig.

When the step is created, it also ensures that the desired input destination
of the step meets some specific criteria (such as elliptical clipping, vel.
clipping and acceleration clipping.)

\subsection{Gait transitions commands}
Currently, a Scriped command is sent to ensure that the robot is in the correct
posture before starting walking.  This is ensured in MotionSwitchboard,
but the command is generated in WalkProvider.  In the past, this has been
the source of a really bad bug where when the stiffnesses of the robot
are remove, sometimes the robot jumps up violently when the stiffness
are renabled. We believe we have fixed this issue however.

\section{ScriptedProvider}
To be written...
\section{NullProvider}
The Null Provider's job is to take control when the stiffnesses of the robot
are removed in an emergency situation.  It becomes active when a FreezeCommand
is sent, and it relinquinshes control only when an UnFreezeCommand is sent.

When a freeze command is sent, the NullProvider takes control immediately on
the next ticking of the MotionSwitchboard, regardless of what another provider
is doing.  Regardless of any stop commands sent to it, the NullProvider will
only relinquish control once it recieves the appropriate UnFreezeCommand.


\section{Future Work}
What follows is an unedited list of my ideas how to make the motion system better.
\subsection{WalkProvider}
\begin{itemize}
\item Figure out a better way to use angleX/angleY among these might be
\begin{itemize}
   \item Use machine learning to discover the best constants in the spring model
   \item Add a constant Beta, which is the coefficient of friction, and goes on
      the diagonal in the state update matrix
   \item Right now, the max angle and the spring constant are not in sync. This
      means when the angle is measured at the max. value, the spring constant
      is not guaranteed to be of the right magnitude to eventually bring the
      'system' back to equillibrium.  Finding a constraint to ensure that this
      is the case would probably be best.
\end{itemize}
\item Control Nao with a Playstation Controller
\item To deal elegantly with having many gaits, we might consider implementing something
like was presented in the other motion talk about parameters spaces and submanifolds to
generate a good gait suited exactly for the speed/style etc we are trying to accomplish
\item Resolve the philosophical question of whether sending potentially unsafe
   commands to the walk engine should be limited from withing the walk provider
   or if this responsibility should live in the behaviors
\item More future work is in the file man/README.org
\end{itemize}
\end{document}