Playback.h

Go to the documentation of this file.
00001 /* 
00002 
00003      The contents of this file are subject to the Mozilla Public License
00004          Version 1.1 (the "License"); you may not use this file except in
00005      compliance with the License. You may obtain a copy of the License at
00006      http://www.mozilla.org/MPL/
00007 
00008      Software distributed under the License is distributed on an "AS IS"
00009      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00010      License for the specific language governing rights and limitations
00011      under the License.
00012 
00013      The Original Code is the PID trajectory playback library.
00014 
00015      The Initial Developers of the Original Code are Andrew Crossan (ac@dcs.gla.ac.uk) 
00016          and John Williamson (jhw@dcs.gla.ac.uk) from University of Glasgow.
00017          
00018      Portions created by Andrew Crossan and John Williamson are Copyright (C) 2006.
00019      All Rights Reserved.
00020 
00021      Contributor(s): ______________________________________.
00022 
00023 */
00024 
00025 /* PID Trajectory Playback v1.1 -  A library for playing a trajectory on a force feedback device
00026  * To playback a trajectory on the haptic device using the controller  
00027  * 1. Initialise the controller using one of the CreateController functions
00028  * 2. Add a series of points for the trajectory using AddWaypoint
00029  * 3. Set the controller playing with StartPlayback
00030  * 4. At every servo loop update, call GetForce to get the controller force
00031  *    GetForce will return false when the playback is finished
00032  *
00033  * if the trajectory has been recorded at full sampling rate, SetPlaybackAtSampleRate(true)
00034  * can be used to playback at the approximate recorded trajectory speed
00035 */
00036 
00037 #pragma once
00038 
00039 
00040 #include "pid.h"
00041 #include "micolelib.h"
00042 
00043 #include "FF3DForceModel.h"
00044 using namespace Reachin;
00045 
00046 
00047 #define PLAY_AT_SAMPLE_RATE false
00048 #define ABSOLUTE_POSITIONING false
00049 
00050 #define BEAD_SPEED      100
00051 #define ERROR_THRESHOLD 10
00052 
00053 struct PtsList {
00054 // double time;
00055 
00056    double xPos, yPos, zPos;
00057 // double xVel, yVel, zVel; /* Added velocities jhw */
00058    PtsList *prev, *next;
00059 };  
00060 
00061 #define PID_PI                  3.141592
00062 #define PID_PI_BY_2             PID_PI / 2.0
00063 #define _PLAY_MICOLE_RATE 700
00064 
00065 enum Mode
00066 {
00067         PID_IDLE                                                = 0,
00068         PID_STICK_TO_POINT                              = 1,
00069         PID_MOVE_TO_STICK_POINT                 = 2,
00070         PID_PLAY                                                = 3,
00071         PID_MOVE_TO_PLAY_POINT                  = 4,
00072         PID_PAUSE                                               = 5,
00073         PID_CONSTRAIN                                   = 6,
00074         PID_MOVE_TO_CONSTRAIN_POINT             = 7,
00075 };
00076 
00077 class Playback
00078 {
00079 public:
00080         Playback();
00081         ~Playback();
00082 // Overrides
00083 public:
00084 
00085         Vec3f _stick_point;
00086         // Initialize a new PID controller with specfic values
00087         void CreateControllers(double p, double i, double d, double f, double out_filter,
00088                          double gain, double sat_low, double sat_high, double dead_zone);
00089 /*
00090  *      p: proportional control gain
00091  *      i: integral control gain
00092  *      d: derivative control gain
00093  *      f: input filter (for deriv. estimation)
00094  *      out_filter: output filtering
00095  *      gain: overall gain
00096  *      sat_low: minimum saturation point
00097  *      sat_high: maximum_saturation point
00098  */
00099 
00100         // Initialise with preset Phantom omni parameters
00101         // p = 0.3, i = 0.0005, d = 20.0, f = 0.09, out_filter = 0.09, gain = 0.2, sat_low = -3.0,
00102         // sat_high = 3.0, dead_zone = 0.0
00103         void CreateControllersForOmni();
00104 
00105         // Initialise PD controller with preset Phantom omni parameters
00106         // Using PD instead of PID will avoid force wind up when playback is resisted
00107         // p = 0.3, i = 0.0, d = 20.0, f = 0.09, out_filter = 0.09, gain = 0.2, sat_low = -3.0,
00108         // sat_high = 3.0, dead_zone = 0.0
00109         void CreatePDControllersForOmni();
00110 
00111         // Initialise with preset Phantom Premium 1.5parameters
00112         // p = 0.3, i = 0.00005, d = 30.0, f = 0.09, out_filter = 0.09, gain = 0.2, sat_low = -1.5,
00113         // sat_high = 1.5, dead_zone = 0.0
00114         void CreateControllersForPremium15();
00115         
00116         // Reset the's the state of the controller
00117         void ResetControllerState();
00118 
00119         // moves the current position in the playback to the start of the gesture
00120         void MoveToStartOfGesture();
00121         
00122         // gets the current mode of playback
00123         Mode GetMode();
00124         
00125         // sets the playback state to idle. ie stops playback
00126         void SetIdle();
00127 
00128         // toggles between pause and play. Pause will stop the 
00129         // gesture without returning to the start of the gesture
00130         void TogglePauseGesture();
00131 
00132         // Tries to control the users cursor to one specifc point
00133         // curPPos is the current device position, pt is the position to stick to
00134         void StickToPoint(double curPos[3], double pt[3]);
00135         
00136         // Sticks the cursor to the currentPosition specified
00137         // by curPos
00138         void StickToThisPoint(double curPos[3]);
00139 
00140         // sets the controller to playback one sample per update
00141         // if false, playback rate is controller through SetPlaybackSpeed
00142         // Note... this means that if the user resists moving, the gesture will
00143         // still continue
00144         void SetPlayAtSampleRate(bool pasr);
00145 
00146         // returns true if the controller is set to playback at
00147         // the sample rate
00148         bool GetPlayAtSampleRate();
00149 
00150         // call at every servo loop update
00151         // afeter the call, force will contain the force calculated by the controller
00152         bool GetForce(double pt[3], double force[3]);
00153 
00154         // Returns true only if not IDLE. In pPos, the current x, y, z playback position or
00155         // stick point position will be returned
00156         bool GetPlaybackPos(double pPos[3]);
00157 
00158         // called to set the trajectory to play. You MUST still call GetForce every 
00159         // servo loop update to get the force of th playback
00160         // either specify a trajectory explictly by passing in a list of points
00161         // or if no list is provided, the pre-built (with AddWaypoint) trajectory 
00162         // is used
00163         void StartPlayback(PtsList *pt, double curPos[3]); // playback waypoints pt
00164         void StartPlayback(double curPos[3]); // playback currently stored waypoints 
00165 
00166 
00167         // called to set the trajectory to constrain the user to. You MUST still call 
00168         // GetForce every servo loop update to get the force of th playback
00169         // the pre-built (with AddWaypoint) trajectory is used for the constrain path
00170         // curPos is the currentPosition of the device
00171         // if using absolute positioning, the controller will initially go into 
00172         // PID_MOVE_TO_CONSTRAIN_POINT mode
00173         void StartConstrain(double curPos[3]);
00174 
00175         // set the speed of playback in mm/update if not in playback_at_sample_rate mode 
00176         // default is 100
00177         void SetPlaybackSpeed(double v);
00178 
00179         // clears the current trajectory
00180         void ClearPath();
00181 
00182         // add a waypoint to the end of the current trajectory. This is used in conjunction
00183         // with StartPlayback(double curPos[3])... 
00184         // using StartPlayback(PtsList *pt, double curPos[3]) will overwrite any trajectory
00185         // built with AddWaypoint with the list of points specified
00186         void AddWaypoint(double pt[3]);
00187 
00188         // load a gesture from a file fName is the path a name of the file
00189         // returns true if the file is found and false otherwise
00190         // File Format
00191         // time1, pt1_x, pt1_y, pt1_z
00192         // time2, pt2_x, pt2_y, pt2_z
00193         // time3, pt2_x, pt2_y, pt2_z
00194         // .......
00195         bool LoadGestureFile(char *fName);
00196 
00197         // Saves the current gesture to a file fName is the path a name of the file
00198         // returns true if the file can be created and false otherwise
00199         // File Format
00200         // time1, pt1_x, pt1_y, pt1_z
00201         // time2, pt2_x, pt2_y, pt2_z
00202         // time3, pt2_x, pt2_y, pt2_z
00203         // .......
00204         bool SaveGestureFile(char *fName);
00205 
00206         // absPos == True to use absolute Positioning for gesture 
00207         // absPos == False to start gesture at the current postion
00208         void UseAbsolutePositioning(bool absPos);
00209 
00210         // The error threshold is the distance that the device has to get
00211         // to the sample position before the trajectory is moved on to the 
00212         // next point. This is measured in mm (default 10mm)
00213         void SetErrorThreshold(double e);
00214         double GetErrorThreshold();
00215 
00216         // cap the maximum force from the integrator to avoid wind up
00217         // for the CreateControllersForOmni and the CreateControllersForPremium15,
00218         // this is automatically set to the controller max force cap
00219         void SetIntegratorForceCap(double maxforce);
00220 
00221         void stickToPointAndGetForce(Vec3f pos, Vec3f dest, Vec3f& force);
00222 
00223 
00224 private:
00225         
00226         control_state *control_x, *control_y, *control_z; // Pos controllers
00227         PtsList *head, *cur, *end;
00228         PtsList *headToPt, *curToPt, *endToPt;
00229         double startPos[3], stickPoint[3], stickBeadPos[3], beadPos[3], beadSpeed;
00230         double startTime, prevTime;
00231         bool playAtSampleRate;
00232         bool absolutePositioning;
00233         double err_thresh;
00234 
00235         Mode mode;
00236 
00237         // helper functions for stick to Point  
00238         void CreateGestureToPoint(double curPos[3], double thePoint[3]);
00239         void FreeGestureToPoint();
00240         void MoveToPoint(double curPos[3], double pt[3], Mode m);
00241 
00242         // helper functions for constrain
00243         bool DoConstrain(double pPos[3], double force[3]);
00244 
00245         //Set the windup limit
00246         void SetIntegratorCap(double icap);
00247 
00248 
00249         // distance from cur along the pathway that the bead has moved in constrain
00250         // mode. This is used to ensure that the user can only move forwards along
00251         // the path therefore removing the tricky direction decision for sharp corners
00252         double curConstrainDist;
00253 
00254         //debug
00255         double a;
00256         double distFromPrev;
00257 };

Generated on Tue Oct 16 17:10:43 2007 for Micole by  doxygen 1.4.7