Subversion Repositories seema-scanner

Rev

Rev 223 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
9 jakw 1
#include "RotationStage.h"
2
 
3
#include <string.h>
4
#include <iostream>
5
#include <sstream>
10 jakw 6
#include <stdlib.h>
9 jakw 7
#include <unistd.h>
8
 
14 jakw 9
static int wormGearRatio = 72;
10
static float degreesPerStep = 1.8;
9 jakw 11
 
14 jakw 12
RotationStage::RotationStage(): microSteps(0){
13
 
9 jakw 14
    char out[64];
15
    char in[64];
16
 
17
    memset(out,0,64);
18
    memset(in,0,64);
19
 
20
    // acquire information
21
    AR_DWORD num;
22
    if(!fnPerformaxComGetNumDevices(&num)){
138 jakw 23
        std::cerr << "Error in fnPerformaxComGetNumDevices!" << std::endl;
24
        return;
9 jakw 25
    }
26
    if(num<1){
180 jakw 27
        std::cerr << "RotationStage error: no motor controller found!" << std::endl;
138 jakw 28
        return;
9 jakw 29
    }
30
 
51 jakw 31
//    // show product string
32
//    char lpDeviceString[PERFORMAX_MAX_DEVICE_STRLEN];
33
//    if(!fnPerformaxComGetProductString(0, lpDeviceString, PERFORMAX_RETURN_SERIAL_NUMBER) ||
34
//            !fnPerformaxComGetProductString(0, lpDeviceString, PERFORMAX_RETURN_DESCRIPTION) ){
35
//        throw "Error acquiring product string!";
36
//    }
37
//    printf("Device description: %s\n", lpDeviceString);
9 jakw 38
 
10 jakw 39
    // open connection for deviceId 0
9 jakw 40
    if(!fnPerformaxComOpen(0,&Handle)){
41
        throw "Error opening device!";
42
    }
43
 
10 jakw 44
    if(!fnPerformaxComSetTimeouts(5000, 5000)){
9 jakw 45
        throw "Error setting timeouts!";
46
    }
47
 
51 jakw 48
//    // flush connection
49
//    if(!fnPerformaxComFlush(Handle)){
50
//        throw "Error flushing the coms!";
51
//    }
9 jakw 52
 
14 jakw 53
//    // stop motor (in case it is running an old command)
54
//    strcpy(out, "STOP");
55
//    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
56
//        throw "Could not send!";
57
//    }
58
//    wait();
59
 
180 jakw 60
    strcpy(out, "ID");
61
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
62
        std::cerr << "RotationStage error: could not retrieve ID!" << std::endl;
63
    }
64
    printf("Arcus Product: %s ",in);
10 jakw 65
 
180 jakw 66
    strcpy(out, "DN");
67
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
68
        printf("Could not send!");
69
    }
70
    printf("  %s  ",in);
9 jakw 71
 
180 jakw 72
    strcpy(out, "VER");
73
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
74
        printf("Could not send!");
75
    }
76
    printf("Firmware: %s\n",in);
9 jakw 77
 
180 jakw 78
    // setup "driver parameters"
79
    strcpy(out, "DRVMS=500"); // microstep setting
80
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
81
        throw "Could not send!";
82
    }
11 jakw 83
 
180 jakw 84
    strcpy(out, "DRVIT=1"); // idling time
85
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
86
        throw "Could not send!";
87
    }
11 jakw 88
 
180 jakw 89
    strcpy(out, "DRVIC=100"); // idle current
90
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
91
        throw "Could not send!";
92
    }
11 jakw 93
 
180 jakw 94
    strcpy(out, "DRVRC=100"); // running current
95
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
96
        throw "Could not send!";
97
    }
11 jakw 98
 
180 jakw 99
    strcpy(out, "RW"); // write preceding microstep and current settings
100
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
101
        throw "Could not send!";
102
    }
103
    sleep(3);
104
 
175 jakw 105
    microSteps = 0;
180 jakw 106
    strcpy(out, "RR"); // update settings read
30 jakw 107
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
108
        throw "Could not send!";
109
    }
11 jakw 110
 
180 jakw 111
    strcpy(out, "DRVMS"); // read microstep settings
30 jakw 112
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
113
        throw "Could not send!";
114
    }
115
    printf("Microstep setting: %s [2--500]\n",in);
116
    microSteps = atoi(in);
