00001
00002 #ifndef INCLUDED_SSC32Driver_h_
00003 #define INCLUDED_SSC32Driver_h_
00004
00005 #include "local/DeviceDriver.h"
00006 #include "local/MotionHook.h"
00007 #include "local/DataSource.h"
00008 #include "local/CommPort.h"
00009 #include "Shared/plist.h"
00010 #include <iostream>
00011
00012
00013 class SSC32Driver : public virtual DeviceDriver, public MotionHook, public DataSource, public virtual plist::PrimitiveListener {
00014 public:
00015 static const unsigned int NUM_SERVO=32;
00016 static const unsigned int NUM_INPUT=4;
00017 static const int UNUSED=-1;
00018
00019 explicit SSC32Driver(const std::string& name)
00020 : DeviceDriver(autoRegisterSSC32Driver,name), MotionHook(), DataSource(),
00021 servos(NUM_SERVO,UNUSED), inputs(NUM_INPUT,UNUSED),
00022 minPW(NUM_SERVO,500), maxPW(NUM_SERVO,2500), buttonMode(NUM_INPUT,false),
00023 sparse(false), commName(), queryServos(false), motionActive(false), sensorsActive(false), lastSensor(), frameNumber(0)
00024 {
00025 for(unsigned int i=0; i<NumOutputs && i<NUM_SERVO; ++i)
00026 servos[i]=i;
00027 for(unsigned int i=0; i<NumSensors && i<NUM_INPUT; ++i)
00028 inputs[i]=i;
00029 addEntry("OutputMap",servos,"For each of the SSC32's servo pins, lists the output index it should take its values from; -1 to mark unused");
00030 addEntry("InputMap",inputs,"For each of the SSC32's input pins, lists the sensor index it should send its value to; -1 to mark unused");
00031 addEntry("MinPulseWidth",minPW,"The low end of the servo's legal pulse width range (may correspond to unreachable position, use RobotInfo's outputRange[] to limit motion, not this)");
00032 addEntry("MaxPulseWidth",maxPW,"The high end of the servo's legal pulse width range (may correspond to unreachable position, use RobotInfo's outputRange[] to limit motion, not this)");
00033 addEntry("ButtonMode",buttonMode,"Controls interpretation of the input pin.\nFalse means directly measure voltage, true means test for high (1),\nhigh now but low was detected in interval (0.5), or low (0).\nButton mode implies interpreting inputMap value as a button index instead of sensor index.");
00034 addEntry("SparseUpdates",sparse,"If true, only send servo positions to SSC when they change, instead of all servos on every update (don't use a lossy transport like UDP if you turn this on!)");
00035 addEntry("CommPort",commName,"The name of the comm port where output will be sent");
00036 addEntry("QueryServos",queryServos,"If set to true, will attempt to query the servo positions with each sensor update.\nThis may decrease the sampling frequency");
00037 }
00038 virtual ~SSC32Driver() {}
00039
00040 virtual std::string getClassName() const { return autoRegisterSSC32Driver; }
00041
00042 virtual MotionHook* getMotionSink() { return dynamic_cast<MotionHook*>(this); }
00043 virtual void getSensorSources(std::map<std::string,DataSource*>& sources) {
00044 sources.clear();
00045 sources["Sensors"]=dynamic_cast<DataSource*>(this);
00046 }
00047
00048 virtual void motionStarting();
00049 virtual void motionStopping();
00050 virtual void motionCheck(const float outputs[][NumOutputs]);
00051
00052 virtual unsigned int nextTimestamp();
00053 virtual const std::string& nextName() { return instanceName; }
00054 virtual unsigned int getData(const char *& payload, unsigned int& payloadSize, unsigned int& timestamp, std::string& name);
00055 virtual void setDataSourceThread(LoadDataThread* th);
00056
00057 virtual void plistValueChanged(const plist::PrimitiveBase& pl);
00058
00059 plist::ArrayOf<plist::Primitive<int> > servos;
00060 plist::ArrayOf<plist::Primitive<int> > inputs;
00061 plist::ArrayOf<plist::Primitive<unsigned int> > minPW;
00062 plist::ArrayOf<plist::Primitive<unsigned int> > maxPW;
00063 plist::ArrayOf<plist::Primitive<bool> > buttonMode;
00064 plist::Primitive<bool> sparse;
00065 plist::Primitive<std::string> commName;
00066 plist::Primitive<bool> queryServos;
00067
00068 protected:
00069
00070 void provideOutput(unsigned int idx) { if(idx<NumOutputs) providingOutput(idx); }
00071
00072 void ignoreOutput(unsigned int idx) { if(idx<NumOutputs) ignoringOutput(idx); }
00073
00074
00075 virtual void setServo(std::ostream& ss, unsigned int servoIdx, float v);
00076
00077 virtual float getServo(unsigned int servoIdx, unsigned int pw);
00078
00079 virtual float getAnalog(unsigned int inputIdx, unsigned char s);
00080
00081 virtual float getDigital(unsigned int inputIdx, unsigned char cur, unsigned char latch);
00082
00083 bool motionActive;
00084 bool sensorsActive;
00085 std::string lastSensor;
00086 unsigned int frameNumber;
00087
00088 private:
00089
00090 static const std::string autoRegisterSSC32Driver;
00091 };
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 #endif