#ifndef seleneLiftAxis_H #define seleneLiftAxis_H #include "seleneAngleAxis.h" #include "turboPmacAxis.h" #include "turboPmacController.h" /** * @brief Virtual axis for setting the height of the center of a Selene guide * * This axis acts as the "master" for a partnering seleneAngleAxis (i.e. it * controls the movement and polls the physical motors) */ class seleneLiftAxis : public turboPmacAxis { public: seleneLiftAxis(turboPmacController *pController, int liftAxisNo, int angleAxisNo, int realAxis1No, int realAxis2No); /** * @brief Destroy the seleneLiftAxis * */ virtual ~seleneLiftAxis(); /** * @brief Implementation of the `stop` function from asynMotorAxis * * @param acceleration Acceleration ACCEL from the motor record. This * value is currently not used. * @return asynStatus */ asynStatus stop(double acceleration); /** * @brief Implementation of the `doPoll` function from sinqAxis. The * parameters are described in the documentation of `sinqAxis::doPoll`. * * @param moving * @return asynStatus */ asynStatus doPoll(bool *moving); /** * @brief Set the target value for the detector angle and trigger a position * collection cycle * * @param position * @param relative * @param min_velocity * @param maxOffset_velocity * @param acceleration * @return asynStatus */ asynStatus doMove(double position, int relative, double min_velocity, double maxOffset_velocity, double acceleration); /** * @brief Start a movement to the target positions of this axis and the * attached seleneAngleAxis. * * @return asynStatus */ asynStatus startCombinedMove(); /** * @brief Readout of some values from the controller at IOC startup * * The following steps are performed: * - Read out the motor status, motor position, velocity and acceleration * from the MCU and store this information in the parameter library. * - Set the enable PV according to the initial status of the axis. * * @return asynStatus */ asynStatus init(); /** * @brief Reset the error(s) of both physical motors * * @param on * @return asynStatus */ asynStatus reset(); /** * @brief Enable / disable both physical motors * * @param on * @return asynStatus */ asynStatus enable(bool on); /** * @brief Override of the home function of asynMotorAxis, which does nothing * * @param on * @return asynStatus */ asynStatus home(double min_velocity, double maxOffset_velocity, double acceleration, int forwards) { return asynSuccess; } /** * @brief The encoder of both physical motors is absolute, hence the encoder * of the virtual axis is also absolute * * @return asynStatus */ asynStatus readEncoderType(); /** * @brief Trigger a rereading of the encoder position of both physical * motors * * @return asynStatus */ asynStatus rereadEncoder(); // TODO asynStatus normalizeOffsets(); /** * @brief Calculate the * * @param lift * @param angle * @return asynStatus */ double[6] calculateMotorPositions(double lift, double angle); protected: static const int numAxes_ = 6; turboPmacController *pC_; seleneAngleAxis *angleAxis_; turboPmacAxis axes_[numAxes_]; // Horizontal distance from the first axis in mm (which is located at 0 mm) double xOffset_[numAxes_]; // Vertical distance from the first axis in mm (which is located at 0 mm) double zOffset_[numAxes_]; double xLift_ = 0.0; }; #endif