pcdshub / lcls-twincat-motion

TwinCAT 3 Motion Control Utilities - PLC Motion Library for all PCDS Applications
https://pcdshub.github.io/lcls-twincat-motion
Other
35 stars 20 forks source link

ENH: PMPS Built-ins #80

Closed ZLLentz closed 4 years ago

ZLLentz commented 4 years ago

The goal of this PR is to define some motion-PMPS tie-ins that I don't want to write multiple times for each common component. The plan is to include:

This is not complete nor is it ready for a full review, but it will require a review from @slacAWallace when it is done. This PR will close #78 and go a bit further.

Change log (OUTDATED):

### `DUT_MotionStage` (modified) - IO link points for all encoder count data types - Summary variable for encoder count for EPICS (so all axes have the same PV regardless of IO data type) - `sName` field to provide a name for PMPS FFO - `bMoveOk` field as a PMPS API point - `sCustomErrorMessage` field for other programs to inject their own error messages/errors - `stAxisParameters` field for storing NC parameters - `bAxisParameters` field that is `TRUE` once the NC parameters have been loaded ### `DUT_PositionState` (modified) - `nEncoderCount` field to define states via encoder count - `bUseRawCounts` field to flag that we should use the encoder count field over the EGU position - `stBeamParams` field to define beam parameters for the state - `nRequestAssertionID` field to define a beam assertion ID for the arbiter ### `MOTION_GVL` (new) - `stUnknownState` to define parameters for unknown states (transitions, for example) - `stInvalidState` to define parameters for invalid states (state 7 on a 2-state device, for example) ### `FB_EncoderValue` (new) - Function block to update the encoder summary field in `DUT_MotionStage` ### `FB_MotionStage` (modified) - Modifications to facilitate `bMoveOk`, `sCustomErrorMessage`, `stAxisParameters, `bAxisParameters`, and encoder counts ### `FB_MotionStageNCParams` (new) - Function block to cyclically update `stAxisParameters` for other code that wants to check NC config ### `FB_EncErrorFFO` (new) - Function block to raise a fast fault when an axis has an encoder error ### `FB_NCErrorFFO` (new) - Function block to raise a fast fault when an axis has errors within predefined ranges ### `FB_PositionStatePMPS` (new) - Function block to facilitate arbiter and FFO for a state mover - Requests beam params and forces the motor to wait before moving ### `FB_EpicsInOut` (modified) - Remove now redundant lines (moved to `FB_PositionStateInternal`) ### `FB_EpicsInOutPMPS` (new) - Extension of `FB_EpicsInOut` to use `FB_PositionStatePMPS` and `FB_EncErrorFFO` as an example usage as a drop-in usable. ### `FB_PositionStateInternal` (new) - Master FB for processing `DUT_PositionState` - Facilitates encoder counts and locking ### `FB_PositionStateLock` (modified) - Add `bEnable` arg ### `FB_PositionStateManager` (modified) - Call `FB_PositionStateInternal` on all states ### `FB_PositionStateMove` (modified) - Do not allow moves until `FB_PositionStateInternal` has been called ### `FB_RawCountConverter` (new) - Utility function block for converting an axis's position in EGU to encoder counts and back ### `F_AtPositionState` and helpers (modified) - Expand to allow moves within a state to still count as being at that state, rather than counting as state unknown. - Do not count as at state if `FB_PositionStateInternal` has not been called. If this isn't called, state is unknown.
ZLLentz commented 4 years ago

I've gotten a bit stuck. I'm going to type out my confusion before calling it quits for the day.

The main issues I'm having are:

  1. I'm held up by the concept of the FB_LinearDeviceStateTable.

    • Who fills this table, and when?
    • What will the filled table look like?
    • How do I correlate physical position states with sets of valid beam states? E.g., when the user asks to move to YAG, how I do find the YAG states in the hash table and how do I pick which of them is correct?
  2. There are a lot of magic numbers to juggle, and I'm not sure what each number means and whether any of them are correlated. Do I request these numbers from the Arbiter? Do I make them up? Is it bad if they collide with each other? Do I let the PLC project handle them instead of doing in the Library? Here is a list of magic numbers that the PMPS API expects:

    • FB_FastFault.i_TypeCode (example number is the cryptic 16#9010)
    • BeamParameterTransitionManager.i_TransitionAssertionID (defaults to 0)
    • BeamParameterTransitionManager.i_nRequestedAssertionID (defaults to 0)
    • FB_LinearDeviceStateTable.key
  3. Some things aren't documented:

    • ST_BeamParams.neVRange (clearly a bitmask, but what do the bits mean?)
  4. It's not clear exactly which FBs and DUTs in the PMPS lib are meant for external use. My guess is that I need to manipulate these in the library:

    • ST_BeamParams
    • ST_Device
    • FB_FastFault
    • BeamParameterTransitionManager
    • FB_LinearGovernor
ZLLentz commented 4 years ago

@slacAWallace I have a lot of questions queued up about how to PMPS before I finish this PR

slacAWallace commented 4 years ago
  1. How do I correlate physical position states with sets of valid beam states? E.g., when the user asks to move to YAG, how I do find the YAG states in the hash table and how do I pick which of them is correct?

This will become a thing for SC, for now there will be only one combination of state and beam parameter set. In the SC case we'll need some higher-level automation to select the optimal combo of target state and beam parameter set.

  1. Fast fault typecode is left to us to build. We should discuss it. I have it purely for UI/UX. Request IDs need to be unique within an arbiter. Originally they were going to be unique globally in the PMPS so we could use a diagnostic to aggregate all preemptive requests from all arbiter instances and understand exactly who was requesting what. For this round they just need to be locally unique. I'll need to revisit the linear device key. It's been a while since I worked on that.

  2. I will document the eV bitmask better. There is a constant in PMPS_GVL which defines these ranges, and I'll make it clearer how and that they're associated.

  3. This indicates to me the library would be more user-friendly if I spent a little time organizing it. ST_Device and FB_LinearGovernor are examples. If FB_LinearGovernor looks useful to you, then with a bit of work it could be more permanent.

ZLLentz commented 4 years ago

Thanks Alex, your clarifications help a lot. I will do the following:

  1. I will ignore the hash table until we go SC and need to manage large numbers of states, in favor of tacking on ST_BeamParameters to every DUT_PositionState struct.
  2. I will pick a few fault codes for now based on NC error range, we can change them later. I'll require the request IDs to be passed in to the FB I provide.
  3. Now that I see the PMPS_GVL the bitmask does make more sense. I realize now that I don't need to use it until SC.
  4. I will opt to use FB_LinearGovernor as a starting point for ideas for the state governor to be built out here, since I'm not using the hash table and this FB expects it. My gov will fulfill the same purpose but will be expecting this library's native data types.
ZLLentz commented 4 years ago

I have finished the implementation phase here and have written a change log. I will proceed to testing and fixing issues offline.

ZLLentz commented 4 years ago

I'm fairly convinced that this is complete. I will try implementing it for the various common components next, then clean this messy PR up a bit and move in for the tag. With some luck this could be deployed in time for this PAMM, but even if not this is work that had to get finished.

ZLLentz commented 4 years ago

This is hitting the threshold of "please tag me so we don't run with v0.0.0 come back later to fix issues and re-tag"