00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "xyPlatformConstants.hpp"
00029 #include "xyPlatformAxisHardware.hpp"
00030 #include <fstream>
00031 #include <iostream>
00032 #include <assert.h>
00033 #include <rtt/Method.hpp>
00034
00035 using namespace RTT;
00036 using namespace OCL;
00037 using namespace std;
00038
00039 namespace OCL
00040 {
00041
00042 class VelocityReaderXY : public SensorInterface<double>
00043 {
00044 public:
00045 VelocityReaderXY(Axis* axis, double maxvel) : _axis(axis), _maxvel(maxvel)
00046 {};
00047
00048 virtual ~VelocityReaderXY() {};
00049
00050 virtual int readSensor( double& vel ) const { vel = _axis->getDriveValue(); return 0; }
00051
00052 virtual double readSensor() const { return _axis->getDriveValue(); }
00053
00054 virtual double maxMeasurement() const { return _maxvel; }
00055
00056 virtual double minMeasurement() const { return -_maxvel; }
00057
00058 virtual double zeroMeasurement() const { return 0; }
00059
00060 private:
00061 Axis* _axis;
00062 double _maxvel;
00063 };
00064
00065 }
00066
00067 xyPlatformAxisHardware::xyPlatformAxisHardware(Event<void(void)>& maximumDrive, std::string configfile )
00068 : _axes(XY_NUM_AXIS),
00069 _axesInterface(XY_NUM_AXIS),
00070 _my_task_context("XYAxis"),
00071 _configfile(configfile),
00072 _initialized(false)
00073 {
00074
00075 double mmpsec2volt[XY_NUM_AXIS] = XY_SCALES;
00076 double encoderOffsets[XY_NUM_AXIS] = XY_ENCODEROFFSETS;
00077 double ticks2mm[XY_NUM_AXIS] = XY_PULSES_PER_MM;
00078 double jointspeedlimits[XY_NUM_AXIS] = XY_JOINTSPEEDLIMITS;
00079 double driveOffsets[XY_NUM_AXIS];
00080 ifstream offsetfile(_configfile.c_str(), ios::in); bool success = true;
00081 for (unsigned int i=0; i<XY_NUM_AXIS; i++){
00082 driveOffsets[i] = 0;
00083 if ( ! (offsetfile >> driveOffsets[i]) ) success = false;
00084 }
00085 if (!success) cout << "(xyPlatformAxisHardware) Offset file not read. Setting offsets to zero" << endl;
00086
00087 _comediDevAOut = new ComediDevice( 1 );
00088 _comediDevEncoder = new ComediDevice( 2 );
00089 _comediDevDInOut = new ComediDevice(3);
00090
00091 int subd;
00092 subd = 1;
00093 _comediSubdevAOut = new ComediSubDeviceAOut( _comediDevAOut, "xyPlatform", subd);
00094
00095 subd = 1;
00096 _comediSubdevDOut = new ComediSubDeviceDOut ( _comediDevDInOut, "xyPlatform", subd);
00097
00098 subd = 0;
00099
00100 _encoderInterface[0] = new ComediEncoder(_comediDevEncoder , subd , 6);
00101 _encoderInterface[1] = new ComediEncoder(_comediDevEncoder , subd , 7);
00102 _encoder[0] = new IncrementalEncoderSensor( _encoderInterface[0], -1000 * ticks2mm[0], encoderOffsets[0], X_AXIS_MIN_POS, X_AXIS_MAX_POS, 4096);
00103 _encoder[1] = new IncrementalEncoderSensor( _encoderInterface[1], -1000 * ticks2mm[1], encoderOffsets[1], Y_AXIS_MIN_POS, Y_AXIS_MAX_POS, 4096);
00104
00105
00106
00107
00108
00109 for (unsigned int i = 0; i < XY_NUM_AXIS; i++){
00110 _brake[i] = new DigitalOutput( );
00111
00112
00113 _vref[i] = new AnalogOutput( _comediSubdevAOut, i + 6 );
00114 _enable[i] = new DigitalOutput( );
00115
00116 _drive[i] = new AnalogDrive( _vref[i], _enable[i], 1.0 / mmpsec2volt[i], driveOffsets[i] / mmpsec2volt[i]);
00117
00118 _axes[i] = new Axis( _drive[i] );
00119 _axes[i]->limitDrive( jointspeedlimits[i] );
00120 _axes[i]->setLimitDriveEvent( maximumDrive );
00121 _axes[i]->setBrake( _brake[i] );
00122 _axes[i]->setSensor( "Position", _encoder[i] );
00123 _axes[i]->setSensor( "Velocity", new VelocityReaderXY(_axes[i], jointspeedlimits[i] ) );
00124
00125 _axesInterface[i] = _axes[i];
00126 }
00127
00128
00129 this->methods()->addMethod(method( "lock", &xyPlatformAxisHardware::lock, this), "lock axis", "axis", "axis to lock");
00130 this->methods()->addMethod(method( "unlock", &xyPlatformAxisHardware::unlock, this), "unlock axis", "axis", "axis to unlock");
00131 this->methods()->addMethod(method( "stop", &xyPlatformAxisHardware::stop, this), "stop axis", "axis", "axis to stop");
00132 this->methods()->addMethod(method( "getDriveValue", &xyPlatformAxisHardware::getDriveValue, this), "get drive value of axis", "axis", "drive value of this axis");
00133 this->methods()->addMethod(method( "addOffset", &xyPlatformAxisHardware::addOffset,this ), "Add offset to axis", "offset", "offset to add");
00134 this->methods()->addMethod(method( "getReference", &xyPlatformAxisHardware::getReference, this), "Get referencesignal from axis", "axis", "axis to get reference from");
00135 this->methods()->addMethod(method( "writePosition", &xyPlatformAxisHardware::writePosition, this), "Write value to axis", "axis","axis to write value to","q", "joint angle in radians");
00136 this->methods()->addMethod(method( "prepareForUse", &xyPlatformAxisHardware::prepareForUse, this), "Prepare robot for use");
00137 this->methods()->addMethod(method( "prepareForShutdown", &xyPlatformAxisHardware::prepareForShutdown, this), "Prepare robot for shutdown");
00138 }
00139
00140 xyPlatformAxisHardware::~xyPlatformAxisHardware()
00141 {
00142
00143 prepareForShutdown();
00144
00145
00146 ofstream offsetfile(_configfile.c_str(), ios::out);
00147 for (unsigned int i=0; i<XY_NUM_AXIS; i++)
00148 offsetfile << " " << (_axes[i]->getDrive()->getOffset());
00149
00150 for (unsigned int i = 0; i < XY_NUM_AXIS; i++){
00151
00152 delete _axes[i];
00153 }
00154
00155 delete _comediDevAOut;
00156 delete _comediDevEncoder;
00157 delete _comediSubdevAOut;
00158 delete _comediDevDInOut;
00159 delete _comediSubdevDOut;
00160
00161 }
00162
00163
00164 bool xyPlatformAxisHardware::prepareForUse()
00165 {
00166 if (!_initialized){
00167
00168 for(int i = 0; i < 24 ; i++) _comediSubdevDOut->switchOff( i );
00169
00170 _comediSubdevDOut->switchOn( 7 );
00171 _initialized = true;
00172 }
00173
00174
00175
00176 if (_initialized)
00177 return true;
00178 else
00179 return false;
00180 }
00181
00182
00183
00184
00185 bool xyPlatformAxisHardware::prepareForShutdown()
00186 {
00187 _comediSubdevDOut->switchOff(7);
00188 _initialized = false;
00189 return true;
00190 }
00191
00192
00193 std::vector<AxisInterface*>
00194 xyPlatformAxisHardware::getAxes()
00195 {
00196 return _axesInterface;
00197 }
00198
00199
00200
00201 void
00202 xyPlatformAxisHardware::unlock(int axis)
00203 {
00204 if (!(axis<0 || axis>XY_NUM_AXIS-1))
00205 _axes[axis]->unlock();
00206 }
00207
00208
00209 void
00210 xyPlatformAxisHardware::stop(int axis)
00211 {
00212 if (!(axis<0 || axis>XY_NUM_AXIS-1))
00213 _axes[axis]->stop();
00214 }
00215
00216
00217 void
00218 xyPlatformAxisHardware::lock(int axis)
00219 {
00220 if (!(axis<0 || axis>XY_NUM_AXIS-1))
00221 _axes[axis]->lock();
00222 }
00223
00224
00225
00226 double
00227 xyPlatformAxisHardware::getDriveValue(int axis)
00228 {
00229 if (!(axis<0 || axis>XY_NUM_AXIS-1))
00230 return _axes[axis]->getDriveValue();
00231 else
00232 return 0.0;
00233 }
00234
00235
00236 void
00237 xyPlatformAxisHardware::addOffset(const std::vector<double>& offset)
00238 {
00239 assert(offset.size() == XY_NUM_AXIS);
00240 for (unsigned int i=0; i<XY_NUM_AXIS; i++)
00241 _axes[i]->getDrive()->addOffset(offset[i]);
00242 }
00243
00244 bool
00245 xyPlatformAxisHardware::getReference(int axis)
00246 {
00247 assert(!(axis<0 || axis>XY_NUM_AXIS-1));
00248 return true;
00249 }
00250
00251 void
00252 xyPlatformAxisHardware::writePosition(int axis, double q)
00253 {
00254 assert(!(axis<0 || axis>XY_NUM_AXIS-1));
00255 _encoder[axis]->writeSensor(q);
00256 }
00257
00258
00259 TaskContext*
00260 xyPlatformAxisHardware::getTaskContext()
00261 {
00262 return &_my_task_context;
00263 }