Hi Mark,
I forgot to reply to all the last time, so I copy pasted your solution into this mail.
Yes, your second solution works quite well. Even though I put the " homingInProgress " variable into the header file. I pushed it to git:
https://github.com/MichaS-git/motorMicos
but it is the very first version and still needs further development and testing.
Thanks for the explanation!
Michael
>However, it works to compile with "pC_->lock();" and "pC_->unlock();". But it has no effect on the record-update.
Yes, my mistake. You need to use pC_->lock()/unlock().
To create a new thread you need to call epicsThreadCreate(). You pass it the address of a function to be called, and a void* pointer, which in this case would be “this”.
However, I just realized there is probably a simpler way to solve this problem.
- In your SMCpegasusAxis class create a new private bool variable called homingInProgress or something like that.
- In SMCpegasusAxis::home only do the following:
o set that homingInProgress variable to true
o Start the homing operation
- Change your SMCpegasusAxis::poll() routine so it does the following:
o If homingInProgress is true, and if the motor makes the transition from moving to not moving (homing is complete) then do the following:
Set homingInProgress to false
Send the string that needs to be sent to the controller when homing is complete
Does that seem like it would work?
Mark
________________________________________
From: Sintschuk, Michael <michael.sintschuk at bam.de>
Sent: Wednesday, June 30, 2021 8:18 AM
To: Mark Rivers
Subject: AW: questions about the motor homing sequence
Hi Mark,
> You can take that code and run it in a separate thread. You need to call lock() on entrance, and then release the lock around the sleep.
By calling lock() the separate thread is created or do I need to write the separate thread by my own, like a separate function? (sorry, I'm new to c++ )
When I try to compile my code with the the "lock();" and "unlock();" lines I get the error: 'lock' was not declared in this scope.
However, it works to compile with "pC_->lock();" and "pC_->unlock();". But it has no effect on the record-update.
Michael
-----Ursprüngliche Nachricht-----
Von: Mark Rivers <rivers at cars.uchicago.edu>
Gesendet: Dienstag, 29. Juni 2021 18:13
An: Sintschuk, Michael <michael.sintschuk at bam.de>
Cc: tech-talk at aps.anl.gov
Betreff: Re: questions about the motor homing sequence
Hi Michael,
> Having a while-loop with an threadSleep is kind of bad coding I think, so I'm wondering if someone knows a better solution?
You can take that code and run it in a separate thread. You need to call lock() on entrance, and then release the lock around the sleep.
unlock();
epicsThreadSleep(1);
lock();
> PS: I'm also trying to update the motor position during the while-loop (it is the "// Read the current motor position" passage). I see the correct position in the asyn communication but the .RBV value of the motor record won't update. I guess, this can only be done from the poll-function?
The poller should continue to run normally if you run the home sequence in a separate thread and call unlock() as shown above.
Mark
________________________________
From: Tech-talk <tech-talk-bounces at aps.anl.gov> on behalf of Sintschuk, Michael via Tech-talk <tech-talk at aps.anl.gov>
Sent: Tuesday, June 29, 2021 10:13 AM
To: tech-talk at aps.anl.gov
Subject: questions about the motor homing sequence
Hello EPICS-community,
I'm trying to write an EPICS-motor device support for the PEGASUS Rotation- and Linear-Stages from Micos. I'm using the Hydra and Corvus motor-support from the main EPICS-motor module as a template.
I have the following problem when writing the homing sequence for the Rotation-stages: after sending the homing-command string
sprintf(pC_->outString_, "1 0 %i setsw 1 1 %i setsw 1 0 %i sncal", (axisNo_ + 1), (axisNo_ + 1), (axisNo_ + 1));
pC_->writeController();
I need to wait until reference-drive finished aka. the motor stopped, so I can switch off the Limit-switches with the following command:
sprintf(pC_->outString_, "2 0 %i setsw 2 1 %i setsw", (axisNo_ + 1), (axisNo_ + 1));
pC_->writeController();
So far I could resolve this problem by implementing a while loop with an epicsThreadSleep(1.) asking the controller about its moving bit and once it set to 1 (done), execute the desired command. Here is my complete code of the homing function:
asynStatus SMCpegasusAxis::home(double baseVelocity, double slewVelocity, double acceleration, int forwards) {
asynStatus status;
int done = 0;
int axisStatus = -1;
double position = 0.0;
// static const char *functionName = "SMCpegasusAxis::home";
status = sendAccelAndVelocity(acceleration, slewVelocity);
if (forwards) {
sprintf(pC_->outString_, "1 0 %i setsw 1 1 %i setsw 1 0 %i sncal", (axisNo_ + 1), (axisNo_ + 1), (axisNo_ + 1));
pC_->writeController();
// Read the status of this motor
sprintf(pC_->outString_, "%i nst", (axisNo_ + 1));
pC_->writeReadController();
// The response string is an int
axisStatus = atoi( (char *) &pC_->inString_);
do
{
// Read the current motor position
sprintf(pC_->outString_, "%i np", (axisNo_ + 1));
pC_->writeReadController();
// The response string is a double
position = atof( (char *) &pC_->inString_);
setDoubleParam(pC_->motorPosition_, (position / axisRes_) );
setDoubleParam(pC_->motorEncoderPosition_, (position / axisRes_) );
// Read the status of this motor
sprintf(pC_->outString_, "%i nst", (axisNo_ + 1));
pC_->writeReadController();
// The response string is an int
axisStatus = atoi( (char *) &pC_->inString_);
// Check the moving bit
done = !(axisStatus & 0x1);
setIntegerParam(pC_->motorStatusDone_, done);
setIntegerParam(pC_->motorStatusMoving_, !done);
epicsThreadSleep(1.);
} while (done == 0);
//epicsThreadSleep(3.);
sprintf(pC_->outString_, "2 0 %i setsw 2 1 %i setsw", (axisNo_ + 1), (axisNo_ + 1));
} else {
//still ToDo the Home Run backward
}
status = pC_->writeController();
return status;
}
Having a while-loop with an threadSleep is kind of bad coding I think, so I'm wondering if someone knows a better solution?
PS: I'm also trying to update the motor position during the while-loop (it is the "// Read the current motor position" passage). I see the correct position in the asyn communication but the .RBV value of the motor record won't update. I guess, this can only be done from the poll-function?
Best regards
Michael
Michael Sintschuk
Bundesanstalt für Materialforschung und –prüfung (BAM)
8.5 Mikro-ZfP
Unter den Eichen 87
12205 Berlin
GERMANY
P: +49 30 8062-15063 (BESSY, Adlershof)
P: +49 30 8104-4065 (BAM, Steglitz)
michael.sintschuk at bam.de<mailto:michael.sintschuk at bam.de>
- References:
- questions about the motor homing sequence Sintschuk, Michael via Tech-talk
- Re: questions about the motor homing sequence Mark Rivers via Tech-talk
- Navigate by Date:
- Prev:
Re: Kubernetes for EPICS IOCs Josh Fiddler via Tech-talk
- Next:
Re: Event Recordings -- Epics Spring 2021 Knap, Giles (DLSLtd,RAL,LSCI) via Tech-talk
- 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
- Navigate by Thread:
- Prev:
Re: questions about the motor homing sequence Mark Rivers via Tech-talk
- Next:
porting IOCs from Linux to RTEMS Siddons, David via Tech-talk
- 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
|