#include "shaftencoder.h" #include "timer.h" #include "network.h" #include // cout #include // setw, setfill #include // gSystem #include // TGLabel->SetText #include #include // PRIO_PROCESS ShaftEncoder::ShaftEncoder(const BYTE_t nodeid, const char *name, MLog &out) : NodeDrv(nodeid, name, out), fLabel(NULL), fPosHasChanged(false) { } ShaftEncoder::~ShaftEncoder() { } void ShaftEncoder::HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, struct timeval *tv) { switch (idx) { case 0x1000: lout << "- Model: "; switch (val&0xffff) { case 0x0196: lout << "Shaft Encoder Type: "; switch ((val>>16)&0xff) { case 0x01: lout << "Singleturn" << endl; return; case 0x02: lout << "Multiturn" << endl; return; default: lout << "?" << endl; return; } default: lout << "???" << endl; return; } case 0x100b: lout << "Node ID: " << dec << val << endl; return; case 0x6000: case 0x6500: lout << "- Counting: " << (val&1 ?"anti-clockwise":"clockwise") << " "; lout << "HwTest: " << (val&2 ?"on":"off") << " "; lout << "Scaling: " << (val&4 ?"on":"off") << " "; lout << "Modulo: " << (val&4096?"on":"off") << endl; case 0x6001: lout << "- Logical Ticks/Revolution: " << dec << val << endl; return; case 0x6004: lout << "- Position: " << dec << val << endl; fPos = val; fTurn = 0; return; case 0x6501: lout << "- Phys. Ticks/Revolution: " << dec << val << endl; fTicks = val; return; case 0x6502: lout << "- Possible Turns: " << dec << val << endl; fTurns = val ? val : 1; // Single Turn = Multiturn with one turn return; } cout << hex << setfill('0'); cout << "Sdo=" << idx << "/" << (int)subidx << ": 0x" << setw(8) << val; cout << endl; } void ShaftEncoder::DisplayVal() { char text[21]; if (fPos!=fUpdPos) { sprintf(text, "%ld", fPos); fLabel[0]->SetText(new TGString(text)); fUpdPos = fPos; } if (fVel!=fUpdVel) { sprintf(text, "%d", fVel); fLabel[1]->SetText(new TGString(text)); fUpdVel = fVel; } if (fAcc!=fUpdAcc) { sprintf(text, "%d", fAcc); fLabel[2]->SetText(new TGString(text)); fUpdAcc = fAcc; } } void ShaftEncoder::HandlePDOType0(BYTE_t *data, struct timeval *tv) { // // Decode information, we have a 14bit only // LWORDS_t pos = data[0] | (data[1]<<8) | (data[2]<<16); // | (data[3]<<24); if (pos==fPos) return; fPos = pos; fTime.SetTimer(tv); fPosHasChanged = true; } void ShaftEncoder::HandlePDOType1(BYTE_t *data, struct timeval *tv) { // // Decode information, we have a 14bit only // LWORDS_t pos = data[0] | (data[1]<<8) | (data[2]<<16); // | (data[3]<<24); BYTE_t flag = data[4]; if (fPos==pos) return; fPos=pos; fTime.SetTimer(tv); fPosHasChanged=true; flag=flag; } void ShaftEncoder::HandlePDOType2(BYTE_t *data, struct timeval *tv) { // // Decode information, we have a 14bit only // LWORDS_t pos = data[0] | (data[1]<<8) | (data[2]<<16); // | (data[3]<<24); fVel = data[4] | (data[5]<<8); fAcc = data[6] | (data[7]<<8); const int uplim = 9*fTicks/10; const int dnlim = 1*fTicks/10; int turn = fTurn; if (fPos > uplim && pos < dnlim) turn++; if (fPos < dnlim && pos > uplim) turn--; if (fPos==pos && fTurn==fTurn) return; fPos = pos; fTurn = turn; fTime.SetTimer(tv); fPosHasChanged=true; } double ShaftEncoder::GetTime() { return fTime.Now(); } double ShaftEncoder::GetMjd() { return fTime.CalcMjd(); } void ShaftEncoder::InitDevice(Network *net) { NodeDrv::InitDevice(net); //----------------------------------------------------------------------- // Start Setup of the Shaft Encoder //----------------------------------------------------------------------- // // Requesting and checking (FIXME) type of encoder // lout << "- Requesting Hardware Type (SDO 0x1000) of " << GetNodeName() << endl; RequestSDO(0x1000); WaitForSdo(0x1000); // // Read physical ticks per revolution // lout << "- Requesting physical ticks/revolution (SDO 0x6501) of " << GetNodeName() << endl; RequestSDO(0x6501); WaitForSdo(0x6501); // // Read number of possible ticks per revolution // lout << "- Requesting possible ticks/revolution (SDO 0x6502) of " << GetNodeName() << endl; RequestSDO(0x6502); WaitForSdo(0x6502); // // Set logic ticks/revolution = physical ticks/revolution => scale factor = 1 // lout << "- Configuring SDO 0x6001 of " << GetNodeName() << endl; SendSDO(0x6001, fTicks); WaitForSdo(0x6001); // // Set maximum number of ticks (ticks * turns) // lout << "- Configuring SDO 0x6002 of " << GetNodeName() << endl; SendSDO(0x6002, (LWORD_t)(fTicks*fTurns)); WaitForSdo(0x6002); // // Configure PDOs // lout << "- Configuring SDO 0x1802 of " << GetNodeName() << endl; SendSDO(0x1802, 1, (LWORD_t)0x281); WaitForSdo(0x1802, 1); // // Delete preset Value // lout << "- Configuring SDO 0x6003 of " << GetNodeName() << endl; SendSDO(0x6003, (LWORD_t)0xffffffff); WaitForSdo(0x6003); // // Request Parameter // lout << "- Requesting SDO 0x6000 of " << GetNodeName() << endl; RequestSDO(0x6000); WaitForSdo(0x6000); ReqPos(); lout << "- Start Node " << GetNodeName() << endl; SendNMT(kNMT_START); } void ShaftEncoder::ReqPos() { // // Request Position // lout << "- Requesting Position of " << GetNodeName() << endl; RequestSDO(0x6004); WaitForSdo(0x6004); } void ShaftEncoder::SetPreset(LWORD_t pre) { fPos = pre%16384; fTurn = pre/16384; lout << " - Setting Preset " << GetNodeName() << endl; SendSDO(0x6003, (LWORD_t)fPos); WaitForSdo(0x6003); } void ShaftEncoder::StopDevice() { lout << "- Start Node " << GetNodeName() << endl; SendNMT(kNMT_STOP); }