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 "AxesComponent.hpp"
00029 #include <rtt/Method.hpp>
00030 #include <rtt/Command.hpp>
00031
00032 namespace OCL
00033 {
00034
00035 AxesComponent::AxesComponent( int max_chan , const std::string& name )
00036 : TaskContext(name),
00037 max_channels("MaximumChannels","The maximum number of virtual sensor/drive channels", max_chan),
00038 chan_sensor("OutputValues",ChannelType(max_chan, 0.0) ),
00039 chan_drive("InputValues"),
00040 testData("testData", ChannelType(max_chan, 0.0) ),
00041 usingChannels(0)
00042 {
00043 this->attributes()->addAttribute(&testData);
00044
00045 chan_out.resize(max_chan);
00046 chan_meas.resize(max_chan);
00047
00048 this->methods()->addMethod( method( "switchOn", &AxesComponent::switchOn, this),
00049 "Switch A Digital Output on",
00050 "Name","The Name of the DigitalOutput."
00051 );
00052 this->methods()->addMethod( method( "switchOff", &AxesComponent::switchOff, this),
00053 "Switch A Digital Output off",
00054 "Name","The Name of the DigitalOutput."
00055 );
00056 this->methods()->addMethod( method( "enableAxis", &AxesComponent::enableAxis, this),
00057 "Enable an Axis ( equivalent to unlockAxis( )",
00058 "Name","The Name of the Axis."
00059 );
00060 this->methods()->addMethod( method( "unlockAxis", &AxesComponent::enableAxis, this),
00061 "Unlock an Axis. Enters 'stopped' state.",
00062 "Name","The Name of the Axis."
00063 );
00064 this->methods()->addMethod( method( "stopAxis", &AxesComponent::stopAxis, this),
00065 "Stop an Axis from driven. Enters 'stopped' state.",
00066 "Name","The Name of the Axis."
00067 );
00068 this->methods()->addMethod( method( "lockAxis", &AxesComponent::disableAxis, this),
00069 "Disable (lock an Axis. Enters 'locked' state/",
00070 "Name","The Name of the Axis."
00071 );
00072 this->methods()->addMethod( method( "disableAxis", &AxesComponent::disableAxis, this),
00073 "Disable (lock an Axis (equivalent to lockAxis() )",
00074 "Name","The Name of the Axis."
00075 );
00076
00077 this->methods()->addMethod( method( "isOn", &AxesComponent::isOn, this),
00078 "Inspect the status of a Digital Input or Output.",
00079 "Name", "The Name of the Digital IO."
00080 );
00081 this->methods()->addMethod( method( "isEnabled", &AxesComponent::isEnabled, this),
00082 "Inspect if an Axis is not locked.",
00083 "Name", "The Name of the Axis."
00084 );
00085 this->methods()->addMethod( method( "isLocked", &AxesComponent::isLocked, this),
00086 "Inspect if an Axis is mechanically locked.",
00087 "Name", "The Name of the Axis."
00088 );
00089 this->methods()->addMethod( method( "isStopped", &AxesComponent::isStopped, this),
00090 "Inspect if an Axis is electronically stopped.",
00091 "Name", "The Name of the Axis."
00092 );
00093 this->methods()->addMethod( method( "isDriven", &AxesComponent::isDriven, this),
00094 "Inspect if an Axis is in movement.",
00095 "Name", "The Name of the Axis."
00096 );
00097 this->methods()->addMethod( method( "axes", &AxesComponent::getAxes, this),
00098 "The number of axes."
00099 );
00100
00101 this->commands()->addCommand( command( "calibrateSensor", &AxesComponent::calibrateSensor, &AxesComponent::isCalibrated, this),
00102 "Calibrate a Sensor of an Axis.",
00103 "Axis", "The Name of the Axis.",
00104 "Sensor", "The Name of the Sensor of that axis e.g. 'Position'."
00105 );
00106 this->commands()->addCommand( command( "resetSensor", &AxesComponent::resetSensor, &AxesComponent::isCalibrated, this, true),
00107 "UnCalibrate a Sensor of an Axis.",
00108 "Axis", "The Name of the Axis.",
00109 "Sensor", "The Name of the Sensor of that axis e.g. 'Position'.");
00110 this->methods()->addMethod( method( "isSensorCalibrated", &AxesComponent::isCalibrated, this),
00111 "Check if a Sensor of an Axis is calibrated.",
00112 "Axis", "The Name of the Axis.",
00113 "Sensor", "The Name of the Sensor of that axis e.g. 'Position'.");
00114 }
00115
00116 bool AxesComponent::startup()
00117 {
00118 if ( chan_sensor.connected() )
00119 {
00120 for (AxisMap::iterator it = axes.begin(); it != axes.end(); ++it)
00121 {
00122
00123
00124 if ( it->second.axis && it->second.inport->connected() && it->second.channel != -1 ) {
00125 log(Warning) << "Axis: "<<it->second.name
00126 << ": Ignoring input from connected Data Port "
00127 << it->second.inport->getName() <<": using InputValues Data Port."<<endlog();
00128 }
00129 }
00130 }
00131 return true;
00132 }
00133
00134 void AxesComponent::update()
00135 {
00136
00137
00138
00139 if (usingChannels )
00140 chan_drive.Get( chan_out );
00141
00142
00143
00144
00145 for (AxisMap::iterator it= axes.begin(); it != axes.end(); ++it)
00146 this->to_axis( it->second );
00147
00148
00149 if ( usingChannels )
00150 chan_sensor.Set( chan_meas );
00151
00152 }
00153
00154 void AxesComponent::shutdown()
00155 {
00156 for (AxisMap::iterator it= axes.begin(); it != axes.end(); ++it)
00157 it->second.axis->lock();
00158 }
00159
00160 bool AxesComponent::addAxis( const std::string& name, AxisInterface* ax )
00161 {
00162 if ( this->isRunning() ) {
00163 log(Error) << "Can not add Axis "<<name<< " to running Component." <<endlog();
00164 return false;
00165 }
00166 if ( axes.count(name) != 0 ) {
00167 log(Error) << "Can not add Axis "<<name<< " to Component: name already in use." <<endlog();
00168 return false;
00169 }
00170
00171 axes.insert( std::make_pair(name, AxisInfo(ax, name)));
00172
00173 d_out[ name + ".Enable" ] = ax->getEnable();
00174 if ( ax->getBrake() )
00175 d_out[ name + ".Brake" ] = ax->getBrake();
00176 if ( ax->getSwitch("Home") )
00177 d_in[ name + ".Home" ] = ax->getSwitch("Home");
00178
00179
00180 AxisInfo* axinfo = & axes.find(name)->second;
00181 std::vector<std::string> res( ax->sensorList() );
00182 for ( std::vector<std::string>::iterator it = res.begin(); it != res.end(); ++it)
00183 {
00184 std::string sname( name+"_"+*it );
00185 axinfo->sensors[ sname ] = std::make_pair( ax->getSensor( *it ), new WriteDataPort<double>(sname) );
00186 this->ports()->addPort( axinfo->sensors[ sname ].second );
00187 }
00188
00189 axinfo->inport = new DataPort<double>(name+"_Drive");
00190 this->ports()->addPort( axinfo->inport );
00191 return true;
00192 }
00193
00194 bool AxesComponent::addAxisOnChannel(const std::string& axis_name, const std::string& sensor_name, int virtual_channel )
00195 {
00196 AxisInfo* axinfo = mhasAxis(axis_name);
00197
00198 if ( axinfo == 0 ||
00199 virtual_channel >= max_channels ||
00200 axinfo->channel != -1 ||
00201 axinfo->axis->getSensor( sensor_name ) == 0 ||
00202 this->isRunning() )
00203 return false;
00204
00205
00206 axinfo->channel = virtual_channel;
00207 axinfo->sensor = axinfo->axis->getSensor( sensor_name );
00208
00209 if (usingChannels == 0) {
00210 this->ports()->addPort(&chan_sensor, "Sensor measurements.");
00211 this->ports()->addPort(&chan_drive, "Drive values.");
00212 }
00213
00214 ++usingChannels;
00215 return true;
00216 }
00217
00218 AxesComponent::AxisInfo* AxesComponent::mhasAxis(const std::string& axis_name)
00219 {
00220 AxisMap::iterator axit = axes.find(axis_name);
00221 if ( axit == axes.end() ) {
00222 log(Error) <<"No such axis present: "<< axis_name <<endlog();
00223 return 0;
00224 }
00225 return &axit->second;
00226 }
00227
00228 void AxesComponent::removeAxisFromChannel( const std::string& axis_name )
00229 {
00230 AxisInfo* axinfo = mhasAxis(axis_name);
00231 if ( axinfo == 0 ||
00232 axinfo->channel == -1 ||
00233 this->isRunning() )
00234 return;
00235
00236 axinfo->channel = -1;
00237 axinfo->sensor = 0;
00238 --usingChannels;
00239
00240 if (usingChannels == 0) {
00241 this->ports()->removePort("InputValues");
00242 this->ports()->removePort("OutputValues");
00243 }
00244
00245 }
00246
00247
00248 bool AxesComponent::removeAxis( const std::string& name )
00249 {
00250 if ( axes.count(name) != 1 || this->isRunning() )
00251 return false;
00252
00253
00254 d_out.erase( name + ".Enable" );
00255 d_out.erase( name + ".Brake" );
00256 d_in.erase( name + ".Home" );
00257
00258
00259 AxisInfo* axinfo = & axes.find(name)->second;
00260 this->ports()->removePort(axinfo->inport->getName());
00261 delete axinfo->inport;
00262
00263
00264 std::vector<std::string> res( axinfo->axis->sensorList() );
00265 for ( std::vector<std::string>::iterator it = res.begin(); it != res.end(); ++it)
00266 {
00267 std::string sname( name+"_"+*it );
00268 this->ports()->removePort(sname);
00269 delete axinfo->sensors[sname].second;
00270 }
00271
00272
00273 axes.erase(name);
00274 return true;
00275 }
00276
00277 bool AxesComponent::enableAxis( const std::string& name )
00278 {
00279 if ( axes.count(name) != 1 )
00280 return false;
00281 AxisInfo* axinfo = & axes.find(name)->second;
00282 return axinfo->axis->unlock();
00283 }
00284
00285 bool AxesComponent::stopAxis( const std::string& name )
00286 {
00287 if ( axes.count(name) != 1 )
00288 return false;
00289 AxisInfo* axinfo = & axes.find(name)->second;
00290 return axinfo->axis->stop();
00291 }
00292
00293 bool AxesComponent::disableAxis( const std::string& name )
00294 {
00295 if ( axes.count(name) != 1 )
00296 return false;
00297 AxisInfo* axinfo = & axes.find(name)->second;
00298 return axinfo->axis->stop() && axinfo->axis->lock();
00299 }
00300
00301 bool AxesComponent::switchOn( const std::string& name )
00302 {
00303 if (d_out.count(name) != 1)
00304 return false;
00305 d_out[name]->switchOn();
00306 return true;
00307 }
00308
00309 bool AxesComponent::switchOff( const std::string& name )
00310 {
00311 if (d_out.count(name) != 1)
00312 return false;
00313 d_out[name]->switchOff();
00314 return true;
00315 }
00316
00317 bool AxesComponent::isEnabled( const std::string& name ) const
00318 {
00319 AxisMap::const_iterator it = axes.find(name);
00320 if ( it != axes.end() )
00321 return ! it->second.axis->isLocked();
00322 return false;
00323 }
00324
00325 bool AxesComponent::isLocked( const std::string& name ) const
00326 {
00327 AxisMap::const_iterator it = axes.find(name);
00328 if ( it != axes.end() )
00329 return it->second.axis->isLocked();
00330 return false;
00331 }
00332
00333 bool AxesComponent::isStopped( const std::string& name ) const
00334 {
00335 AxisMap::const_iterator it = axes.find(name);
00336 if ( it != axes.end() )
00337 return it->second.axis->isStopped();
00338 return false;
00339 }
00340
00341 bool AxesComponent::isDriven( const std::string& name ) const
00342 {
00343 AxisMap::const_iterator it = axes.find(name);
00344 if ( it != axes.end() )
00345 return it->second.axis->isDriven();
00346 return false;
00347 }
00348
00349 int AxesComponent::getAxes() const
00350 {
00351 return axes.size();
00352 }
00353
00354 bool AxesComponent::isOn( const std::string& name ) const
00355 {
00356 if ( d_in.count(name) == 1 )
00357 return d_in.find(name)->second->isOn();
00358 else if (d_out.count(name) == 1 )
00359 return d_out.find(name)->second->isOn();
00360 return false;
00361 }
00362
00363 bool AxesComponent::calibrateSensor( const std::string& axis, const std::string& name )
00364 {
00365 AxisMap::iterator axit = axes.find(axis);
00366 if ( axit != axes.end() ) {
00367 SensorMap::iterator it = axit->second.sensors.find(name);
00368 if ( it != axit->second.sensors.end() )
00369 return it->second.first->calibrate(), true;
00370 }
00371 return false;
00372 }
00373
00374 bool AxesComponent::resetSensor( const std::string& axis, const std::string& name )
00375 {
00376 AxisMap::iterator axit = axes.find(axis);
00377 if ( axit != axes.end() ) {
00378 SensorMap::iterator it = axit->second.sensors.find(name);
00379 if ( it != axit->second.sensors.end() )
00380 return it->second.first->unCalibrate(), true;
00381 }
00382 return false;
00383 }
00384
00385 bool AxesComponent::isCalibrated( const std::string& axis, const std::string& name ) const
00386 {
00387 AxisMap::const_iterator axit = axes.find(axis);
00388 if ( axit != axes.end() ) {
00389 SensorMap::const_iterator it = axit->second.sensors.find(name);
00390 if ( it != axit->second.sensors.end() )
00391 return it->second.first->isCalibrated(), true;
00392 }
00393 return false;
00394 }
00395
00396 void AxesComponent::to_axis(const AxisInfo& dd )
00397 {
00398
00399 SensorMap::const_iterator it = dd.sensors.begin();
00400 while (it != dd.sensors.end() ) {
00401 it->second.second->Set( it->second.first->readSensor() );
00402 ++it;
00403 }
00404
00405
00406 if (dd.channel != -1)
00407 chan_meas[dd.channel] = dd.sensor->readSensor();
00408
00409
00410
00411 if ( dd.axis->isLocked() == false ) {
00412 if ( dd.channel == -1) {
00413 dd.axis->drive( dd.inport->Get() );
00414 }
00415 else
00416 dd.axis->drive( chan_out[dd.channel] );
00417 }
00418 }
00419 }