source: trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc@ 801

Last change on this file since 801 was 732, checked in by tbretz, 24 years ago
*** empty log message ***
File size: 6.6 KB
Line 
1#include "shaftencoder.h"
2
3#include "timer.h"
4#include "network.h"
5
6#include <iostream.h> // cout
7#include <iomanip.h> // setw, setfill
8
9#include <TSystem.h> // gSystem
10#include <TGLabel.h> // TGLabel->SetText
11
12#include <pthread.h>
13#include <sys/resource.h> // PRIO_PROCESS
14
15ShaftEncoder::ShaftEncoder(BYTE_t nodeid, ostream &out=cout) : NodeDrv(nodeid, out), fLabel(NULL)
16{
17 //
18 // Show information
19 //
20 pthread_create(&fThread, NULL, MapUpdateThread, this);
21
22}
23
24ShaftEncoder::~ShaftEncoder()
25{
26 pthread_cancel(fThread);
27}
28
29void ShaftEncoder::HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, struct timeval *tv)
30{
31 switch (idx)
32 {
33 case 0x1000:
34 cout << "Model: ";
35 switch (val&0xffff)
36 {
37 case 0x0196:
38 cout << "Shaft Encoder Type: ";
39 switch ((val>>16)&0xff)
40 {
41 case 0x01:
42 cout << "Singleturn" << endl;
43 return;
44 case 0x02:
45 cout << "Multiturn" << endl;
46 return;
47 default:
48 cout << "?" << endl;
49 return;
50 }
51 default:
52 cout << "???" << endl;
53 return;
54 }
55 case 0x100b:
56 cout << "Node ID: " << dec << val << endl;
57 return;
58
59 case 0x6000:
60 case 0x6500:
61 cout << "Counting: " << (val&1 ?"anti-clockwise":"clockwise") << " ";
62 cout << "HwTest: " << (val&2 ?"on":"off") << " ";
63 cout << "Scaling: " << (val&4 ?"on":"off") << " ";
64 cout << "Modulo: " << (val&4096?"on":"off") << endl;
65
66 case 0x6001:
67 cout << "Logical Ticks/Turn: " << dec << val << endl;
68 return;
69
70 case 0x6004:
71 cout << "Position: " << dec << val << endl;
72 fPos = val;
73 fTurn = 0;
74 return;
75
76
77 case 0x6501:
78 cout << "Phys. Ticks/Turn: " << dec << val << endl;
79 fTicks = val;
80 return;
81
82 case 0x6502:
83 cout << "Possible Turns: " << dec << val << endl;
84 fTurns = val ? val : 1; // Single Turn = Multiturn with one turn
85 return;
86
87
88 }
89 cout << hex << setfill('0');
90 cout << "Sdo=" << idx << "/" << (int)subidx << ": 0x" << setw(8) << val;
91 cout << endl;
92}
93
94void *ShaftEncoder::MapUpdateThread(void *data)
95{
96 ShaftEncoder *se = (ShaftEncoder*) data;
97
98 //
99 // Detach thread (make sure that it is really removed from memory)
100 //
101 pthread_detach(pthread_self());
102 setpriority(PRIO_PROCESS, 0, 5);
103
104 se->UpdateThread();
105
106 return NULL;
107}
108
109void ShaftEncoder::UpdateThread()
110{
111 //
112 // check for a running thread and lock mutex
113 //
114 char text[21];
115
116 //
117 // Wait until the network and the output widget is initialized
118 //
119 while (!GetNetwork() || !fLabel)
120 usleep(1);
121
122 while (1)
123 {
124 WaitForNextPdo1();
125
126 //
127 // Update information
128 //
129 sprintf(text, "%ld", fPos);
130 fLabel[0]->SetText(new TGString(text));
131
132 sprintf(text, "%d", fVel);
133 fLabel[1]->SetText(new TGString(text));
134
135 sprintf(text, "%d", fAcc);
136 fLabel[2]->SetText(new TGString(text));
137
138 //
139 // make updated information visible
140 //
141 gSystem->ProcessEvents();
142 }
143}
144
145void ShaftEncoder::HandlePDOType0(BYTE_t *data)
146{
147 //
148 // Decode information, we have a 14bit only
149 //
150 fPos = data[0] | (data[1]<<8) | (data[2]<<16); // | (data[3]<<24);
151}
152
153void ShaftEncoder::HandlePDOType1(BYTE_t *data)
154{
155 //
156 // Decode information, we have a 14bit only
157 //
158 LWORDS_t pos = data[0] | (data[1]<<8) | (data[2]<<16); // | (data[3]<<24);
159 BYTE_t flag = data[4];
160 pos=pos;
161 flag=flag;
162}
163
164void ShaftEncoder::HandlePDOType2(BYTE_t *data, struct timeval *tv)
165{
166 //
167 // Decode information, we have a 14bit only
168 //
169 LWORDS_t pos = data[0] | (data[1]<<8) | (data[2]<<16); // | (data[3]<<24);
170
171 fVel = data[4] | (data[5]<<8);
172 fAcc = data[6] | (data[7]<<8);
173
174 fTime.SetTimer(tv);
175
176 const int uplim = 9*fTicks/10;
177 const int dnlim = 1*fTicks/10;
178
179 if (fPos > uplim && pos < dnlim)
180 fTurn++;
181
182 if (fPos < dnlim && pos > uplim)
183 fTurn--;
184
185 fPos = pos;
186}
187
188double ShaftEncoder::GetTime()
189{
190 return fTime.GetTime();
191}
192
193double ShaftEncoder::GetMjd()
194{
195 return fTime.GetMjd();
196}
197
198void ShaftEncoder::InitDevice(Network *net)
199{
200 NodeDrv::InitDevice(net);
201
202 //-----------------------------------------------------------------------
203 // Start Setup of the Shaft Encoder
204 //-----------------------------------------------------------------------
205
206 //
207 // Requesting and checking (FIXME) type of encoder
208 //
209 lout << "- Requesting SDO 0x1000 of " << (int)GetId() << endl;
210 RequestSDO(0x1000);
211 WaitForSdo(0x1000);
212
213 //
214 // Read physical ticks per turn
215 //
216 lout << "- Requesting SDO 0x6501 of " << (int)GetId() << endl;
217 RequestSDO(0x6501);
218 WaitForSdo(0x6501);
219
220 //
221 // Read number of possible ticks per turn
222 //
223 lout << "- Requesting SDO 0x6502 of " << (int)GetId() << endl;
224 RequestSDO(0x6502);
225 WaitForSdo(0x6502);
226
227 //
228 // Set logic ticks per turn = physical ticks per turn => scale factor = 1
229 //
230 lout << "- Configuring SDO 0x6001 of " << (int)GetId() << endl;
231 SendSDO(0x6001, fTicks);
232 WaitForSdo(0x6001);
233
234 //
235 // Set maximum number of ticks (ticks * turns)
236 //
237 lout << "- Configuring SDO 0x6002 of " << (int)GetId() << endl;
238 SendSDO(0x6002, (LWORD_t)(fTicks*fTurns));
239 WaitForSdo(0x6002);
240
241 //
242 // Configure PDOs
243 //
244 lout << "- Configuring SDO 0x1802 of " << (int)GetId() << endl;
245 SendSDO(0x1802, 1, (LWORD_t)0x281);
246 WaitForSdo(0x1802, 1);
247
248 //
249 // Delete preset Value
250 //
251 lout << "- Configuring SDO 0x6003 of " << (int)GetId() << endl;
252 SendSDO(0x6003, (LWORD_t)0xffffffff);
253 WaitForSdo(0x6003);
254
255 //
256 // Request Parameter
257 //
258 lout << "- Requesting SDO 0x6000 of " << (int)GetId() << endl;
259 RequestSDO(0x6000);
260 WaitForSdo(0x6000);
261
262 ReqPos();
263
264 lout << "- Start Node " << (int)GetId() << endl;
265 SendNMT(kNMT_START);
266}
267
268void ShaftEncoder::ReqPos()
269{
270 //
271 // Request Position
272 //
273 lout << "- Requesting Position of #" << (int)GetId() << endl;
274 RequestSDO(0x6004);
275 WaitForSdo(0x6004);
276}
277
278void ShaftEncoder::SetPreset(LWORD_t pre)
279{
280 fPos = pre%16384;
281 fTurn = pre/16384;
282
283 lout << " - Setting Preset #" << (int)GetId() << endl;
284 SendSDO(0x6003, (LWORD_t)fPos);
285 WaitForSdo(0x6003);
286}
287
288void ShaftEncoder::StopDevice()
289{
290 lout << "- Start Node " << (int)GetId() << endl;
291 SendNMT(kNMT_STOP);
292}
293
Note: See TracBrowser for help on using the repository browser.