Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
MotionHook.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_MotionHook_h_ 00003 #define INCLUDED_MotionHook_h_ 00004 00005 #include "Shared/RobotInfo.h" 00006 #include <vector> 00007 00008 //! Interface for connections to remote hosts and hardware devices which should be polled with output values 00009 /*! - Override motionCheck() if your hardware needs to have a value specified for every output 00010 * on every update, regardless of whether it changes. 00011 * - Override motionUpdated() if you only need to process the outputs which have changed. 00012 * 00013 * You can expect to be called every FrameTime*NumFrame milliseconds in terms of simulator time. 00014 * However, keep in mind this is relative to SharedGlobals::timeScale (Config.Speed) in terms of 00015 * wall-clock time, and is also subject to the simulator being paused, set to full-speed mode, or hitting 00016 * a breakpoint in the debugger. See enteringRealtime() and leavingRealtime() if you want updates 00017 * when the user switches simulation modes, although there's still no way to get notification if a 00018 * debugger breakpoint is hit */ 00019 class MotionHook { 00020 public: 00021 //! constructor 00022 MotionHook() : verbose(0), isFirstCheck(true) {} 00023 00024 //! no-op destructor 00025 virtual ~MotionHook() {} 00026 00027 //! Called when motion process is starting 00028 virtual void motionStarting() {} 00029 00030 //! Called each time the motion process has polled active motion commands 00031 /*! When in realtime mode, this should be called every FrameTime*NumFrames (defined in the RobotInfo) 00032 * milliseconds if running at full speed. See enteringRealtime() and leavingRealtime(). 00033 * 00034 * This default implementation checks to see which outputs have changed value since the last call and 00035 * passes the summary on to motionUpdated(). #lastOutputs will be updated with the new values @e after 00036 * the call to motionUpdated(). 00037 * 00038 * If you need to process all the outputs on every frame, you only need to override this function. 00039 * Your subclass doesn't need to call the MotionHook implementation unless you want to have 00040 * lastOutputs updated for you. 00041 * 00042 * If you only need to process the @e changed outputs for each frame, override motionUpdated() instead. 00043 * motionUpdated() is always called for each update, even if there aren't any changes, so you can still 00044 * use that if there are some outputs which need to be updated every cycle. */ 00045 virtual void motionCheck(const float outputs[][NumOutputs]) { 00046 std::vector<size_t> changedIndices; 00047 changedIndices.reserve(NumOutputs); 00048 for(size_t i=0; i<NumOutputs; ++i) { 00049 if(isFirstCheck) { 00050 changedIndices.push_back(i); 00051 } else { 00052 for(size_t j=0; j<NumFrames; ++j) { // if *any* of the frames have changed, update the output 00053 if(outputs[j][i]!=lastOutputs[i]) { // (not just checking last frame for each output) 00054 changedIndices.push_back(i); 00055 break; 00056 } 00057 } 00058 } 00059 } 00060 motionUpdated(changedIndices,outputs); 00061 for(size_t i=0; i<NumOutputs; ++i) 00062 lastOutputs[i] = outputs[NumFrames-1][i]; 00063 isFirstCheck=false; 00064 } 00065 00066 //! Called by motionCheck(), after comparing the new output values to #lastOutputs, and before lastOutputs is updated 00067 /*! Override this if you only need to send commands to the hardware for values that have changed. 00068 * This function is always called for each update, even though changedIndices might be empty. */ 00069 virtual void motionUpdated(const std::vector<size_t>& /*changedIndices*/, const float /*outputs*/[][NumOutputs]) {} 00070 00071 //! Called when motion process is stopping 00072 virtual void motionStopping() { isFirstCheck=true; } 00073 00074 //! Called when the controller is going to be running in realtime mode, which is probably the normal mode you'd expect. 00075 /*! No guarantees though! You might be in realtime mode, but a debugger breakpoint will still pause things. */ 00076 virtual void enteringRealtime() {} 00077 00078 //! Called when leaving realtime mode, which means you have no idea when motionCheck is going to be called in terms of wall-clock time. 00079 /*! Argument set to true if entering full speed mode, which @e may mean motionCheck will be 00080 * called at a high(er) frequency, or slower the computation is overwhelming the host hardware. 00081 * However, if false, almost certainly indicates updates will be sparse. 00082 * 00083 * A non-realtime mode might be triggered if the user wants to pause the simulator/controller to debug something... 00084 * No guarantees though! The debugger might catch a breakpoint and stop things, and this won't be called! */ 00085 virtual void leavingRealtime(bool /*isFullSpeed*/) {} 00086 00087 //! Called by simulator thread to indicate level of verbosity for diagnostics and reporting errors 00088 virtual void setMotionHookVerbose(int v) { verbose=v; } 00089 00090 protected: 00091 //! stores current verbosity 00092 int verbose; 00093 //! set to false following the first motionCheck, reset to true by motionStopping 00094 bool isFirstCheck; 00095 //! stores the last frame of the outputs, updated by motionCheck() 00096 float lastOutputs[NumOutputs]; 00097 }; 00098 00099 /*! @file 00100 * @brief Describes MotionHook, an interface for connections to remote hosts and hardware devices which should be polled with output values 00101 * @author Ethan Tira-Thompson (ejt) (Creator) 00102 * 00103 * $Author: ejt $ 00104 * $Name: tekkotsu-4_0 $ 00105 * $Revision: 1.3 $ 00106 * $State: Exp $ 00107 * $Date: 2007/08/27 22:14:16 $ 00108 */ 00109 00110 #endif |
Tekkotsu Hardware Abstraction Layer 4.0 |
Generated Thu Nov 22 01:00:53 2007 by Doxygen 1.5.4 |