Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I meet some problems when I tried writing a motor driver for my Step Motor Controller by modified some examples in Motor module. #22

Open
1458861693 opened this issue Aug 27, 2024 · 9 comments

Comments

@1458861693
Copy link

I meet some problems when I tried writing a motor driver for my Step Motor Controller by modified motorVMC and motorAcs in Motor module. I have tried many times, but there are still some problems in my motor driver. I hope to receive your help very much.
My modified motor driver is committed as a compress file as follow.

motorAcs.zip

I have some questions, if you could give me some help, I would be extremely grateful.

  1. In this directory : synApps_6_1/support/motor/modules/motorAcs/acsApp/src

ls@ubuntu64:~/epics/softIoc/synApps_6_1/support/motor/modules/motorAcs/acsApp/src$ ls
AcsRegister.cc devAcsMotor.dbd drvMCB4B.cc Makefile MCB4BDriver.h O.linux-x86_64
AcsRegister.h devMCB4B.cc drvMCB4B.h MCB4BDriver.cpp O.Common

Can I only modify MCB4BDriver.cpp and comment on AcsRegister.cc、drvMCB4B.cc、devMCB4B.cc in Makefile?
What is the function of these files(AcsRegister.cc、drvMCB4B.cc、devMCB4B.cc)?

  1. In My Motor Driver, I have modified the poll() function to query motor status periodically, but why some ascii commands can be sent, however some commands can't be send. It's strange enough.
    In My motor driver, there are five ascii commands to query axis Status.
    By set trace code, I can find only "GET_RUN"、"GET_POS"、"GET_NEG" can be sent, "GET_P" and “”GET_ZERO“ can't be sent.
    Is some other place that i need to modify?

  2. How and where can i initialize the axis?

  3. Why did I set motor record's VAL or DVAL to zero, the motor doesn't move. But for any other VAL, the motor will move.

  4. I want to get the position of axis from encoder when i set UEIP to "YES", what should i do?

My questions maybe simple, but it really confuses me. I hope to receive your help very much.
Looking forward to your help. Thanks very much!

@prjemian
Copy link

prjemian commented Aug 27, 2024

Last message (now removed by GitHub) was a phish, very similar to one in area detector yesterday. Stomp them out quickly.

@kmpeters
Copy link
Contributor

@prjemian, I don't see a phishing message. This looks like a real request for help.

@kmpeters
Copy link
Contributor

  1. The motorAcs/acsApp/src contains two different drivers for ACS controllers. There is a model-1 driver (AcsRegister.cc, drvMCB4B.cc, devMCB4B.cc) and a model-3 asyn motor driver (MCB4BDriver.cpp). We strongly recommend only developing new model-3 asyn motor drivers because they are much more extensible than model-1 drivers. The approach I would recommend is copying MCB4BDriver.cpp and MCB4BDriver.h to new files named after the new stepper motor controller, and then modifying the support to use appropriate commands.

  2. You can use the asyn trace masks to enable debug messages that can show you why some commands succeed and others don't:

https://github.com/epics-motor/motorAcs/blob/cc156ae788a2dc49a0c86c3a66f5006a161b9eaf/iocs/acsIOC/iocBoot/iocAcs/st.cmd.mcb4b#L14-L15

You can also load an asyn record, which makes it easy to change the trace masks and can also be used to manually send commands to the controller:

https://github.com/epics-motor/motorAcs/blob/cc156ae788a2dc49a0c86c3a66f5006a161b9eaf/iocs/acsIOC/iocBoot/iocAcs/st.cmd.mcb4b#L22

  1. I would initialize the axis in the constructor for the axis class:

https://github.com/epics-motor/motorAcs/blob/cc156ae788a2dc49a0c86c3a66f5006a161b9eaf/acsApp/src/MCB4BDriver.cpp#L120-L124

  1. The move method looks OK to me:
asynStatus MCB4BAxis::move(double position, int relative, double minVelocity, double maxVelocity, double acceleration)
{
  asynStatus status;
  // static const char *functionName = "MCB4BAxis::move";

  status = sendAccelAndVelocity(acceleration, maxVelocity);
  
  // if (relative) {
  //   sprintf(pC_->outString_, "#%02dI%+d", axisNo_, NINT(position));
  // } else {
  //   sprintf(pC_->outString_, "#%02dG%+d", axisNo_, NINT(position));
  // }

  if (relative) {
    sprintf(pC_->outString_, "P_REL %d %d", axisNo_, NINT(position));
  } else {
    sprintf(pC_->outString_, "P_ABS %d %d", axisNo_, NINT(position));
  }
  
  status = pC_->writeReadController();
  return status;
}

You should enable asyn traces, move the motor to a non-zero position and then to zero, and see if the move commands appear in the asyn trace output. Maybe a relative move of zero is being commanded when an absolute move is expected?

  1. Before UEIP can be set to YES, the driver needs to set the motor record's "encoder present" status bit and the poller needs to read and update the encoder position, in addition to the motor (theoretical) position. I'll try to find an example of this.

@prjemian
Copy link

I reported the "phish" comment as SPAM to GitHub. They investigated and removed it from the history. The original posting is not (I believe) SPAM or phish.

@kmpeters
Copy link
Contributor

  1. Before UEIP can be set to YES, the driver needs to set the motor record's "encoder present" status bit and the poller needs to read and update the encoder position, in addition to the motor (theoretical) position. I'll try to find an example of this.

