AMAction3* BioXASMirrorRollControl::createMoveAction(double setpoint) { AMAction3 *result = 0; if (isConnected()) { AMListAction3 *move = new AMListAction3(new AMListActionInfo3(name()+" move", name()+" move"), AMListAction3::Parallel); double pitch = calculatePitch(upstreamInboard_->xPosition(), upstreamInboard_->yPosition(), upstreamInboard_->zPositionSetpoint(), upstreamOutboard_->xPosition(), upstreamOutboard_->yPosition(), upstreamOutboard_->zPositionSetpoint(), downstream_->xPosition(), downstream_->yPosition(), downstream_->zPositionSetpoint()); double height = calculateHeight(upstreamInboard_->xPosition(), upstreamInboard_->yPosition(), upstreamInboard_->zPositionSetpoint(), upstreamOutboard_->xPosition(), upstreamOutboard_->yPosition(), upstreamOutboard_->zPositionSetpoint(), downstream_->xPosition(), downstream_->yPosition(), downstream_->zPositionSetpoint()); double upstreamInboardDestination = calculateUpstreamInboardPosition(upstreamInboard_->xPosition(), upstreamInboard_->yPosition(), pitch, setpoint, height); move->addSubAction(AMActionSupport::buildControlMoveAction(upstreamInboard_, upstreamInboardDestination)); double upstreamOutboardDestination = calculateUpstreamOutboardPosition(upstreamOutboard_->xPosition(), upstreamOutboard_->yPosition(), pitch, setpoint, height); move->addSubAction(AMActionSupport::buildControlMoveAction(upstreamOutboard_, upstreamOutboardDestination)); double downstreamDestination = calculateDownstreamPosition(downstream_->xPosition(), downstream_->yPosition(), pitch, setpoint, height); move->addSubAction(AMActionSupport::buildControlMoveAction(downstream_, downstreamDestination)); result = move; } return result; }
AMAction3* VESPERSEnergyScanActionController::createCleanupActions() { AMListAction3 *cleanupAction = qobject_cast<AMListAction3 *>(buildCleanupAction()); cleanupAction->addSubAction(VESPERSBeamline::vespers()->mono()->createEaAction(originalEnergy_)); return cleanupAction;}
AMAction3 * SGMGratingAngleControl::createMoveAction(double setpoint) { AMListAction3* moveAction = new AMListAction3(new AMListActionInfo3("Moving Grating Angle", "Moving Grating Angle"), AMListAction3::Sequential); if(isClosedLoop()) { moveAction->addSubAction(AMActionSupport::buildControlMoveAction(encoderControl_, setpoint)); } else { // Get distance to move in terms of the encoder double deltaDistanceEncoder = setpoint - value(); // Convert into steps double deltaDistanceSteps = deltaDistanceEncoder * stepsPerEncoderCount(); // Get current step position double currentStepPosition = stepMotorControl_->value(); // Get the setpoint in terms of steps double stepSetpoint = currentStepPosition + deltaDistanceSteps; // Up our tolerance moveAction->addSubAction(new AMChangeToleranceAction(new AMChangeToleranceActionInfo(toInfo(), 400),this)); // Do the move moveAction->addSubAction(AMActionSupport::buildControlMoveAction(stepMotorControl_, stepSetpoint)); } return moveAction; }
AMAction3* SGMVATValveState::createMoveAction(double indexSetpoint) { AMListAction3 *action = new AMListAction3(new AMListActionInfo3("Moving leak valve", "Moving leak valve"), AMListAction3::Sequential); AMAction3 *updateSpeed = 0; // If the valve is opening, always want to move at the min speed. if (int(indexSetpoint) == Open) updateSpeed = AMActionSupport::buildControlMoveAction(speed_, SGMVATVALVE_SPEED_MIN); else updateSpeed = AMActionSupport::buildControlMoveAction(speed_, SGMVATVALVE_SPEED_MAX); // Add modifying the speed to the list of actions. action->addSubAction(updateSpeed); // Add the valve position change. action->addSubAction(AMSingleEnumeratedControl::createMoveAction(indexSetpoint)); // Return the action. return action; }
void AMAppController::updateScanEditorModelItem() { // Get the action, or if it's in a list, the current running action. AMAction3 *currentAction = AMActionRunner3::workflow()->currentAction(); AMScanAction *action = 0; if (currentAction && !currentAction->hasChildren()) action = qobject_cast<AMScanAction *>(currentAction); else if (currentAction && currentAction->hasChildren()){ AMListAction3 *listAction = qobject_cast<AMListAction3 *>(currentAction); if (listAction) action = qobject_cast<AMScanAction *>(listAction->currentSubAction()); } // Do something with it if the action is valid. if (action && (action->state() == AMAction3::Running || action->inFinalState())){ AMGenericScanEditor *editor = editorFromScan(action->controller()->scan()); if (!editor) return; QString stateString; switch(action->state()){ case AMAction3::Running: stateString = "running"; break; case AMAction3::Succeeded: stateString = "succeeded"; break; case AMAction3::Failed: stateString = "failed"; break; case AMAction3::Cancelled: stateString = "cancelled"; break; default: stateString = "default"; break; } AMScanEditorModelItem *item = (AMScanEditorModelItem *)(mw_->windowPaneModel()->itemFromIndex(mw_->windowPaneModel()->indexForPane(editor))); if (item) item->scanActionStateChanged(stateString, editor == mw_->currentPane()); } }
AMAction3* IDEASBeamline::createScanCleanupAction(AMScanConfiguration *configuration) { Q_UNUSED(configuration) AMListAction3 *cleanupActions = new AMListAction3(new AMListActionInfo3("IDEAS XAS Cleanup Actions", "IDEAS XAS Cleanup Actions")); cleanupActions->addSubAction(IDEASBeamline::ideas()->scaler()->createDwellTimeAction3(0.25)); cleanupActions->addSubAction(IDEASBeamline::ideas()->scaler()->createContinuousEnableAction3(true)); return cleanupActions; }
AMAction3* AMScanActionControllerScanAssembler::generateActionTreeForStepAxis(AMControl *axisControl, AMScanAxis *stepScanAxis){ AMListAction3 *axisActions = new AMListAction3(new AMListActionInfo3(QString("Axis %1").arg(axisControl->name()), QString("Axis %1").arg(axisControl->name())), AMListAction3::Sequential); // generate axis initialization list AMListAction3 *initializationActions = new AMListAction3(new AMListActionInfo3(QString("Initializing %1").arg(axisControl->name()), QString("Initializing Axis with Control %1").arg(axisControl->name())), AMListAction3::Sequential); AMControlInfo initializeControlPositionSetpoint = axisControl->toInfo(); initializeControlPositionSetpoint.setValue(stepScanAxis->axisStart()); AMControlMoveAction3 *initializeControlPosition = new AMControlMoveAction3(new AMControlMoveActionInfo3(initializeControlPositionSetpoint), axisControl); initializeControlPosition->setGenerateScanActionMessage(true); initializationActions->addSubAction(initializeControlPosition); AMListAction3 *allRegionsList = new AMListAction3(new AMListActionInfo3(QString("%1 Regions for %2 Axis").arg(stepScanAxis->regionCount()).arg(axisControl->name()), QString("%1 Regions for %2 Axis").arg(stepScanAxis->regionCount()).arg(axisControl->name())), AMListAction3::Sequential); for(int x = 0; x < stepScanAxis->regionCount(); x++) allRegionsList->addSubAction(generateActionTreeForStepAxisRegion(axisControl, stepScanAxis->regionAt(x), (x == stepScanAxis->regionCount()-1) )); // generate axis cleanup list AMListAction3 *cleanupActions = new AMListAction3(new AMListActionInfo3(QString("Cleaning Up %1").arg(axisControl->name()), QString("Cleaning Up Axis with Control %1").arg(axisControl->name())), AMListAction3::Sequential); AMAxisStartedAction *axisStartAction = new AMAxisStartedAction(new AMAxisStartedActionInfo(QString("%1 Axis").arg(axisControl->name()), AMScanAxis::StepAxis)); AMAxisFinishedAction *axisFinishAction = new AMAxisFinishedAction(new AMAxisFinishedActionInfo(QString("%1 Axis").arg(axisControl->name()))); axisActions->addSubAction(axisStartAction); axisActions->addSubAction(initializationActions); axisActions->addSubAction(allRegionsList); axisActions->addSubAction(cleanupActions); axisActions->addSubAction(axisFinishAction); return axisActions; }
AMAction3 * SGMUndulatorControl::createMoveAction(double setpoint) { AMListAction3* moveAction = new AMListAction3(new AMListActionInfo3("Moving Undulator", "Moving Undulator"), AMListAction3::Sequential); moveAction->addSubAction(AMActionSupport::buildControlMoveAction(encoderControl_, setpoint)); return moveAction; }
QList<AMAction3*> findActionsOfType(AMAction3 *rootAction, AMAction3 *typeAction){ QList<AMAction3*> retVal; AMListAction3 *castToListAction = qobject_cast<AMListAction3*>(rootAction); if(castToListAction){ for(int x = 0; x < castToListAction->subActionCount(); x++){ if(typeAction->metaObject()->className() == castToListAction->subActionAt(x)->metaObject()->className()) retVal.append(castToListAction->subActionAt(x)); retVal.append((findActionsOfType(castToListAction->subActionAt(x), typeAction))); } } return retVal; }
AMAction3* BioXASCarbonFilterFarmActuatorPositionControl::createMoveAction(double setpoint) { AMListAction3 *action = new AMListAction3(new AMListActionInfo3("Move BioXAS Carbon Filter Farm Actuator", "Move BioXAS Carbon Filter Farm Actuator"), AMListAction3::Sequential); AMAction3 *move = AMActionSupport::buildControlMoveAction(position_, setpoint); action->addSubAction(move); AMAction3 *check = AMActionSupport::buildControlWaitAction(status_, InPosition, TIMEOUT_MOVE); action->addSubAction(check); return action; }
AMAction3 *CLSMAXvMotor::createCalibrationAction(double oldPosition, double newPosition) { AMAction3 *result = 0; if (isConnected()) { AMListAction3 *calibrationAction = new AMListAction3(new AMListActionInfo3("Motor calibration", "Motor calibration"), AMListAction3::Sequential); calibrationAction->addSubAction(AMActionSupport::buildControlMoveAction(this, oldPosition)); calibrationAction->addSubAction(AMActionSupport::buildControlMoveAction(EGUSetPosition_, newPosition)); result = calibrationAction; } return result; }
AMAction3 * AM3DCoordinatedSystemControl::createMoveAction(double setpoint) { AMListAction3* action = 0; if(globalXAxis_ && globalYAxis_ && globalZAxis_) { action = new AMListAction3(new AMListActionInfo3(QString("Moving %1").arg(name()), QString("Moving %1 from %2 to %3") .arg(value()).arg(setpoint)), AMListAction3::Sequential); AMListAction3* moveActions = new AMListAction3(new AMListActionInfo3(QString("Moving %1").arg(name()), QString("Moving %1").arg(name())), AMListAction3::Parallel); // Grab the current global positions: QVector3D currentGlobalSetpoints(globalXAxis_->setpoint(), globalYAxis_->setpoint(), globalZAxis_->setpoint()); // Transform it to our system: QVector3D primeSetpoint = globalAxisToPrime(currentGlobalSetpoints); // Set the value in terms of our system based on the axis we are: switch(axis_) { case XAxis: primeSetpoint.setX(setpoint); break; case YAxis: primeSetpoint.setY(setpoint); break; case ZAxis: primeSetpoint.setZ(setpoint); } // Transform back the the global system: QVector3D newGlobalSetpoints = primeAxisToGlobal(primeSetpoint); // Create the required move actions in the global system: moveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalXAxis_, newGlobalSetpoints.x())); moveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalYAxis_, newGlobalSetpoints.y())); moveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalZAxis_, newGlobalSetpoints.z())); action->addSubAction(moveActions); } return action; }
AMAction3* IDEASBeamline::createScanInitializationAction(AMScanConfiguration *configuration) { AMAction3 *result = 0; AMStepScanConfiguration *stepScanConfiguration = qobject_cast<AMStepScanConfiguration*>(configuration); if (stepScanConfiguration) { AMListAction3 *initializationActions = new AMListAction3(new AMListActionInfo3("IDEAS XAS Initialization Stage 1", "IDEAS XAS Initialization Stage 1"), AMListAction3::Parallel); initializationActions->addSubAction(AMBeamline::createInitializeScanAxisControlsAction(stepScanConfiguration)); initializationActions->addSubAction(IDEASBeamline::ideas()->scaler()->createContinuousEnableAction3(false)); initializationActions->addSubAction(IDEASBeamline::ideas()->scaler()->createDwellTimeAction3(stepScanConfiguration->scanAxisAt(0)->regionAt(0)->regionTime())); result = initializationActions; } return result; }
CLSSIS3820ScalerDarkCurrentMeasurementAction::CLSSIS3820ScalerDarkCurrentMeasurementAction(CLSSIS3820ScalerDarkCurrentMeasurementActionInfo *info, QObject *parent) : AMListAction3(info, AMListAction3::Sequential, parent) { CLSSIS3820Scaler *scaler = CLSBeamline::clsBeamline()->scaler(); double secondsDwell = scalerDarkCurrentMeasurementActionInfo()->dwellTime(); connect( this, SIGNAL(failed()), this, SLOT(onActionFailed()) ); if (scaler && scaler->isConnected() && secondsDwell > 0) { // pre-measurement settings. double oldDwell = scaler->dwellTime(); // first turn off beam. // addSubAction(AMBeamline::bl()->createTurnOffBeamActions()); // set the scaler's dwell time to new time. addSubAction(scaler->createDwellTimeAction3(secondsDwell)); // initiate a scaler measurement and wait until it is complete. addSubAction(scaler->createStartAction3(true)); addSubAction(scaler->createWaitForDwellFinishedAction(secondsDwell + 5.0)); // notify attached and able scaler channel detectors that the latest measurement was a dark current measurement. AMListAction3 *notifyChannelDetectors = new AMListAction3(new AMListActionInfo3("Set last measurement as dark current measurement", "Set last measurement as dark current measurement")); for (int i = 0; i < scaler->channels().count(); i++) { CLSSIS3820ScalerChannel *channel = scaler->channelAt(i); if (channel && channel->isEnabled() && channel->detector() && channel->detector()->canDoDarkCurrentCorrection()) { notifyChannelDetectors->addSubAction(channel->detector()->createSetLastMeasurementAsDarkCurrentAction()); } } addSubAction(notifyChannelDetectors); // reset settings to pre-measurement conditions. addSubAction(scaler->createDwellTimeAction3(oldDwell)); } else { AMErrorMon::alert(this, CLSSIS3820SCALERDARKCURRENTMEASUREMENTACTION_SCALER_NOT_VALID, "Failed to complete dark current measurement--scaler not valid."); setFailed(); } }
// Copy constructor. Takes care of making copies of the sub-actions AMListAction3::AMListAction3(const AMListAction3& other) : AMAction3(other) { currentSubActionIndex_ = -1; // prior to running an subactions subActionMode_ = other.subActionMode_; if(subActionMode_ == AMListAction3::Parallel) AMAction3::info()->setIconFileName(":/32x32/format-line-spacing-triple.png"); logSubActionsSeparately_ = other.shouldLogSubActionsSeparately(); logActionId_ = other.logActionId(); skipAfterCurrentAction_ = false; loggingDatabase_ = other.loggingDatabase(); if (subActionMode_ == Sequential) skipOptions_.append("After current action"); foreach(AMAction3* action, other.subActions_) subActions_ << action->createCopy(); foreach(AMAction3* action, subActions_) action->setParentAction(this); }
AMAction3 *REIXSBeamline::buildBeamStateChangeAction(bool beamOn) const { AMListAction3 *list = new AMListAction3(new AMListActionInfo3("REIXS Beam On", "REIXS Beam Off")); if (beamOn){ if (REIXSBeamline::bl()->valvesAndShutters()->ssh1()->value() != 1.0) list->addSubAction(AMActionSupport::buildControlMoveAction(REIXSBeamline::bl()->valvesAndShutters()->ssh1(), 1.0)); if (REIXSBeamline::bl()->valvesAndShutters()->psh2()->value() != 1.0) list->addSubAction(AMActionSupport::buildControlMoveAction(REIXSBeamline::bl()->valvesAndShutters()->psh2(), 1.0)); if (REIXSBeamline::bl()->valvesAndShutters()->psh4()->value() != 1.0) list->addSubAction(AMActionSupport::buildControlMoveAction(REIXSBeamline::bl()->valvesAndShutters()->psh4(), 1.0)); } else if (!beamOn && REIXSBeamline::bl()->valvesAndShutters()->psh4()->value() != 0.0) list->addSubAction(AMActionSupport::buildControlMoveAction(REIXSBeamline::bl()->valvesAndShutters()->psh4(), 0.0)); return list; }
AMAction3* CLSSIS3820ScalerDarkCurrentMeasurementAction::createMeasurementAction(double secondsDwell) { AMAction3 *result = 0; CLSSIS3820Scaler *scaler = CLSBeamline::clsBeamline()->scaler(); if (scaler) { AMListAction3 *measurementAction = new AMListAction3(new AMListActionInfo3("Taking dark current measurement.", "Taking dark current measurement."), AMListAction3::Sequential); measurementAction->addSubAction(scaler->createDwellTimeAction3(secondsDwell)); measurementAction->addSubAction(scaler->createTriggerAction(AMDetectorDefinitions::SingleRead)); AMListAction3 *notifyChannelDetectors = new AMListAction3(new AMListActionInfo3("Set last measurement as dark current measurement", "Set last measurement as dark current measurement")); for (int i = 0; i < scaler->channels().count(); i++) { CLSSIS3820ScalerChannel *channel = scaler->channelAt(i); if (channel && channel->isEnabled() && channel->detector() && channel->detector()->canDoDarkCurrentCorrection()) { notifyChannelDetectors->addSubAction(channel->detector()->createSetLastMeasurementAsDarkCurrentAction()); } } measurementAction->addSubAction(notifyChannelDetectors); result = measurementAction; } return result; }
AMAction3* BioXASSSRLMonochromatorRegionControl::createMoveAction(double newRegion) { AMListAction3 *action = 0; if (value_ != newRegion && validValue(newRegion)) { action = new AMListAction3(new AMListActionInfo3("CrystalChange", "BioXAS SSRL Mono Crystal Change Action"), AMListAction3::Sequential); action->addSubAction(createCloseMaskBladesAction()); action->addSubAction(createRemovePaddleAction()); action->addSubAction(createWaitForKeyEnabledAction()); action->addSubAction(createMoveBraggToCrystalChangePositionAction(int(value_))); action->addSubAction(createWaitForBrakeDisabledAction()); action->addSubAction(createMoveCrystalChangeToRegionLimitAction(int(newRegion))); action->addSubAction(createWaitForBrakeEnabledAction()); action->addSubAction(createMoveBraggToRegionAction(int(newRegion))); action->addSubAction(createWaitForKeyDisabledAction()); // Make additional action connections. connect( action, SIGNAL(progressChanged(double, double)), this, SIGNAL(moveProgressChanged(double,double)) ); connect( action, SIGNAL(currentSubActionChanged(int)), this, SLOT(onMoveStepChanged(int)) ); }
bool AMActionHistoryModel3::logUncompletedAction(const AMAction3 *uncompletedAction, AMDatabase *database, int parentLogId){ if(uncompletedAction && !uncompletedAction->inFinalState()){ if(database == AMDatabase::database("scanActions") && AMActionRunner3::scanActionRunner()->cachedLogCount() > 200){ database->commitTransaction(); AMActionRunner3::scanActionRunner()->resetCachedLogCount(); } if(database == AMDatabase::database("scanActions")){ if(!database->transactionInProgress()) database->startTransaction(); AMActionRunner3::scanActionRunner()->incrementCachedLogCount(); } /* AMActionLog3 actionLog(uncompletedAction); actionLog.setParentId(parentLogId); bool success = actionLog.storeToDb(database); */ AMActionLog3 *actionLog = new AMActionLog3(uncompletedAction); infosToLogsForUncompletedActions_.insert(uncompletedAction->info(), actionLog); actionLog->setParentId(parentLogId); bool success = actionLog->storeToDb(database); const AMListAction3 *listAction = qobject_cast<const AMListAction3*>(uncompletedAction); if(success && listAction){ AMListAction3 *modifyListAction = const_cast<AMListAction3*>(listAction); modifyListAction->setLogActionId(actionLog->id()); } AMActionLogItem3* item = new AMActionLogItem3(*actionLog); emit modelAboutToBeRefreshed(); /// \todo Ordering... This may end up at the wrong spot until a full refresh is done. Most of the time, any actions added will be the most recent ones, however that is not guaranteed. appendItem(item); visibleActionsCount_++; emit modelRefreshed(); return success; } return false; }
void AMEmptyListScanOptimizer::optimizeImplementation(AMAction3 *scanActionTree){ AMListAction3 *templateListAction = new AMListAction3(new AMListActionInfo3("Fake List", "Fake List")); QList<AMAction3*> allListsAsActions = AMScanActionTreeSupport::findActionsOfType(scanActionTree, templateListAction); QList<AMListAction3*> allLists; AMListAction3 *tempListAction; for(int x = 0; x < allListsAsActions.count(); x++){ tempListAction = qobject_cast<AMListAction3*>(allListsAsActions.at(x)); if(tempListAction) allLists.append(tempListAction); } for(int x = 0; x < allLists.count(); x++){ if(allLists.at(x)->subActionCount() == 0){ AMListAction3 *castParentToList = qobject_cast<AMListAction3*>(allLists.at(x)->parentAction()); if(castParentToList) castParentToList->deleteSubAction(castParentToList->indexOfSubAction(allLists.at(x))); } } templateListAction->deleteLater(); }
AMAction3* BioXASZebraTimeSeconds::createMoveAction(double setpointS) { AMAction3 *result = 0; double timeValueSetpoint = -1; double timeUnitsSetpoint = -1; // Resolve the given setpoint in seconds to other time values and units. double setpointMS = convertTimeValue(setpointS, Seconds, MSeconds); double setpointDS = convertTimeValue(setpointS, Seconds, DSeconds); // Starting with finest resolution, find the first valid setpoint. if (validTimeValue(setpointMS)) { timeValueSetpoint = setpointMS; timeUnitsSetpoint = MSeconds; } else if (validTimeValue(setpointS)) { timeValueSetpoint = setpointS; timeUnitsSetpoint = Seconds; } else if (validTimeValue(setpointDS)) { timeValueSetpoint = setpointDS; timeUnitsSetpoint = DSeconds; } // If the time value and units setpoints are valid, create and return valid action. if (validTimeValue(timeValueSetpoint) && validTimeUnits(timeUnitsSetpoint)) { AMListAction3 *moveAction = new AMListAction3(new AMListActionInfo3(QString("Moving %1").arg(name()), QString("Moving %1").arg(name())), AMListAction3::Sequential); moveAction->addSubAction(AMActionSupport::buildControlMoveAction(timeUnits_, timeUnitsSetpoint)); moveAction->addSubAction(AMActionSupport::buildControlMoveAction(timeValue_, timeValueSetpoint)); result = moveAction; } return result; }
AMAction3* BioXASMirrorYawControl::createMoveAction(double setpoint) { AMAction3 *result = 0; if (isConnected()) { AMListAction3 *move = new AMListAction3(new AMListActionInfo3(name()+" move", name()+" move"), AMListAction3::Parallel); double lateral = calculateLateral(upstreamLength_, downstreamLength_, stripeSelect_->value(), yaw_->value()); double yawDestination = calculateYawPosition(setpoint, upstreamLength_, downstreamLength_); move->addSubAction(AMActionSupport::buildControlMoveAction(yaw_, yawDestination)); // The lateral control depends on the yaw and so will appear to move as a consequence of yaw motion. We want to try and correct for this with the following action. double lateralDestination = calculateLateralPosition(lateral, upstreamLength_, downstreamLength_, setpoint); move->addSubAction(AMActionSupport::buildControlMoveAction(stripeSelect_, lateralDestination)); result = move; } return result; }
void AMSingleElementListOptimizer::optimizeImplementation(AMAction3 *scanActionTree){ AMListAction3 *templateListAction = new AMListAction3(new AMListActionInfo3("Fake List", "Fake List")); QList<AMAction3*> allListsAsActions = AMScanActionTreeSupport::findActionsOfType(scanActionTree, templateListAction); QList<AMListAction3*> allLists; AMListAction3 *tempListAction; for(int x = 0; x < allListsAsActions.count(); x++){ tempListAction = qobject_cast<AMListAction3*>(allListsAsActions.at(x)); if(tempListAction) allLists.append(tempListAction); } for(int x = 0; x < allLists.count(); x++){ if(allLists.at(x)->subActionCount() == 1){ AMListAction3 *castParentToList = qobject_cast<AMListAction3*>(allLists.at(x)->parentAction()); if(castParentToList){ int indexOfThisList = castParentToList->indexOfSubAction(allLists.at(x)); castParentToList->insertSubAction(allLists.at(x)->takeSubActionAt(0), indexOfThisList); castParentToList->deleteSubAction(castParentToList->indexOfSubAction(allLists.at(x))); } } } }
QList<AMAction3*> findActionsWhereNameContains(AMAction3 *rootAction, const QString &searchString){ QList<AMAction3*> retVal; AMListAction3 *castToListAction = qobject_cast<AMListAction3*>(rootAction); if(castToListAction){ for(int x = 0; x < castToListAction->subActionCount(); x++){ AMListAction3 *subActionToListAction = qobject_cast<AMListAction3*>(castToListAction->subActionAt(x)); if(subActionToListAction && subActionToListAction->info()->shortDescription().contains(searchString)) retVal.append(subActionToListAction); retVal.append((findActionsNamed(castToListAction->subActionAt(x), searchString))); } } return retVal; }
QList<AMAction3*> findActionsNamed(AMAction3 *rootAction, const QString &name){ QList<AMAction3*> retVal; AMListAction3 *castToListAction = qobject_cast<AMListAction3*>(rootAction); if(castToListAction){ for(int x = 0; x < castToListAction->subActionCount(); x++){ AMListAction3 *subActionToListAction = qobject_cast<AMListAction3*>(castToListAction->subActionAt(x)); if(subActionToListAction && subActionToListAction->info()->shortDescription() == name) retVal.append(subActionToListAction); retVal.append((findActionsNamed(castToListAction->subActionAt(x), name))); } } return retVal; }
AMAction3* SXRMBBeamline::createBeamOffActions() const { if(!isConnected() || PSH1406B1002Shutter_->isClosed()) return 0; AMListAction3 *beamOffControlActionsList = new AMListAction3(new AMListActionInfo3("SXRMB Beam off action list", "SXRMB Beam off "), AMListAction3::Sequential); beamOffControlActionsList->addSubAction(AMActionSupport::buildControlMoveAction(PSH1406B1002Shutter_, 0)); AMListAction3 *beamOffControlWaitActionsList = new AMListAction3(new AMListActionInfo3("SXRMB Beam off Wait action list", "SXRMB Beam off"), AMListAction3::Parallel); beamOffControlWaitActionsList->addSubAction(AMActionSupport::buildControlWaitAction(PSH1406B1002Shutter_, 0)); AMListAction3 *beamOffActionsList = new AMListAction3(new AMListActionInfo3("SXRMB Beam Off", "SXRMB Beam Off"), AMListAction3::Parallel); beamOffActionsList->addSubAction(beamOffControlActionsList); beamOffActionsList->addSubAction(beamOffControlWaitActionsList); return beamOffActionsList; }
AMAction3* AMScanActionControllerScanAssembler::generateActionTreeForStepAxisRegion(AMControl *axisControl, const AMScanAxisRegion &stepScanAxisRegion, bool isFinalRegion){ AMListAction3 *regionList = new AMListAction3(new AMListActionInfo3(QString("Region on %1").arg(axisControl->name()), QString("Region from %1 to %2 by %3 on %4").arg(stepScanAxisRegion.regionStart().toString()).arg(stepScanAxisRegion.regionEnd().toString()).arg(stepScanAxisRegion.regionStep().toString()).arg(axisControl->name())), AMListAction3::Sequential); AMControlInfo regionStartSetpoint = axisControl->toInfo(); regionStartSetpoint.setValue(stepScanAxisRegion.regionStart()); AMControlMoveAction3 *regionStart = new AMControlMoveAction3(new AMControlMoveActionInfo3(regionStartSetpoint), axisControl); regionStart->setGenerateScanActionMessage(true); AMListAction3 *detectorSetDwellList = new AMListAction3(new AMListActionInfo3(QString("Set All Detectors Dwell Times"), QString("Set %1 Detectors").arg(detectors_->count())), AMListAction3::Parallel); AMAction3 *detectorSetDwellAction; for(int x = 0; x < detectors_->count(); x++){ detectorSetDwellAction = detectors_->at(x)->createSetAcquisitionTimeAction(stepScanAxisRegion.regionTime()); if(detectorSetDwellAction) detectorSetDwellList->addSubAction(detectorSetDwellAction); } // generate axis loop for region int loopIterations = ceil(( ((double)stepScanAxisRegion.regionEnd()) - ((double)stepScanAxisRegion.regionStart()) )/ ((double)stepScanAxisRegion.regionStep()) ); AMLoopAction3 *axisLoop = new AMLoopAction3(new AMLoopActionInfo3(loopIterations, QString("Loop %1").arg(axisControl->name()), QString("Looping from %1 to %2 by %3 on %4").arg(stepScanAxisRegion.regionStart().toString()).arg(stepScanAxisRegion.regionEnd().toString()).arg(stepScanAxisRegion.regionStep().toString()).arg(axisControl->name()))); axisLoop->setGenerateScanActionMessage(true); AMListAction3 *nextLevelHolderAction = new AMListAction3(new AMListActionInfo3("Holder Action for the Next Sublevel", "Holder Action for the Next Sublevel")); AMControlInfo controlLoopMoveInfoSetpoint = axisControl->toInfo(); controlLoopMoveInfoSetpoint.setValue(stepScanAxisRegion.regionStep()); AMControlMoveActionInfo3 *controlLoopMoveInfo = new AMControlMoveActionInfo3(controlLoopMoveInfoSetpoint); controlLoopMoveInfo->setIsRelativeMove(true); controlLoopMoveInfo->setIsRelativeFromSetpoint(true); AMControlMoveAction3 *controlLoopMove = new AMControlMoveAction3(controlLoopMoveInfo, axisControl); controlLoopMove->setGenerateScanActionMessage(true); axisLoop->addSubAction(nextLevelHolderAction); axisLoop->addSubAction(controlLoopMove); regionList->addSubAction(regionStart); regionList->addSubAction(detectorSetDwellList); regionList->addSubAction(axisLoop); if(isFinalRegion){ AMListAction3 *nextLevelFinalHolderAction = new AMListAction3(new AMListActionInfo3("Holder Action for the Next Sublevel", "Holder Action for the Next Sublevel")); regionList->addSubAction(nextLevelFinalHolderAction); } return regionList; }
AMAction3 * SGMHexapodTransformedAxis::createSetParametersActions(double startPoint, double endPoint, double deltaTime) { AMListAction3* action = 0; lastStartPoint_ = startPoint; lastEndPoint_ = endPoint; lastDeltaTime_ = deltaTime; qDebug() << "Checking on some axis stuff for SGMHexapodTransformedAxis::createSetParameterActions for axis " << axis_; if(globalXAxis_) qDebug() << "Have globalXAxis_"; if(globalYAxis_) qDebug() << "Have globalYAxis_"; if(globalZAxis_) qDebug() << "Have globalZAxis_"; if(trajectoryStartControl_) qDebug() << "Have trajectoryStartControl_"; if(globalXAxis_ && globalYAxis_ && globalZAxis_ && trajectoryStartControl_) { // Setting the start position action = new AMListAction3(new AMListActionInfo3("Setting hexapod movement parameters", "Setting hexapod movement parameters"), AMListAction3::Sequential); // Grab the current global positions: QVector3D currentGlobalSetpoints(globalXAxis_->setpoint(), globalYAxis_->setpoint(), globalZAxis_->setpoint()); // Transform it to our system: QVector3D primeSetpoints = globalAxisToPrime(currentGlobalSetpoints); // Set the value in terms of our system based on the axis we are: switch(axis_) { case XAxis: primeSetpoints.setX(startPoint); break; case YAxis: primeSetpoints.setY(startPoint); break; case ZAxis: primeSetpoints.setZ(startPoint); } // Transform back the the global system: QVector3D newGlobalStartSetpoints = primeAxisToGlobal(primeSetpoints); // Create the required move actions in the global system: AMListAction3* startMoveActions = new AMListAction3(new AMListActionInfo3("Moving parameter controls for start", "Moving parameter controls for end"), AMListAction3::Parallel); startMoveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalXAxis_, newGlobalStartSetpoints.x())); startMoveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalYAxis_, newGlobalStartSetpoints.y())); startMoveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalZAxis_, newGlobalStartSetpoints.z())); action->addSubAction(startMoveActions); // Wait for the parameters to take AMListAction3* startWaitActions = new AMListAction3(new AMListActionInfo3("Waiting for parameter controls for start", "Waiting for parameter controls for start"), AMListAction3::Parallel); startWaitActions->addSubAction(AMActionSupport::buildControlWaitAction(globalXAxis_, newGlobalStartSetpoints.x(), 2, AMControlWaitActionInfo::MatchWithinTolerance)); startWaitActions->addSubAction(AMActionSupport::buildControlWaitAction(globalYAxis_, newGlobalStartSetpoints.y(), 2, AMControlWaitActionInfo::MatchWithinTolerance)); startWaitActions->addSubAction(AMActionSupport::buildControlWaitAction(globalZAxis_, newGlobalStartSetpoints.z(), 2, AMControlWaitActionInfo::MatchWithinTolerance)); action->addSubAction(startWaitActions); // Trigger the movement AMAction3* trajectoryStartAction = AMActionSupport::buildControlMoveAction(trajectoryStartControl_, 1); action->addSubAction(trajectoryStartAction); action->addSubAction(AMActionSupport::buildControlWaitAction(trajectoryStartControl_, 0, 100, AMControlWaitActionInfo::MatchWithinTolerance)); // Wait for the move to start point to complete action->addSubAction(AMActionSupport::buildControlWaitAction(this, startPoint, 60, AMControlWaitActionInfo::MatchWithinTolerance)); action->addSubAction(AMActionSupport::buildControlWaitAction(globalXAxisStatus_, 0, 100, AMControlWaitActionInfo::MatchWithinTolerance)); action->addSubAction(AMActionSupport::buildControlWaitAction(globalYAxisStatus_, 0, 100, AMControlWaitActionInfo::MatchWithinTolerance)); action->addSubAction(AMActionSupport::buildControlWaitAction(globalZAxisStatus_, 0, 100, AMControlWaitActionInfo::MatchWithinTolerance)); // Setting the end position switch(axis_) { case XAxis: primeSetpoints.setX(endPoint); break; case YAxis: primeSetpoints.setY(endPoint); break; case ZAxis: primeSetpoints.setZ(endPoint); } // Transform the end setpoints to the global system: QVector3D newGlobalEndSetpoints = primeAxisToGlobal(primeSetpoints); // Create the required move actions in the global system: AMListAction3* endMoveActions = new AMListAction3(new AMListActionInfo3("Moving parameter controls for end", "Moving parameter controls for end"), AMListAction3::Parallel); endMoveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalXAxis_, newGlobalEndSetpoints.x())); endMoveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalYAxis_, newGlobalEndSetpoints.y())); endMoveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalZAxis_, newGlobalEndSetpoints.z())); action->addSubAction(endMoveActions); // Wait for the parameters to take AMListAction3* endWaitActions = new AMListAction3(new AMListActionInfo3("Waiting for parameter controls for end", "Waiting for parameter controls for end"), AMListAction3::Parallel); endWaitActions->addSubAction(AMActionSupport::buildControlWaitAction(globalXAxis_, newGlobalEndSetpoints.x(), 2, AMControlWaitActionInfo::MatchWithinTolerance)); endWaitActions->addSubAction(AMActionSupport::buildControlWaitAction(globalYAxis_, newGlobalEndSetpoints.y(), 2, AMControlWaitActionInfo::MatchWithinTolerance)); endWaitActions->addSubAction(AMActionSupport::buildControlWaitAction(globalZAxis_, newGlobalEndSetpoints.z(), 2, AMControlWaitActionInfo::MatchWithinTolerance)); action->addSubAction(endWaitActions); // Save the previous velocity before we alter it lastSavedVelocity_ = systemVelocity_->value(); // Setting the system velocity double velocity = qAbs(endPoint - startPoint) / deltaTime; action->addSubAction(AMActionSupport::buildControlMoveAction(systemVelocity_, velocity)); action->addSubAction(AMActionSupport::buildControlWaitAction(systemVelocity_, velocity, 2, AMControlWaitActionInfo::MatchWithinTolerance)); // Setting up the data recorder double requiredRate = HEXAPOD_RECORDER_POINTS_PER_MOVE / deltaTime; action->addSubAction(AMActionSupport::buildControlMoveAction(dataRecorderRate_, requiredRate)); action->addSubAction(AMActionSupport::buildControlWaitAction(dataRecorderRate_, requiredRate, 2.0, AMControlWaitActionInfo::MatchWithinTolerance)); action->addSubAction(AMActionSupport::buildControlMoveAction(dataRecorderStatus_, 1)); action->addSubAction(AMActionSupport::buildControlWaitAction(dataRecorderStatus_, 1, 2.0, AMControlWaitActionInfo::MatchWithinTolerance)); } return action; }
AMAction3 * SGMHexapodTransformedAxis::createMoveAction(double setpoint) { AMListAction3* action = 0; if(globalXAxis_ && globalYAxis_ && globalZAxis_ && trajectoryStartControl_) { action = new AMListAction3(new AMListActionInfo3(QString("Moving %1").arg(name()), QString("Moving %1 from %2 to %3") .arg(value()).arg(setpoint)), AMListAction3::Sequential); AMListAction3* moveActions = new AMListAction3(new AMListActionInfo3(QString("Moving %1").arg(name()), QString("Moving %1").arg(name())), AMListAction3::Parallel); // Grab the current global positions: QVector3D currentGlobalSetpoints(globalXAxis_->setpoint(), globalYAxis_->setpoint(), globalZAxis_->setpoint()); // Transform it to our system: QVector3D primeSetpoint = globalAxisToPrime(currentGlobalSetpoints); // Set the value in terms of our system based on the axis we are: switch(axis_) { case XAxis: primeSetpoint.setX(setpoint); break; case YAxis: primeSetpoint.setY(setpoint); break; case ZAxis: primeSetpoint.setZ(setpoint); } // Transform back the the global system: QVector3D newGlobalSetpoints = primeAxisToGlobal(primeSetpoint); // Create the required move actions in the global system: moveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalXAxis_, newGlobalSetpoints.x())); moveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalYAxis_, newGlobalSetpoints.y())); moveActions->addSubAction(AMActionSupport::buildControlMoveAction(globalZAxis_, newGlobalSetpoints.z())); action->addSubAction(moveActions); AMAction3* trajectoryStartAction = AMActionSupport::buildControlMoveAction(trajectoryStartControl_, 1); action->addSubAction(trajectoryStartAction); AMAction3* waitAction = AMActionSupport::buildControlWaitAction(this, setpoint, 100, AMControlWaitActionInfo::MatchWithinTolerance); AMAction3* waitXAction = AMActionSupport::buildControlWaitAction(globalXAxisStatus_, 0, 100, AMControlWaitActionInfo::MatchWithinTolerance); AMAction3* waitYAction = AMActionSupport::buildControlWaitAction(globalYAxisStatus_, 0, 100, AMControlWaitActionInfo::MatchWithinTolerance); AMAction3* waitZAction = AMActionSupport::buildControlWaitAction(globalZAxisStatus_, 0, 100, AMControlWaitActionInfo::MatchWithinTolerance); action->addSubAction(waitAction); action->addSubAction(waitXAction); action->addSubAction(waitYAction); action->addSubAction(waitZAction); } return action; }
AMAction3 * SGMHexapodTransformedAxis::createWaitForCompletionActions() { AMListAction3* waitActions = new AMListAction3(new AMListActionInfo3("Waiting for coordinated move", "Waiting for coordinated move"), AMListAction3::Sequential); waitActions->addSubAction(AMActionSupport::buildControlWaitAction(trajectoryStartControl_, 0, lastDeltaTime_+1.5, AMControlWaitActionInfo::MatchWithinTolerance)); AMListAction3 *recorderActions = new AMListAction3(new AMListActionInfo3("Waiting for data recorders to monitor", "Waiting for data recorders to monitor"), AMListAction3::Parallel); // Read action for the detector emulators for data recorders. These detectors are set to AMDetectorDefinitions::WaitRead, which will mean they will only read once they monitor. AMAction3 *hexapodXRecorderDetectorReadAction = AMBeamline::bl()->exposedDetectorByName("HexapodXRecorder")->createReadAction(); hexapodXRecorderDetectorReadAction->setGenerateScanActionMessage(true); recorderActions->addSubAction(hexapodXRecorderDetectorReadAction); AMAction3 *hexapodYRecorderDetectorReadAction = AMBeamline::bl()->exposedDetectorByName("HexapodYRecorder")->createReadAction(); hexapodYRecorderDetectorReadAction->setGenerateScanActionMessage(true); recorderActions->addSubAction(hexapodYRecorderDetectorReadAction); AMAction3 *hexapodZRecorderDetectorReadAction = AMBeamline::bl()->exposedDetectorByName("HexapodZRecorder")->createReadAction(); hexapodZRecorderDetectorReadAction->setGenerateScanActionMessage(true); recorderActions->addSubAction(hexapodZRecorderDetectorReadAction); AMAction3 *hexapodTimeRecorderDetectorReadAction = AMBeamline::bl()->exposedDetectorByName("HexapodTimeRecorder")->createReadAction(); hexapodTimeRecorderDetectorReadAction->setGenerateScanActionMessage(true); recorderActions->addSubAction(hexapodTimeRecorderDetectorReadAction); AMListAction3 *positionWaitActions = new AMListAction3(new AMListActionInfo3("Waiting for hexapod positions", "Waiting for hexapod positions"), AMListAction3::Parallel); // We need to add 1.5 seconds to the delta time, as the data recorder is slow AMAction3* positionWaitAction = AMActionSupport::buildControlWaitAction(this, lastEndPoint_, lastDeltaTime_+1.5, AMControlWaitActionInfo::MatchWithinTolerance); /* AMAction3* statusXWaitAction = AMActionSupport::buildControlWaitAction(globalXAxisStatus_, 0, lastDeltaTime_+1.5, AMControlWaitActionInfo::MatchWithinTolerance); AMAction3* statusYWaitAction = AMActionSupport::buildControlWaitAction(globalYAxisStatus_, 0, lastDeltaTime_+1.5, AMControlWaitActionInfo::MatchWithinTolerance); AMAction3* statusZWaitAction = AMActionSupport::buildControlWaitAction(globalZAxisStatus_, 0, lastDeltaTime_+1.5, AMControlWaitActionInfo::MatchWithinTolerance); */ positionWaitActions->addSubAction(positionWaitAction); /* positionWaitActions->addSubAction(statusXWaitAction); positionWaitActions->addSubAction(statusYWaitAction); positionWaitActions->addSubAction(statusZWaitAction); */ /* waitActions->addSubAction(positionWaitAction); waitActions->addSubAction(statusXWaitAction); waitActions->addSubAction(statusYWaitAction); waitActions->addSubAction(statusZWaitAction); */ AMListAction3 *centralParallelActions = new AMListAction3(new AMListActionInfo3("Parallel List of Recorder and Position Waits", "Parallel List of Recorder and Position Waits"), AMListAction3::Parallel); centralParallelActions->addSubAction(recorderActions); centralParallelActions->addSubAction(positionWaitActions); waitActions->addSubAction(centralParallelActions); // Return the data recorder to the off state (we need a clean up actions function adding to the AMControl API) waitActions->addSubAction(AMActionSupport::buildControlMoveAction(dataRecorderStatus_, 0)); waitActions->addSubAction(AMActionSupport::buildControlWaitAction(dataRecorderStatus_, 0, 2.0, AMControlWaitActionInfo::MatchWithinTolerance)); waitActions->addSubAction(AMActionSupport::buildControlMoveAction(systemVelocity_, lastSavedVelocity_)); waitActions->addSubAction(AMActionSupport::buildControlWaitAction(systemVelocity_, lastSavedVelocity_, 2.0, AMControlWaitActionInfo::MatchWithinTolerance)); return waitActions; }