Commit ed55f1f1 authored by gdargaud's avatar gdargaud
Browse files

Added extern control parameters

parent d27b6dac
......@@ -71,15 +71,19 @@ enum TcheckAxisStatus { powStageErr, powStageNormal,
emergencyStop, normalStop };
enum { D_ALL, D_NO_REPLY, D_NONE }; // Display cmd&reply, just cmd or neither
static int Display=D_ALL; // Global to skip displaying some commands or replies
static int Display=D_ALL; // Global to skip displaying some commands or replies
static int sock=0; // Socket
int Phytron_msWait=10; // Min delay between command and reply and new command. 50ms seems safe enough
#define msleep(ms) usleep((ms)*1000)// ms sleep
int Phytron_msMotionPolling=500; // Same as above, but higher value to limit the number of polling messages
int Phytron_SpeedDiv=6; // Range: 1 to 255. Default is 6 or 10. 1 is too fast and might break the switch
double Phytron_MoveInDiode_Pos=-45; // Precise angle where the diode is in the middle of the beam
int Phytron_SpeedDiv=10; // Range: 1 to 256. Default is 6 or 10. 1 is too fast and might break the switch
double Phytron_MoveInDiode_Pos=34; // Precise angle where the diode is in the middle of the beam
double Phytron_OpMin=0, Phytron_OpMax=70;// Operational motion limits (in deg)
int Phytron_MainDir=+1; // +1 if the homing should go for the positive direction, -1 otherwise.
// Don't get this wrong or you will BREAK the support
int Phytron_UseEncoder=0;
static int Enabled=0;
static char LastErrMsg[1024]="";
......@@ -463,7 +467,8 @@ static char *PT[NbP][5]={ [1]={"rotational", "linear"},
/////////////////////////////////////////////////////////////////////
int PH_SetParamValue(int Param, int Val) {
char Reply[MAX_REPLY], Extra[256]="";
if (Param<0 or NbP<=Param) { PrintErr("Invalid parameter %d", Param); return -1; }
if (Param<0 or NbP<=Param or
Param==3 or Param==19) { PrintErr("Invalid parameter %d", Param); return -1; }
int Ret=PH_SendCommand(Reply, "XP%dS%d", Param, Parameter[Param]=Val);
if (Val>=0 and Val<5 and PT[Param][Val]!=NULL and PT[Param][Val][0]!='\0')
sprintf(Extra, ": %s", PT[Param][Val]);
......@@ -476,18 +481,19 @@ int PH_SetParamValue(int Param, int Val) {
/////////////////////////////////////////////////////////////////////
int PH_SetParamValueF(int Param, double Val) {
char Reply[MAX_REPLY];
if (Param<0 or NbP<=Param) { PrintErr("Invalid parameter %d", Param); return -1; }
if (!(Param==3 or Param==19)) { PrintErr("Invalid parameter %d", Param); return -1; }
double Ret=PH_SendCommand(Reply, "XP%dS%.2f", Param, ParameterF[Param]=Val);
printf(BLD YEL "%sSetting param %d to %.2f (%s)\n" NRM, Tabs, Param, Val, ParameterTxt[Param]);
return Ret;
}
/////////////////////////////////////////////////////////////////////
/// HIRET Parameter value is returned
/// HIRET Integer parameter value is read and returned
/////////////////////////////////////////////////////////////////////
int PH_GetParamValue(int Param) {
char Reply[MAX_REPLY]="", Extra[256]="";
if (Param<0 or NbP<=Param) { PrintErr("Invalid parameter %d", Param); return -1; }
if (Param<0 or NbP<=Param or
Param==3 or Param==19) { PrintErr("Invalid parameter %d", Param); return -1; }
PH_SendCommand(Reply, "XP%dR", Param);
int Val=Parameter[Param]=atoi(Reply);
if (Val>=0 and Val<5 and PT[Param][Val]!=NULL and PT[Param][Val][0]!='\0')
......@@ -497,12 +503,12 @@ int PH_GetParamValue(int Param) {
}
/////////////////////////////////////////////////////////////////////
/// HIPAR Some values are floats
/// HIPAR Some values are floats. Currently only 3 and 19
/// HIRET Parameter value is returned
/////////////////////////////////////////////////////////////////////
double PH_GetParamValueF(int Param) {
char Reply[MAX_REPLY]="";
if (Param<0 or NbP<=Param) { PrintErr("Invalid parameter %d", Param); return -1; }
if (!(Param==3 or Param==19)) { PrintErr("Invalid parameter %d", Param); return -1; }
PH_SendCommand(Reply, "XP%dR", Param);
double Val=ParameterF[Param]=atof(Reply);
printf(BLD YEL "%sParam %d: %s (%s)\n" NRM, Tabs, Param, Reply, ParameterTxt[Param]);
......@@ -512,11 +518,9 @@ double PH_GetParamValueF(int Param) {
/////////////////////////////////////////////////////////////////////
static int GearReduction=26; // ??? 46; // See GPL26 manual
#define StepRes (Parameter[45]) // Must be read with PH_GetParamValue prior to using those macros
//#define P2D(p) ((p)*360./(GearReduction*StepRes)) // From position (steps) to degrees
//#define D2P(d) ((d)*GearReduction*StepRes/360.) // From degrees to position (steps)
#define P2D(p) ((p)/(GearReduction*StepRes)) // From position (steps) to degrees
#define D2P(d) ((d)*GearReduction*StepRes) // From degrees to position (steps)
#define StepRes (Parameter[45]) // Must be read with PH_GetParamValue prior to using those macros
#define P2D(p) ((double)(p)/(GearReduction*StepRes))// From position (steps) to degrees
#define D2P(d) ((d)*GearReduction*StepRes) // From degrees to position (steps)
/////////////////////////////////////////////////////////////////////
/// HIFN Move to relative position
......@@ -556,7 +560,9 @@ int PH_FreeRunning(int val) {
double PH_DbgGetPosition(double *P) {
// This is a double with 2 digits precision (so 1/100th step in theory),
// it's the most precise positioning parameter but must be zeroed at start
P[19]=PH_GetParamValueF(19); // Electronical zero counter. Used for setting operating points. At standstill of the axis, P19 can be read or programmed during program execution.
P[19]=PH_GetParamValueF(19); // Electronical zero counter. Used for setting operating points.
// At standstill of the axis, P19 can be read or programmed during program execution.
// Before you can use this you must reset EL0P with Set(19,0)
// This has only a precision of 1 step
P[20]=PH_GetParamValue(20); // Mechanical zero counter. This counter contains the number of steps referred to the mechanical zero (M0P). Can be read at axis standstill. If the axis reaches the M0P, P20 will be set to zero.
......@@ -567,7 +573,7 @@ double PH_DbgGetPosition(double *P) {
// Only available if encoder is used, but... WTF is this value ? Seems to be P[19]*333.6
P[22]=PH_GetParamValue(22);
printf(BLD PRP "Pos:%s%.1fdeg\n" NRM, Tabs, P2D(P[19])); // or 21 ?
printf(BLD PRP "Pos:%s%.1fdeg\n" NRM, Tabs, P2D(P[19])); // 19 works only without encoder. 20 works with both. 21 and 22 always seem at 0 ?
return P2D(P[19]);
}
......@@ -639,17 +645,16 @@ int PH_DoGetGeneralStatus(void) {
////////////////////////////////////////////////////////////////////////////////
#ifdef STANDALONE_TEST_PROG
#undef USE_ENCODER // Use this only if appropriate 10 extra encoder wires are connected
int main(int argc, const char* argv[]) {
char Reply[MAX_REPLY];
int Ret=0, i;
if (argc>1 and (0==strcmp("-h", argv[1]) or 0==strcmp("--help", argv[1]))) {
fprintf(stderr, "%s [Pos|@Cmd] ...\n"
"Pos:\tAbsolute position to move the motor to (numerical value, in degrees)\n"
"@Cmd:\tArbitrary command to send to the controller (must follow a '@'). No sanity check is performed\n"
, argv[0]);
"Pos:\tAbsolute positions to move the motor to (numerical value, in degrees)\n"
"@Cmd:\tArbitrary commands to send to the controller (must follow a '@'). No sanity check is performed\n"
"Currently %susing the encoder\n"
, argv[0], Phytron_UseEncoder?"NOT ":"");
return 1;
}
......@@ -660,33 +665,36 @@ int main(int argc, const char* argv[]) {
printf(BLD WHT "%s\n" NRM, TB_Phytron_Status());
Ret|=PH_Reset();
// Ret|=PH_ResetAxis(); // FIXME: not sure if this ought to be here. Does it set the zero ?
// Ret|=PH_ResetAxis(); // not necessary
Ret|=PH_DoGetGeneralStatus();
Ret|=PH_SetParamValue(45, Phytron_SpeedDiv); // Full step. Default was 1/6 ?
Ret|=PH_SetParamValue(45, 4 /*FIXME Phytron_SpeedDiv */); // Full step. Default was 1/6 ?
Ret|=PH_SetParamValue(2, 1); // Measuring unit of movement - Step
// Ret|=PH_SetParamValue(2, 4); // Measuring unit of movement - Degree - DOES NOT SEEM DO ANYTHING
Ret|=PH_SetParamValue(39, GearReduction); // Encoder conversion factor - DOES NOT SEEM TO DO ANYTHING
double P[argc][NbP]; // Positioning tests, in steps
#ifdef USE_ENCODER
double Q[argc][NbP]; // Positioning tests, in steps
#endif
if (Ret) goto Skip;
#define PAUSE printf("Press Enter: "), getchar()
// PH_DoAct();
Ret|=PH_MoveToLimit(-1); // If no contactor, will stop after a timeout (18s I think. It's one of the parameters)
msleep(Phytron_msMotionPolling);
while (PH_GetStatusAxes()) msleep(Phytron_msMotionPolling);
#if 1 // Check the effect of limits/timeout on initiator motion
Ret|=PH_SetParamValue(23, D2P(90)); // Axis + limitation
Ret|=PH_SetParamValue(24, D2P(0)); // Axis - limitation
// It works but it doesn't make sense: it should be the opposite
#endif
Ret|=PH_MoveToLimit(Phytron_MainDir); // If no contactor, will stop after a timeout (18s I think. It's one of the parameters)
do msleep(Phytron_msMotionPolling); while (PH_GetStatusAxes());
// PH_DbgGetPosition(Q[i]);
PAUSE;
Ret|=PH_SetParamValueF(19, 0.); // Reset EL0P
#if 0 // Check the effect of the resolution. It's important at low angles because of truncation
Ret|=PH_SetParamValueF(19, 0.); // Reset EL0P
PH_SetParamValue(34, 0); // no encoder
PH_SetParamValue(34, Phytron_UseEncoder);
double POS=90.;
Ret|=PH_SetParamValue(45, 1); // Full step. Default was 4
TB_Phytron_MoveAbs(POS);
......@@ -705,7 +713,6 @@ int main(int argc, const char* argv[]) {
exit(1);
#endif
Ret|=PH_SetParamValueF(19, 0.); // Reset EL0P
PH_SetParamValue(34, 0); // no encoder
for (i=1; i<argc; i++) {
printf("\nArgv:%s%s\n", Tabs, argv[i]);
......@@ -715,27 +722,27 @@ int main(int argc, const char* argv[]) {
} else { // Otherwise assume numerical absolute moves
Ret|=PH_AbsPosition(atof(argv[i]));
if (Ret) break;
msleep(Phytron_msMotionPolling);
while (PH_GetStatusAxes()) msleep(Phytron_msMotionPolling);
do msleep(Phytron_msMotionPolling); while (PH_GetStatusAxes());
PH_DbgGetPosition(P[i]);
}
PAUSE;
}
#ifdef USE_ENCODER
Ret|=PH_MoveToLimit(Phytron_MainDir); // If no contactor, will stop after a timeout (18s I think. It's one of the parameters)
do msleep(Phytron_msMotionPolling); while (PH_GetStatusAxes());
// Now with encoder
// This works, but there seems to be no benefit at standard speeds
Ret|=PH_SetParamValueF(19, 0.); // Reset EL0P
PH_SetParamValue(34, 1); // Use incremental encoder
for (i=1; i<argc; i++) {
Ret|=PH_AbsPosition(atof(argv[i]));
if (Ret) break;
msleep(Phytron_msMotionPolling);
while (PH_GetStatusAxes()) msleep(Phytron_msMotionPolling);
do msleep(Phytron_msMotionPolling); while (PH_GetStatusAxes());
PH_DbgGetPosition(Q[i]);
PAUSE;
}
double Qerr=0;
#endif
double Perr=0;
printf(BLD WHT "%s\n" NRM, TB_Phytron_Status());
......@@ -751,7 +758,8 @@ int main(int argc, const char* argv[]) {
p[19], P2D(p[19]),
p[20], P2D(p[20]),
p[21], P2D(p[21]));
#ifdef USE_ENCODER
// Encoder
double *q=Q[i];
printf("\nenc\t%.2f\t%.2f\t%.0f\t%.2f\t%.0f\t%.2f\t%.0f\t%.1f\t%.1f",
q[19], P2D(q[19]),
......@@ -764,14 +772,13 @@ int main(int argc, const char* argv[]) {
p[20]-q[20], P2D(p[20]-q[20]),
p[21]-q[21], P2D(p[21]-q[21]));
Qerr+=fabs(P2D(q[19])-atof(argv[i]));
#endif
Perr+=fabs(P2D(p[19])-atof(argv[i]));
}
if (argc>1) {
printf("\nnoenc average positionning error at StepRes=%d:\t%.2fdeg\n\n", StepRes, Perr/(argc-1));
#ifdef USE_ENCODER
printf("\nenc average positionning error at StepRes=%d:\t%.2fdeg\n\n", StepRes, Qerr/(argc-1));
#endif
// Encoder
printf("\nencod average positionning error at StepRes=%d:\t%.2fdeg\n\n", StepRes, Qerr/(argc-1));
printf(BLD WHT "%s\n" NRM, TB_Phytron_Status());
}
......@@ -802,12 +809,21 @@ int TB_Phytron_Init(void) {
if ((Ret=PH_Reset())) return Ret;
if ((Ret=PH_DoGetGeneralStatus())) return Ret;
if ((Ret=PH_SetParamValue(45, Phytron_SpeedDiv))) return Ret; // Full step. Default was 1/6 ?
if ((Ret=PH_SetParamValue(45, Phytron_SpeedDiv))) return Ret;// Full step. Default was 1/6 ?
if ((Ret=PH_SetParamValue(2, 1))) return Ret; // Measuring unit of movement - Step
if ((Ret=PH_SetParamValue(39, GearReduction))) return Ret; // Encoder conversion factor - DOES NOT SEEM TO DO ANYTHING
if ((Ret=PH_SetParamValue (34, Phytron_UseEncoder))) return Ret;
if ((Ret=PH_MoveToLimit(-1))) return Ret;
// Check the effect of limits/timeout on initiator motion
Ret|=PH_SetParamValue(23, D2P(90)); // Axis + limitation
Ret|=PH_SetParamValue(24, D2P(0)); // Axis - limitation
// It works but it doesn't make sense: it should be the opposite
if ((Ret=PH_MoveToLimit(Phytron_MainDir))) return Ret;
do msleep(Phytron_msMotionPolling); while (PH_GetStatusAxes());
if ((Ret=PH_SetParamValueF(19, 0.))) return Ret; // Reset EL0P
if ((Ret=PH_SetParamValue (34, 0 ))) return Ret; // no encoder
printf(BLD GRN "================== PHYTRON MOTOR READY ==================\n" NRM);
Enabled=1;
return 0;
......@@ -846,7 +862,12 @@ char* TB_Phytron_Status(void) {
PH_SendCommand(Reply, "SE");
sprintf(String+strlen(String), "SE: %s\n", PH_GetSystemStatusExtendedMsg(Status = strtoul(Reply, NULL, 0x10)));
sprintf(String+strlen(String), "Hardware limits: -∞..+∞");
sprintf(String+strlen(String), "Encoder: %s\n", PH_GetParamValue(34)?"ON":"OFF");
sprintf(String+strlen(String), "M0P offset: +:%d, -:%d\n", PH_GetParamValue(11), PH_GetParamValue(12));
sprintf(String+strlen(String), "Axis limit pos: +:%.1fdeg, -:%.1fdeg\n", P2D(PH_GetParamValue(23)), P2D(PH_GetParamValue(24)));
// sprintf(String+strlen(String), "Hardware limits: -Inf..+Inf\n"); // TODO: check if there is a parameter for that
sprintf(String+strlen(String), "Software limits: %.0f..%.0f", Phytron_OpMin, Phytron_OpMax);
return String;
}
......@@ -858,6 +879,9 @@ char* TB_Phytron_Status(void) {
int TB_Phytron_MoveAbs(double Angle) {
int Ret;
if (!Enabled) { PrintErr("The system is not ready, call TB_Phytron_Init() before"); return 1; }
if (Angle<Phytron_OpMin or Phytron_OpMax<Angle) {
PrintErr("Attempt to move to %.1f out of allowed range %.0f..%.0fdeg",
Angle, Phytron_OpMin, Phytron_OpMax); return 1; }
// TODO: sanity check, but not really necessary as we have full 360deg motion
if ((Ret=PH_AbsPosition(Angle))) return Ret;
while (PH_GetStatusAxes()) msleep(Phytron_msMotionPolling);
......@@ -870,7 +894,7 @@ int TB_Phytron_MoveAbs(double Angle) {
/// HIPAR SD/1 for highest speed, 255 for lowest
///////////////////////////////////////////////////////////////////////////////
int TB_Phytron_SpeedDiv(int SD) {
return PH_SetParamValue(45, Phytron_SpeedDiv = (SD<1 ? 1 : SD>255 ? 255 : SD));
return PH_SetParamValue(45, Phytron_SpeedDiv = (SD<1 ? 1 : SD>256 ? 256 : SD));
}
///////////////////////////////////////////////////////////////////////////////
......
#ifndef __TB_PHYTRON_H
#define __TB_PHYTRON_H
extern char Phytron_IP[80]; // This is defined by the dhcp server configuration. See /etc/dhcp/dhcpd.conf file
extern int Phytron_Port;
extern int Phytron_msWait; // Min delay between command and reply and new command. 50ms seems safe enough
extern int Phytron_msMotionPolling; // Same as above, but higher value to limit the number of polling messages
extern int Phytron_SpeedDiv; // Speed divisor (1-fastest to 255-slowest)
extern double Phytron_MoveInDiode_Pos; // Precise angle where the diode is in the middle of the beam
extern char Phytron_IP[80]; // This is defined by the dhcp server configuration. See /etc/dhcp/dhcpd.conf file
extern int Phytron_Port; // Note that the Phytron opens several ports for various uses
extern int Phytron_msWait; // Min delay between command and reply and new command. 50ms seems safe enough
extern int Phytron_msMotionPolling; // Same as above, but higher value to limit the number of polling messages
extern int Phytron_SpeedDiv; // Speed divisor (1-fastest to 256-slowest)
extern double Phytron_MoveInDiode_Pos; // Precise angle where the diode is in the middle of the beam
extern double Phytron_OpMin, Phytron_OpMax; // Operational motion limits (in deg)
extern int Phytron_MainDir; // +1 if the homing should go for the positive direction, -1 otherwise
extern int Phytron_UseEncoder; // 1 to use encoder (if available). Must be set BEFORE init()
// Low level commands
......@@ -34,9 +37,9 @@ extern int PH_AxisStatusRequest(int val);
extern int PH_ResetAxis(void);
extern int PH_DoAxisStop(void);
extern int PH_EnAxisPowerStage(int val);
extern int PH_RelPosition(double val);
extern int PH_AbsPosition(double val);
extern int PH_FreeRunning(int val);
extern int PH_RelPosition(double val); // WARNING: Does not enforce limits (see below)
extern int PH_AbsPosition(double val); // WARNING: Does not enforce limits
extern int PH_FreeRunning(int val); // WARNING: Does not enforce limits
extern int PH_SetParamValue(int param,int val);
extern int PH_GetParamValue(int param);
......@@ -52,11 +55,10 @@ extern int PH_DoGetGeneralStatus(void);
// For use by common control program
extern int TB_Phytron_Init(void);
extern int TB_Phytron_Close(void);
extern int TB_Phytron_MoveAbs(double Angle);
extern int TB_Phytron_MoveAbs(double Angle); // Enforces operational limits
extern char* TB_Phytron_Status(void);
extern char* TB_Phytron_LastErrMsg(void);
extern int TB_Phytron_SpeedDiv(int SD);
extern int TB_Phytron_MoveInDiode(int Do);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment