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 #ifndef ORO_NODEGUARD_HPP
00029 #define ORO_NODEGUARD_HPP
00030
00031 #include "CAN.hpp"
00032 #include <rtt/RunnableInterface.hpp>
00033 #include "CANConfigurator.hpp"
00034 #include "CANMessage.hpp"
00035 #include "CANOpenBus.hpp"
00036
00037 namespace RTT
00038 {namespace CAN
00039 {
00040
00044 class NodeGuard
00045 : public RunnableInterface ,
00046 public CANListenerInterface
00047 {
00048 CANOpenBus* bus;
00049 unsigned int nodeId;
00050 CANMessage* rtr;
00051 unsigned int toggle;
00052 bool toggle_ok;
00053 char status;
00054 bool cres;
00055 CANConfigurator config;
00056 public:
00057
00064 NodeGuard( CANOpenBus* _bus, CANDeviceInterface* node )
00065 : bus(_bus), nodeId( node->nodeId() ), toggle(2), toggle_ok(false), cres(false),
00066 config( _bus) {}
00067
00071 unsigned int getStatus() { return status; }
00072
00076 bool isPreOperational() { return status == 0x7F; }
00077
00081 bool isOperational() { return status == 0x05; }
00082
00086 bool isStopped() { return status == 0x04; }
00087
00092 bool validToggle() { return toggle_ok; }
00093
00094 bool configure() {
00095 CANMessage *guardtime = new CANMessage();
00096 CANMessage *answer = new CANMessage();
00097 CANMessage *lifetime = new CANMessage();
00098
00099 guardtime->setStdId(0x600 + nodeId );
00100 CANMessage::Data d[] = { 0x22, 0x0c, 0x10, 0x00, 0x32, 0x00, 0x00, 0x00 };
00101 guardtime->setDataDLC( d, 8);
00102
00103 answer->setStdId(0x580 + nodeId );
00104 fillData(d, 0x60, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 );
00105 answer->setDataDLC( d, 8);
00106
00107 config.addRequest( new CANRequest( guardtime, answer, 0.5 ) );
00108
00109 lifetime->setStdId(0x600 + nodeId );
00110 fillData(d, 0x22, 0x0d, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00 );
00111 lifetime->setDataDLC( d, 8);
00112
00113 answer = new CANMessage();
00114 answer->setStdId(0x580 + nodeId );
00115 fillData(d, 0x60, 0x0d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 );
00116 answer->setDataDLC( d, 8);
00117
00118 config.addRequest( new CANRequest( lifetime, answer, 0.5 ) );
00119
00120 config.configInit();
00121
00122 while ( !config.isFinished() && config.configStep() )
00123 sleep(1);
00124
00125 cres = config.isFinished();
00126 config.configCleanup();
00127 return cres;
00128 }
00129
00130 bool initialize()
00131 {
00132 if (cres) {
00133 rtr = CANMessage::createStdRemote( 0, 0x700+nodeId, 0, 0 );
00134 bus->addListener(this);
00135 }
00136
00137 return cres;
00138 }
00139
00140 void step()
00141 {
00142 bus->write(rtr);
00143 }
00144
00145 void finalize() {
00146 bus->removeListener(this);
00147 delete rtr;
00148 }
00149
00150 void process(const CANMessage* msg)
00151 {
00152 if ( msg->getStdId() == 0x700 + nodeId && ! msg->isRemote() )
00153 {
00154 toggle_ok = false;
00155 status = msg->getData(0) & 0x7F;
00156 switch (toggle) {
00157 case 0:
00158 if ( msg->getData(0) >> 7 == 1)
00159 toggle_ok = true;
00160 break;
00161 case 1:
00162 if ( msg->getData(0) >> 7 == 0)
00163 toggle_ok = true;
00164 break;
00165 case 2:
00166 toggle_ok = true;
00167 break;
00168 }
00169 toggle = msg->getData(0) >> 7;
00170 }
00171 }
00172 };
00173
00174 }}
00175
00176 #endif