@1458861693, the Parker ACR driver is a good example. The motor record is told that the axis supports encoders in the constructor:

https://github.com/epics-motor/motorParker/blob/f6b7eb83fe1747ebd9122fae82034151818240b6/parkerApp/src/ACRMotorDriver.cpp#L304-L305

And the axis poll method sets both the encoder and motor positions:

https://github.com/epics-motor/motorParker/blob/f6b7eb83fe1747ebd9122fae82034151818240b6/parkerApp/src/ACRMotorDriver.cpp#L434-L446

@1458861693
Copy link
Author

1458861693 commented Aug 29, 2024

Thanks for your help very much. I have solved most problems above described, but there are still several problems.

  1. For fourth problem above described, could you tell me when the "relative" parameters in move method is 1(true) and when it is zero(false), because the "relative" parameters determine that the axis is absolute move or relative move.

  2. For these fields: VAL、DVAL、TWV、RLV..., I want to know what parameters that I changed and what circumstances will cause absolute move, and what parameters changed will cause relative move.
    When I change the motor record 's VAL field, I find that if i set the retry counts to zero, it will cause absolute move. But if i set the retry counts greater than 0, it will cause relative move. And i think this is related to why ascii command can't be sent when position is 0.

  3. For move() and setPosition() method, What is the value of "position" parameters and how is the "position" parameters calculated?
    I'm not sure that if it is calculated as this:
    absolute move : absolute position(VAL field)/MRES ?
    relative move : relative position(RLV field)/MRES ?
    Is it all like this for UEIP is 1 or 0?

  4. For this debug code in setPosition() and move() methods, how can i see the output debug message.
    // asynPrint(pasynUser_, ASYN_TRACE_FLOW, "position=%f\n", position);
    I have set the traceMask to 0x3F(all ON) in asyn record, but i can't still find the output debug message in trace file.

Looking forward to your help. Thanks you very much.
Thanks again.

@kmpeters
Copy link
Contributor

kmpeters commented Sep 3, 2024

  1. The most common condition that causes relative moves is setting UEIP=Yes and RTRY>0.

The motor record does the following calculation to determine if relative moves should be used:

bool use_rel = (pmr->rtry != 0 && pmr->rmod != motorRMOD_I && (pmr->ueip || pmr->urip));

Source: https://github.com/epics-modules/motor/blob/f1159c66a686d5c596049174cd53ecd3e5e209a4/motorApp/MotorSrc/motorRecord.cc#L922

It uses the use_rel variable to determine determine whether a MOVE_REL or MOVE_ABS message should be written to device support:

https://github.com/epics-modules/motor/blob/f1159c66a686d5c596049174cd53ecd3e5e209a4/motorApp/MotorSrc/motorRecord.cc#L942-L945

Asyn motor device support creates a relative move transaction, which eventually gets sent ot the motor driver:

https://github.com/epics-modules/motor/blob/f1159c66a686d5c596049174cd53ecd3e5e209a4/motorApp/MotorSrc/devMotorAsyn.c#L509

The asynMotorController's writeFloat64 method is what calls the driver's move method with relative=1:

https://github.com/epics-modules/motor/blob/f1159c66a686d5c596049174cd53ecd3e5e209a4/motorApp/MotorSrc/asynMotorController.cpp#L299

  1. VAL, DVAL, RLV, TWF, and TWR all result in the same type of move being issued to the controller, which is dependent on the values of UEIP, URIP, RMOD, and RTRY. If UEIP=Yes and RTRY>0, any move that is commanded from EPICS results in a relative move. Using the RLV, TWF, and TWR fields results in the VAL field being updated by the specified displacement.

  2. The motor record appears to always calculate the position as DVAL / MRES, regardless of whether absolute or relative moves are being used:

https://github.com/epics-modules/motor/blob/f1159c66a686d5c596049174cd53ecd3e5e209a4/motorApp/MotorSrc/motorRecord.cc#L3767

It is up to the driver to determine what should be done for an axis with an encoder. I think the OMS MAXv driver sets both the motor's position and encoder's position to the value passed by the motor record, if the axis is configured to have an encoder.

  1. If you change ASYN_TRACE_FLOW to ASYN_TRACE_ERROR you can leave only the error traces enable, which should greatly reduce the amount of information that is written to the log file. If the debug code is commented out, you'll need to remove the preceding // .

@1458861693
Copy link
Author

OK, Thanks for your reply very much. I have finished the motor driver and it works fine.
But recently, there seem to be some problems.

motorx_all

As shown in this picture, the error between motor value and readback is -1.6634, this error is greater than Retry deadband(0.4).
Strangely, the times of retry is 1 and it is smaller than 5, i.e. the max retry times. It seems that the retry doesn't work fine. But it's not always like this.

If I change the motor position value at this time, the error between motor value and readback is possible smaller than the deadband.

So, What should I do to solve this problem?
Looking forward to your reply. Thanks very much.

@github-staff github-staff deleted a comment from YeGop0218 Oct 28, 2024
@kmpeters
Copy link
Contributor

I'm not sure what is wrong with the motor record in the picture. The "Controller Error" and "Comm Error" messages are present in the upper right-hand corner of the screen, which usually indicates a problem talking to the controller. A communication error would explain why the retries weren't exhausted.

What are the errors on the the IOC's shell when this happens?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants