1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 <2023> 2024 2025 | Index | 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 <2023> 2024 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Re: Weird behaviour in wait=True when using epics.Motor.get(something,something,wait=True) |
From: | "Marco A. Barra Montevechi Filho via Tech-talk" <tech-talk at aps.anl.gov> |
To: | Torsten Bögershausen <torsten.bogershausen at ess.eu>, "tech-talk at aps.anl.gov" <tech-talk at aps.anl.gov> |
Cc: | SWC <swc at lnls.br> |
Date: | Tue, 17 Jan 2023 16:52:05 +0000 |
Hi, Torsten, thanks for the answer.
> For your case, writing to CNEN and wait for the controller to have the amplifier switched on: Is this what you want ? Kinda. I just expect the function to return in one of two cases:
But what im getting seems to indicate that some other thing is happening:
Investigating the IOC code, the only time when the "SVO" command is used is in: #############################################
asynStatus PIGCSController::setServo(PIasynAxis* pAxis,
int servoState)
{
char cmd[100];
std::cout <<
"TESTE" <<
std::endl;
sprintf(cmd,
"SVO
%s %d",
pAxis->m_szAxisName, servoState);
asynStatus status = m_pInterface->sendOnly(cmd);
if (status != asynSuccess)
{
return status;
}
int err =
getGCSError();
if (COM_NO_ERROR == err)
{
pAxis->m_bServoControl =
(servoState == 1);
if (pAxis->m_bProblem &&
pAxis->m_bServoControl)
{
pAxis->m_bProblem =
false;
}
return asynSuccess;
}
asynPrint(m_pInterface->m_pCurrentLogSink,
ASYN_TRACE_ERROR|ASYN_TRACE_FLOW,
"Could not set servo state!\n");
return asynError;
} ############################################# which seems to mean that CNEN field is not being polled. A way i got to confirm this was: start IOC. Check CNEN value. CNEN value is 1. Change CNEN value to 0. Check CNEN value. CNEN value is 0. Restart IOC. Check CNEN value. CNEN value is still 1. If CNEN is not being polled, then there is no agent modifying its value, not even a driver response. If there is no driver response changing the value at database and i just did: Motor.put("CNEN", 0,wait=True) and my function returned in much less then the default timeout, why is CNEN value!=0 when i check it immediately after? Best regards, Marco From: Torsten Bögershausen <torsten.bogershausen at ess.eu>
Sent: 17 January 2023 04:22 To: Marco A. Barra Montevechi Filho <marco.filho at lnls.br>; tech-talk at aps.anl.gov <tech-talk at aps.anl.gov> Cc: SWC <swc at lnls.br> Subject: Re: Weird behaviour in wait=True when using epics.Motor.get(something,something,wait=True) Hej all.
I think that this behaviour is - what it is. In theory, the motorRecord could behave as you (and me) whish, in proactise there are too many applications depending on this frequent callbacks. So this commit: <https://github.com/epics-modules/motor/commit/c970afbfe71521d1587c51b0c7f3a634b03f5833> Had to be reverted later: <https://github.com/epics-modules/motor/commit/0ef39053aac72d8718ef99d08164da1be0825370> For your case, writing to CNEN and wait for the controller to have the amplifier switched on: Is this what you want ? On our systems this power-on can take 0.6 seconds (typically) up to 6 seconds (on a heavy drive, doing a self test after coldstart). And if the safety relay is off after a power-fail, it will never turn on. So yes, in principle we could change the motorRecord to do what we want: Wait for the driver to report "amplifier on". In practise we would need a time out. And a way to configure it. I am not sure if it ith worth the effort (to change the motorRecord) or if a simple poller with a timout in python is easier to implement. HTH BR /Torsten On 1/16/23 22:26, Marco A. Barra Montevechi Filho via Tech-talk wrote: > Good evening all. > > Im working with the same IOC i was using here: > https://epics.anl.gov/tech-talk/2023/msg00020.php > <https://epics.anl.gov/tech-talk/2023/msg00020.php>. Now i loaded some > motor records in it and am trying to control the IOC via pyepics. > Something weird is happening. > > i made the following python script: > > import epics > a = epics.Motor("MGN:B:E873A:DIAG:X:m1") > a.put("CNEN", 1,wait=True) > assert a.get("CNEN")==1 > > And i frequently get assertion errors. What is happening? Shouldn't > wait=True prevent this? How do i debug this? > Even more weird: i tried debugging this with callbacks: > > import epics, time > > a = epics.Motor( > "MGN:B:E873A:DIAG:X:m1") > > defprintvalue(**kwargs): > print(kwargs["value"]) > > b = epics.PV("MGN:B:E873A:DIAG:X:m1.CNEN") > b.add_callback(printvalue) > > c = 1 > > whileTrue: > c=1-c > print("#####") > a.put("CNEN",c) > time.sleep(0.1) > And i get prints like: > > ##### > 1 > ##### > 0 > ##### > 1 > 0 > ##### > > Why do i sometimes get two callbacks and sometimes get only one? Thanks > in advance for any help. > > I append the IOC initialization log and the substitutions file it loads: > > *INIT LOG:* > > #!/usr/local/epics/apps/pigcs2IOC/bin/linux-x86_64/pigcs2 > < /usr/local/epics/apps/pigcs2IOC/iocBoot/iocPIGCS2/envPaths > epicsEnvSet("IOC","iocPIGCS2") > epicsEnvSet("TOP","/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/motor-R7-1/modules/motorPIGCS2-R1-1/iocs/pigcs2IOC") > epicsEnvSet("SUPPORT","/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support") > epicsEnvSet("ASYN","/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/asyn-R4-36") > epicsEnvSet("STREAM","/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/StreamDevice-2-8-9") > epicsEnvSet("CALC","/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/calc-R3-7-3") > epicsEnvSet("RECCASTER","/usr/local/epics-nfs/apps/recsync/1.4_epics_3.15/client") > epicsEnvSet("SNCSEQ","/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/seq-2-2-6") > epicsEnvSet("BUSY","/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/busy-R1-7-2") > epicsEnvSet("IPAC","/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/ipac-2-15") > epicsEnvSet("MOTOR","/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/motor-R7-1") > epicsEnvSet("EPICS_BASE","/usr/local/epics-nfs/base/R3.15.6") > cd > "/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/motor-R7-1/modules/motorPIGCS2-R1-1/iocs/pigcs2IOC" > ## Set up environment > epicsEnvSet("DEV","MGN:B:E873A:DIAG:X:") > epicsEnvSet("BL", "MGN:B:E873A:DIAG:X") > epicsEnvSet("IOCNAME", "MGN-B-E873A-DIAG-X") > epicsEnvSet("EPICS_CA_MAX_ARRAY_BYTES",15728645) > # protocol file paths > epicsEnvSet ("STREAM_PROTOCOL_PATH", > ".:/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/motor-R7-1/db") > ## Register all support components > dbLoadDatabase "dbd/pigcs2.dbd" > pigcs2_registerRecordDeviceDriver pdbbase > cd > "/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/motor-R7-1/modules/motorPIGCS2-R1-1/iocs/pigcs2IOC/iocBoot/iocPIGCS2" > ## motorUtil (allstop & alldone) > dbLoadRecords("/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/motor-R7-1/db/motorUtil.db", "P=MGN:B:E873A:DIAG:X:") > ## > # < PI_GCS2.cmd > # PI GCS2 support > dbLoadTemplate("/usr/local/epics/apps/config/PIGCS2/e873aX.substitutions") > drvAsynIPPortConfigure("E873_ETH","CDE5B3D.abtlus.org.br:50000",0,0,0) > # Turn on asyn trace > # asynSetTraceMask("E873_ETH",0,3) > # asynSetTraceIOMask("E873_ETH",0,1) > # PI_GCS2_CreateController(portName, asynPort, numAxes, priority, > stackSize, movingPollingRate, idlePollingRate) > # # this is the final setup > # PI_GCS2_CreateController("E873", "E873_ETH", 1, 0, 0, 100, 1000) > # speedup debug > PI_GCS2_CreateController("E873", "E873_ETH", 1, 0, 0, 50, 1000) > 2023/01/16 18:23:03.949 read from E873_ETH: (c)2016-2020 Physik > Instrumente (PI) GmbH & Co. KG, E-873.1AT, 120040762, 03.033 > PIasynAxis::PIasynAxis() 0: 1 > ----------------- axis num: 0 createCLParams() m_szAxisName: > 1------------------- > # Turn off asyn trace > # asynSetTraceMask("E873_ETH",0,1) > # asynSetTraceIOMask("E873_ETH",0,0) > # Set end-of-string terminators (port, addr, terminator) > asynOctetSetInputEos("E873_ETH", 0, "\n") > asynOctetSetOutputEos("E873_ETH", 0, "\n") > dbLoadRecords("/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/motor-R7-1/modules/motorPIGCS2-R1-1/iocs/pigcs2IOC/db/PI_Support.db","P=MGN:B:E873A:DIAG:X:,R=m1:,PORT=E873,ADDR=0,TIMEOUT=1") > # asyn record for troubleshooting > dbLoadRecords("/usr/local/epics-nfs/modules/R3.15.6/synApps/R6.1/support/asyn-R4-36/db/asynRecord.db","P=MGN:B:E873A:DIAG:X:,R=asynEth,PORT=E873_ETH,ADDR=0,OMAX=256,IMAX=524288") > # RECSYNC > dbLoadRecords("/usr/local/epics-nfs/apps/recsync/1.4_epics_3.15/client/db/reccaster.db", "P=MGN:B:E873A:DIAG:X:REC:") > # protocol > #dbLoadRecords("$(MOTOR)/db/e873.db", "P=$(DEV),PORT=E873_ETH") > iocInit > Starting iocInit > ############################################################################ > ## EPICS R3.15.6 > ## EPICS Base built Sep 27 2021 > ############################################################################ > > > *e873aX.substitutions FILE:* > > file "$(MOTOR)/motorApp/Db/asyn_motor.db" > { > pattern > {P, M, DTYP, PORT, ADDR, DESC, EGU, DIR, > VELO, VBAS, ACCL, BDST, BVEL, BACC, MRES, PREC, DHLM, DLLM, > INIT} > {MGN:B:E873A:DIAG:X:, "m1", "asynMotor", "E873", 0, "Motor 1", > mm, Pos, 1, 0, .1, 0, 0, 0, 0.000001, 7, > 5.0, -5.0, ""} > } > > Aviso Legal: Esta mensagem e seus anexos podem conter informações > confidenciais e/ou de uso restrito. Observe atentamente seu conteúdo e > considere eventual consulta ao remetente antes de copiá-la, divulgá-la > ou distribuí-la. Se você recebeu esta mensagem por engano, por favor > avise o remetente e apague-a imediatamente. > > Disclaimer: This email and its attachments may contain confidential > and/or privileged information. Observe its content carefully and > consider possible querying to the sender before copying, disclosing or > distributing it. If you have received this email by mistake, please > notify the sender and delete it immediately. > |