11 jakw 117
 
180 jakw 118
    strcpy(out, "DRVIT"); // read idling time setting
30 jakw 119
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
120
        throw "Could not send!";
121
    }
122
    printf("Idling time: %s centi-sec\n",in);
11 jakw 123
 
180 jakw 124
    strcpy(out, "DRVIC"); // read idle current settings
30 jakw 125
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
126
        throw "Could not send!";
127
    }
128
    printf("Idle current: %s mA [100--2800]\n",in);
11 jakw 129
 
180 jakw 130
    strcpy(out, "DRVRC"); // read run current settings
30 jakw 131
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
132
        throw "Could not send!";
133
    }
134
    printf("Run current: %s mA [100--3000]\n",in);
11 jakw 135
 
180 jakw 136
    // Setup "movement parameters"
137
    strcpy(out, "SL=0"); //disable step-n-loop
138
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
139
        throw "Could not set low speed!";
140
    }
141
 
11 jakw 142
    strcpy(out, "LSPD=0"); //set low speed
143
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
10 jakw 144
        throw "Could not set low speed!";
9 jakw 145
    }
146
 
14 jakw 147
    strcpy(out, "HSPD=200000"); //set high speed
9 jakw 148
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
10 jakw 149
        throw "Could not set high speed!";
9 jakw 150
    }
151
 
10 jakw 152
    strcpy(out, "SCV=1"); //enable s-curve acceleration
9 jakw 153
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
180 jakw 154
        throw "Could not set acceleration type!";
9 jakw 155
    }
156
 
10 jakw 157
    strcpy(out, "ACC=500"); //set acceleration
9 jakw 158
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
180 jakw 159
        throw "Could not set acceleration value!";
9 jakw 160
    }
161
 
10 jakw 162
    strcpy(out, "EDEC=1"); //enable separate deceleration
9 jakw 163
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
10 jakw 164
        throw "Could not send!";
9 jakw 165
    }
166
 
10 jakw 167
    strcpy(out, "DEC=500"); //set deceleration
9 jakw 168
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
169
        throw "Could not send!";
170
    }
171
 
180 jakw 172
//    strcpy(out, "STORE"); //store settings to flash
173
//    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
174
//        throw "Could not send!";
175
//    }
176
 
11 jakw 177
    // enable the motor
10 jakw 178
    strcpy(out, "EO=1"); //enable device
9 jakw 179
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
180
        throw "Could not send!";
181
    }
182
 
10 jakw 183
//    // go to home
184
//    strcpy(out, "H+");
185
//    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
186
//        throw "Could not send!";
187
//    }
14 jakw 188
//    wait();
9 jakw 189
 
11 jakw 190
    // zero the current position value
10 jakw 191
    strcpy(out, "PX=0");
9 jakw 192
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
193
        throw "Could not send!";
194
    }
195
 
180 jakw 196
    std::cout << std::flush;
10 jakw 197
}
9 jakw 198
 
10 jakw 199
bool RotationStage::executeStringCommand(std::string cmd){
200
 
201
    std::string dummy;
202
    return executeStringCommand(cmd, dummy);
9 jakw 203
}
204
 
10 jakw 205
bool RotationStage::executeStringCommand(std::string cmd, std::string& ret){
223 flgw 206
    bool res=false;
9 jakw 207
    char out[64];
208
    char in[64];
209
 
223 flgw 210
    mutex.lock();
9 jakw 211
    strcpy(out, cmd.c_str());
212
    if(!fnPerformaxComSendRecv(Handle, out, 64,64, in)){
213
        std::cerr << "Could not execute command " << cmd << "!" << std::endl;
10 jakw 214
    } else {
215
        ret = std::string(in);
223 flgw 216
        res = true;
10 jakw 217
    }
223 flgw 218
    mutex.unlock();
219
    return res;
9 jakw 220
}
221
 
91 jakw 222
bool RotationStage::isMoving(){
223
 
92 jakw 224
    std::string ret;
91 jakw 225
    if(!executeStringCommand("MST", ret)){
226
        throw "Could not get motor status!";
227
    }
228
    int status = atoi(ret.c_str());
229
    // if any of the first three bits is set, the motor is moving
230
    return status & 0b111;
231
 
232
}
233
 
10 jakw 234
void RotationStage::wait(){
9 jakw 235
 
10 jakw 236
    // poll motor status until not moving
237
    bool moving = true;
238
    while(moving){
239
        std::string ret;
240
        if(!executeStringCommand("MST", ret)){
241
            throw "Could not get motor status!";
9 jakw 242
        }
10 jakw 243
        int status = atoi(ret.c_str());
13 jakw 244
        // if any of the first three bits is set, the motor is moving
10 jakw 245
        moving = status & 0b111;
13 jakw 246
        usleep(100000);
10 jakw 247
    }
9 jakw 248
 
249
}
250
 
23 jakw 251
// Return the current angle in the range [0--360[ (deg)
14 jakw 252
float RotationStage::getAngle(){
9 jakw 253
 
10 jakw 254
    std::string ret;
9 jakw 255
 
10 jakw 256
    if(!executeStringCommand("PX", ret)){
257
        throw "Could not get position!";
258
    } else {
259
        //std::cout << ret << std::endl;
14 jakw 260
        int posX = atoi(ret.c_str());
23 jakw 261
        int fullRevX = (360*microSteps*wormGearRatio)/degreesPerStep;
262
        posX = posX % fullRevX;
263
        if(posX < 0)
264
            posX += fullRevX;
14 jakw 265
        return posX*degreesPerStep/(microSteps*wormGearRatio);
10 jakw 266
    }
267
 
268
}
269
 
270
void RotationStage::moveRelative(float angle){
271
 
272
    //set incremental mode
273
    if(!executeStringCommand("INC"))
274
        throw "Could not set mode!";
275
 
14 jakw 276
    // X position (in microsteps)
277
    int posX = (angle*microSteps*wormGearRatio)/degreesPerStep;
278
 
279
    std::cout << "Moving relative " << angle << " deg, " << posX << " microsteps" << std::endl;
280
 
9 jakw 281
    std::ostringstream cmdStream;
14 jakw 282
    cmdStream << "X" << posX;
10 jakw 283
    //std::cout << cmdStream.str() << std::endl << std::flush;
9 jakw 284
 
10 jakw 285
    if(!executeStringCommand(cmdStream.str()))
286
        throw "Could not execute move command!";
287
 
9 jakw 288
}
10 jakw 289
 
290
void RotationStage::moveAbsolute(float angle){
291
 
292
    //set absolute mode
293
    if(!executeStringCommand("ABS"))
294
        throw "Could not set mode!";
295
 
23 jakw 296
    // get current position
297
    int currPosX;
298
    std::string ret;
299
    if(!executeStringCommand("PX", ret)){
300
        throw "Could not get position!";
301
    } else {
302
        currPosX = atoi(ret.c_str());
303
    }
304
 
14 jakw 305
    // X position (in microsteps)
306
    int posX = (angle*microSteps*wormGearRatio)/degreesPerStep;
307
 
23 jakw 308
    int fullRevX = (360*microSteps*wormGearRatio)/degreesPerStep;
309
    int currPosXNorm = currPosX % fullRevX;
310
    if(currPosXNorm < 0)
311
        currPosXNorm += fullRevX;
14 jakw 312
 
23 jakw 313
    // decide to go cw or ccw
314
    if(posX > currPosXNorm){
315
        if((posX - currPosXNorm) < fullRevX/2){
316
            posX = currPosX + (posX - currPosXNorm);
317
        } else {
318
            posX = currPosX - fullRevX + (posX - currPosXNorm);
319
        }
320
    } else {
321
        if((currPosXNorm - posX) < fullRevX/2){
322
            posX = currPosX - (currPosXNorm - posX);
323
        } else {
324
            posX = currPosX + fullRevX - (currPosXNorm - posX);
325
        }
326
 
327
    }
328
 
329
    std::cout << "Moving absolute " << angle << " deg, pos X" << posX << std::endl;
330
 
10 jakw 331
    std::ostringstream cmdStream;
14 jakw 332
    cmdStream << "X" << posX;
10 jakw 333
    //std::cout << cmdStream.str() << std::endl << std::flush;
334
 
335
    if(!executeStringCommand(cmdStream.str()))
336
        throw "Could not execute move command!";
337
}
338
 
339
RotationStage::~RotationStage(){
226 jakw 340
    if(Handle)
341
        fnPerformaxComClose(Handle);
342
 
343
    std::cout << "Rotation stage closed." << std::endl << std::flush;
10 jakw 344
}