epics-motor / motorVMC

Virtual Motor Controller
1 stars 1 forks source link

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 2 weeks ago

1458861693 commented 2 weeks ago

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 commented 2 weeks ago

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

kmpeters commented 2 weeks ago

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

kmpeters commented 2 weeks ago
  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 commented 2 weeks ago

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 commented 2 weeks ago
  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 commented 2 weeks ago

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 commented 1 week ago
  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 //.