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 "CANBus.hpp"
00036
00037 namespace RTT
00038 {
00039 namespace CAN
00040 {
00041
00045 enum NodeStatus
00046 {
00047 PowerOff, Initialisation, PreOperational, Stopped, Operational
00048 };
00049
00053 class NodeGuard: public RunnableInterface, public CANListenerInterface
00054 {
00055 CANBus* bus;
00056 unsigned int nodeId;
00057 CANMessage* rtr;
00058 unsigned int toggle;
00059 bool toggle_ok;
00060 char status;
00061 bool cres;
00062 CANConfigurator config;
00063 NodeStatus status;
00064 public:
00065
00072 NodeGuard(CANBus* _bus, unsigned int nodeId) :
00073 bus(_bus), nodeId(nodeId), toggle(2), toggle_ok(false), cres(
00074 false), config(_bus)
00075 {
00076 }
00077
00081 unsigned int getStatus()
00082 {
00083 return status;
00084 }
00085
00089 bool isPreOperational()
00090 {
00091 return status == 0x7F;
00092 }
00093
00097 bool isOperational()
00098 {
00099 return status == 0x05;
00100 }
00101
00105 bool isStopped()
00106 {
00107 return status == 0x04;
00108 }
00109
00114 bool validToggle()
00115 {
00116 return toggle_ok;
00117 }
00118
00119 bool configure()
00120 {
00121 CANMessage *guardtime = new CANMessage();
00122 CANMessage *answer = new CANMessage();
00123 CANMessage *lifetime = new CANMessage();
00124
00125 guardtime->setStdId(0x600 + nodeId);
00126 CANMessage::Data d[] =
00127 { 0x22, 0x0c, 0x10, 0x00, 0x32, 0x00, 0x00, 0x00 };
00128 guardtime->setDataDLC(d, 8);
00129
00130 answer->setStdId(0x580 + nodeId);
00131 fillData(d, 0x60, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 );
00132 answer->setDataDLC(d, 8);
00133
00134 config.addRequest(new CANRequest(guardtime, answer, 0.5));
00135
00136 lifetime->setStdId(0x600 + nodeId);
00137 fillData(d, 0x22, 0x0d, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00 );
00138 lifetime->setDataDLC(d, 8);
00139
00140 answer = new CANMessage();
00141 answer->setStdId(0x580 + nodeId);
00142 fillData(d, 0x60, 0x0d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 );
00143 answer->setDataDLC(d, 8);
00144
00145 config.addRequest(new CANRequest(lifetime, answer, 0.5));
00146
00147 config.configInit();
00148
00149 while (!config.isFinished() && config.configStep())
00150 sleep(1);
00151
00152 cres = config.isFinished();
00153 config.configCleanup();
00154 return cres;
00155 }
00156
00157 bool initialize()
00158 {
00159 if (cres)
00160 {
00161 rtr = CANMessage::createStdRemote(0, 0x700 + nodeId, 0, 0);
00162 bus->addListener(this);
00163 }
00164
00165 return cres;
00166 }
00167
00168 void step()
00169 {
00170 bus->write(rtr);
00171 }
00172
00173 void finalize()
00174 {
00175 bus->removeListener(this);
00176 delete rtr;
00177 }
00178
00179 void process(const CANMessage* msg)
00180 {
00181 if (msg->getStdId() == 0x700 + nodeId && !msg->isRemote())
00182 {
00183 toggle_ok = false;
00184 status = msg->getData(0) & 0x7F;
00185 switch (toggle)
00186 {
00187 case 0:
00188 if (msg->getData(0) >> 7 == 1)
00189 toggle_ok = true;
00190 break;
00191 case 1:
00192 if (msg->getData(0) >> 7 == 0)
00193 toggle_ok = true;
00194 break;
00195 case 2:
00196 toggle_ok = true;
00197 break;
00198 }
00199 toggle = msg->getData(0) >> 7;
00200 }
00201 }
00202
00203
00204 };
00205
00206 }
00207 }
00208
00209 #endif