Пример #1
0
bool REIXSSpectrometer::stop()
{
	if(!canStop())
		return false;

	if(moveInProgress()) {
		moveAction_->cancel();
		/// \todo Actually, have to flag that a stop has started, and also catch when the stop is finished... Motors will take a while to actually receive and decelerate.
		moveAction_->deleteLater();
		moveAction_ = 0;
		emit moveFailed(AMControl::WasStoppedFailure);
		AMErrorMon::report(AMErrorReport(this, AMErrorReport::Alert, AMControl::WasStoppedFailure, "Spectrometer Move Stopped."));
	}

	// just in case anything was moving from outside our instructions (ie: commanded from somewhere else in the building)
	spectrometerRotationDrive_->stop();
	detectorTranslation_->stop();
	detectorTiltDrive_->stop();
	endstationTranslation_->stop();
	// hexapod: cannot stop without wrecking init. Don't worry for now... just let it stop over time. Not necessary for it to be not-moving before we re-send it somewhere new.

	/// \todo Actually, have to flag that a stop has started, and also catch when the stop is finished... Motors will take a while to actually receive and decelerate.

	return true;
}
Пример #2
0
void BioXASZebraTimeSeconds::updateValue()
{
	if (canMeasure() && !moveInProgress()) {
		double newValue = convertTimeValue(timeValue_->value(), timeUnits_->value(), Seconds);
		setValue(newValue);
	}
}
Пример #3
0
// Start a move to the value setpoint:
AMControl::FailureExplanation CLSMDriveMotorControl::move(double Setpoint) {

    if(isMoving()) {
        if(!allowsMovesWhileMoving()) {
            AMErrorMon::debug(this, AMPVCONTROL_COULD_NOT_MOVE_WHILE_MOVING, QString("AMPVControl: Could not move %1 (%2) to %3, because the control is already moving.").arg(name()).arg(writePV_->pvName()).arg(setpoint_));
            return AlreadyMovingFailure;
        }

        if(!moveInProgress()) {
            // the control is already moving, but it's not one of our moves. In this situation, there is no way that we can start a move and be assured that we'll be notified when OUR move finishes.
            AMErrorMon::debug(this, AMPVCONTROL_COULD_NOT_MOVE_WHILE_MOVING_EXTERNAL, QString("AMPVControl: Could not move %1 (%2) to %3, because the control is already moving.").arg(name()).arg(writePV_->pvName()).arg(setpoint_));
            return AlreadyMovingFailure;
        }

        // Otherwise: This control supports mid-move updates, and we're already moving. We just need to update the setpoint and send it.
        setpoint_ = writeUnitConverter()->convertToRaw(Setpoint);
        writePV_->setValue(setpoint_);
        // since the settling phase is considered part of a move, it's OK to be here while settling... But for Acquaman purposes, this will be considered a single re-targetted move, even though the hardware will see two.  If we're settling, disable the settling timer, because we only want to respond to the end of the second move.
        if(settlingInProgress_) {
            settlingInProgress_ = false;
            settlingTimer_.stop();
        }
        emit moveReTargetted(); // re-targetted moves will emit moveReTargetted(), although no moveSucceeded()/moveFailed() will be issued for the initial move.
    }

    else {
        settlingInProgress_ = false;
        stopInProgress_ = false;
        moveInProgress_ = false;
        // Flag that "our" move started:
        startInProgress_ = true;

        // This is our new target:
        setpoint_ = writeUnitConverter()->convertToRaw(Setpoint);

        // Special case: "null move" should complete immediately. Use only if moveStartTolerance() is non-zero, and the move distance is within moveStartTolerance().
        if(moveStartTolerance() != 0 && fabs(setpoint()-value()) < moveStartTolerance()) {
            startInProgress_ = false;
            moveInProgress_ = true;
            emit moveStarted();
            moveInProgress_ = false;
            emit moveSucceeded();
        }
        // Normal move:
        else {
            // Issue the move command:
            writePV_->setValue(setpoint_);
            // start the timer to check if our move failed to start:
            moveStartTimer_.start(int(moveStartTimeout_*1000.0));
        }
    }

    return NoFailure;
}
Пример #4
0
AMControl::FailureExplanation REIXSSpectrometer::move(double setpoint)
{
	if(!isConnected()) {
		AMErrorMon::report(AMErrorReport(this, AMErrorReport::Alert, 2, "Can't move the spectrometer: some motor controls are not connected. Check that the IOCs are running and the network connections are good."));
		return NotConnectedFailure;
	}

	// can't start a move while moving
	if(moveInProgress() || isMoving()) {
		AMErrorMon::report(AMErrorReport(this, AMErrorReport::Alert, 2, "Can't move the spectrometer, because it's already moving.  Stop the spectrometer first before attempting another move."));
		return AlreadyMovingFailure;
	}

	specifiedEV_ = setpoint;
	currentFocusOffset_ = specifiedFocusOffset_;
	currentDetectorTiltOffset_ = specifiedDetectorTiltOffset_;

	if(currentGrating_ != specifiedGrating_) {
		emit gratingChanged(currentGrating_ = specifiedGrating_);
	}

	/// \todo limits? out of range?
	moveSetpoint_ = calibration_.computeSpectrometerPosition(specifiedGrating_, specifiedEV_, currentFocusOffset_, currentDetectorTiltOffset_);

	// build the move action (With sub-actions to run in parallel)
	moveAction_ = new AMListAction3(new AMListActionInfo3("spectrometer eV move", "spectrometer eV move"), AMListAction3::Parallel, this);
	// if we need to move the grating into position, add actions for that:
	if(!gratingInPosition()) {
		// make a sequential action for the grating moves
		AMListAction3* gratingAction = new AMListAction3(new AMListActionInfo3("grating move", "grating move"));	// sequential by default.
		// first, move Z to 0
		gratingAction->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->z(), 0));
		// then move U,V,W to 0
		AMListAction3* uvw0Action = new AMListAction3(new AMListActionInfo3("grating UVW move to 0"), AMListAction3::Parallel);
		uvw0Action->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->u(), 0));
		uvw0Action->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->v(), 0));
		uvw0Action->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->w(), 0));
		gratingAction->addSubAction(uvw0Action);
		// then move R,S,T into position (Can do simultaneously with parallel action)
		AMListAction3* rstAction = new AMListAction3(new AMListActionInfo3("grating RST move"), AMListAction3::Parallel);
		rstAction->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->r(), moveSetpoint_.controlNamed("hexapodR").value()));
		rstAction->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->s(), moveSetpoint_.controlNamed("hexapodS").value()));
		rstAction->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->t(), moveSetpoint_.controlNamed("hexapodT").value()));
		gratingAction->addSubAction(rstAction);
		// move U,V,W to actual position
		AMListAction3* uvwAction = new AMListAction3(new AMListActionInfo3("grating UVW move"), AMListAction3::Parallel);
		uvwAction->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->u(), moveSetpoint_.controlNamed("hexapodU").value()));
		uvwAction->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->v(), moveSetpoint_.controlNamed("hexapodV").value()));
		uvwAction->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->w(), moveSetpoint_.controlNamed("hexapodW").value()));
		gratingAction->addSubAction(uvwAction);
		// then move X,Y,Z into position (can do simultaneously with parallel action)
		AMListAction3* xyzAction = new AMListAction3(new AMListActionInfo3("grating XYZ move"), AMListAction3::Parallel);
		xyzAction->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->x(), moveSetpoint_.controlNamed("hexapodX").value()));
		xyzAction->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->y(), moveSetpoint_.controlNamed("hexapodY").value()));
		xyzAction->addSubAction(AMActionSupport::buildControlMoveAction(hexapod_->z(), moveSetpoint_.controlNamed("hexapodZ").value()));
		gratingAction->addSubAction(xyzAction);

		moveAction_->addSubAction(gratingAction);
	}
	// add Lift, Tilt, and Translation
	moveAction_->addSubAction(AMActionSupport::buildControlMoveAction(spectrometerRotationDrive_, moveSetpoint_.controlNamed("spectrometerRotationDrive").value()));
	moveAction_->addSubAction(AMActionSupport::buildControlMoveAction(detectorTiltDrive_, moveSetpoint_.controlNamed("detectorTiltDrive").value()));
	moveAction_->addSubAction(AMActionSupport::buildControlMoveAction(detectorTranslation_, moveSetpoint_.controlNamed("detectorTranslation").value()));
	// Disabled for now: moveAction_->addSubAction(new AMInternalControlMoveAction(endstationTranslation_, moveSetpoint_.controlNamed("endstationTranslation").value()))

	// Watch the move action: succeeded or failed (or cancelled)
	connect(moveAction_, SIGNAL(stateChanged(int,int)), this, SLOT(onMoveActionStateChanged(int,int)));
	emit moveStarted();
	moveAction_->start();
	return NoFailure;
}