DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Stage1D.cpp
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
3 #include "stdafx.h"
4 #include "moc_Stage1D.cpp"
5 #include "Stage1D.h"
6 
7 namespace DynExpModule
8 {
9  Stage1DWidget::Stage1DWidget(Stage1D& Owner, QModuleWidget* parent) : QModuleWidget(Owner, parent)
10  {
11  ui.setupUi(this);
12  ui.SBPosition->blockSignals(true);
13 
14  // For shortcuts
15  this->addAction(ui.action_Stop_current_action);
16  }
17 
19  {
20  Init();
21  }
22 
24  {
25  Velocity = 0;
26  Position = 0;
27  IsUsingSIUnits = true;
28  IsMoving = false;
29  HasFailed = false;
30  LabelsUpdated = false;
31  }
32 
34  {
35  try
36  {
37  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance.ModuleDataGetter());
38  auto StageData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::PositionerStage>(ModuleData->PositionerStage->GetInstrumentData());
39 
40  ModuleData->Velocity = StageData->GetVelocity() * ModuleData->PositionerStage->GetStepNanoMeterRatio();
41  ModuleData->Position = StageData->GetCurrentPosition() * ModuleData->PositionerStage->GetStepNanoMeterRatio();
42  ModuleData->IsUsingSIUnits = ModuleData->PositionerStage->IsUsingSIUnits();
43  ModuleData->IsMoving = StageData->IsMoving();
44  ModuleData->HasFailed = StageData->HasFailed();
45 
47  } // ModuleData and StageData unlocked here.
48  catch (const Util::TimeoutException& e)
49  {
50  if (NumFailedUpdateAttempts++ >= 3)
51  Instance.GetOwner().SetWarning(e);
52  }
53 
55  }
56 
58  {
60  }
61 
62  std::unique_ptr<DynExp::QModuleWidget> Stage1D::MakeUIWidget()
63  {
64  auto Widget = std::make_unique<Stage1DWidget>(*this);
65 
66  Connect(Widget->ui.action_Stop_current_action, &QAction::triggered, this, &Stage1D::OnStopClicked);
67  Connect(Widget->ui.ButtonReference, &QPushButton::clicked, this, &Stage1D::OnFindReferenceClicked);
68  Connect(Widget->ui.ButtonSetHome, &QPushButton::clicked, this, &Stage1D::OnSetHomeClicked);
69  Connect(Widget->ui.ButtonCalibrate, &QPushButton::clicked, this, &Stage1D::OnCalibrateClicked);
70  Connect(Widget->ui.ButtonFirst, &QPushButton::clicked, this, &Stage1D::OnMoveFirstClicked);
71  Connect(Widget->ui.ButtonLast, &QPushButton::clicked, this, &Stage1D::OnMoveLastClicked);
72  Connect(Widget->ui.ButtonLeft, &QPushButton::clicked, this, &Stage1D::OnMoveLeftClicked);
73  Connect(Widget->ui.ButtonRight, &QPushButton::clicked, this, &Stage1D::OnMoveRightClicked);
74  Connect(Widget->ui.ButtonHome, &QPushButton::clicked, this, &Stage1D::OnMoveHomeClicked);
75  Connect(Widget->ui.ButtonStop, &QPushButton::clicked, this, &Stage1D::OnStopClicked);
76  Connect(Widget->ui.SBVelocity, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &Stage1D::OnVelocityValueChanged);
77  Connect(Widget->ui.SBPosition, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &Stage1D::OnPositionValueChanged);
78 
79  return Widget;
80  }
81 
82  void Stage1D::UpdateUIChild(const ModuleBase::ModuleDataGetterType& ModuleDataGetter)
83  {
84  auto Widget = GetWidget<Stage1DWidget>();
85  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(ModuleDataGetter());
86 
87  if (!Widget->ui.SBVelocity->hasFocus())
88  {
89  const QSignalBlocker Blocker(Widget->ui.SBVelocity);
90  Widget->ui.SBVelocity->setValue(ModuleData->Velocity);
91  }
92  if (!Widget->ui.SBPosition->hasFocus())
93  {
94  const QSignalBlocker Blocker(Widget->ui.SBPosition);
95  Widget->ui.SBPosition->setValue(ModuleData->Position);
96  }
97 
98  Widget->ui.CBMoving->setChecked(ModuleData->IsMoving);
99  Widget->ui.CBErrorState->setChecked(ModuleData->HasFailed);
100 
101  if (!ModuleData->LabelsUpdated)
102  {
103  ModuleData->LabelsUpdated = true;
104  Widget->ui.LVelocity->setText("Velocity (" + QString(ModuleData->IsUsingSIUnits ? "nm/s" : "steps/s") + ")");
105  Widget->ui.SBVelocity->setMaximum(ModuleData->PositionerStage->GetMaxVelocity());
106  Widget->ui.SBVelocity->setMinimum(ModuleData->PositionerStage->GetMinVelocity());
107  Widget->ui.SBVelocity->setDecimals(0);
108  Widget->ui.SBVelocity->setValue(ModuleData->PositionerStage->GetDefaultVelocity());
109  Widget->ui.LPosition->setText("Position (" + QString(ModuleData->IsUsingSIUnits ? "nm" : "steps") + ")");
110  Widget->ui.SBPosition->setMaximum(ModuleData->PositionerStage->GetMaxPosition());
111  Widget->ui.SBPosition->setMinimum(ModuleData->PositionerStage->GetMinPosition());
112  Widget->ui.SBPosition->setDecimals(0);
113 
114  // Now unblock signals (if they weren't blocked initially, stage would move to 0)
115  Widget->ui.SBPosition->blockSignals(false);
116  }
117  }
118 
120  {
121  auto ModuleParams = DynExp::dynamic_Params_cast<Stage1D>(Instance->ParamsGetter());
122  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
123 
124  Instance->LockObject(ModuleParams->PositionerStage, ModuleData->PositionerStage);
125  }
126 
128  {
129  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
130 
131  Instance->UnlockObject(ModuleData->PositionerStage);
132  }
133 
135  {
136  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
137  ModuleData->PositionerStage->Reference();
138  }
139 
141  {
142  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
143  ModuleData->PositionerStage->SetHome();
144  }
145 
147  {
148  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
149  ModuleData->PositionerStage->Calibrate();
150  }
151 
153  {
154  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
155  ModuleData->PositionerStage->MoveAbsolute(ModuleData->PositionerStage->GetMinPosition());
156  }
157 
159  {
160  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
161  ModuleData->PositionerStage->MoveAbsolute(ModuleData->PositionerStage->GetMaxPosition());
162  }
163 
165  {
166  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
167  ModuleData->PositionerStage->MoveRelative(-ModuleData->Velocity / ModuleData->PositionerStage->GetStepNanoMeterRatio() * .1);
168  }
169 
171  {
172  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
173  ModuleData->PositionerStage->MoveRelative(ModuleData->Velocity / ModuleData->PositionerStage->GetStepNanoMeterRatio() * .1);
174  }
175 
177  {
178  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
179  ModuleData->PositionerStage->MoveToHome();
180  }
181 
182  void Stage1D::OnStopClicked(DynExp::ModuleInstance* Instance, bool) const
183  {
184  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
185  ModuleData->PositionerStage->StopMotion();
186  }
187 
188  void Stage1D::OnVelocityValueChanged(DynExp::ModuleInstance* Instance, const double Value) const
189  {
190  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
191  ModuleData->PositionerStage->SetVelocity(Value / ModuleData->PositionerStage->GetStepNanoMeterRatio());
192  }
193 
194  void Stage1D::OnPositionValueChanged(DynExp::ModuleInstance* Instance, const double Value) const
195  {
196  auto ModuleData = DynExp::dynamic_ModuleData_cast<Stage1D>(Instance->ModuleDataGetter());
197  ModuleData->PositionerStage->MoveAbsolute(Value / ModuleData->PositionerStage->GetStepNanoMeterRatio());
198  }
199 }
Implementation of a module to control a 1D positioner stage.
void ResetImpl(dispatch_tag< QModuleDataBase >) override final
Definition: Stage1D.cpp:18
Stage1DWidget(Stage1D &Owner, QModuleWidget *parent=nullptr)
Definition: Stage1D.cpp:9
void UpdateUIChild(const ModuleBase::ModuleDataGetterType &ModuleDataGetter) override final
Definition: Stage1D.cpp:82
void OnSetHomeClicked(DynExp::ModuleInstance *Instance, bool) const
Definition: Stage1D.cpp:140
void ResetImpl(dispatch_tag< QModuleBase >) override final
Definition: Stage1D.cpp:57
void OnMoveFirstClicked(DynExp::ModuleInstance *Instance, bool) const
Definition: Stage1D.cpp:152
std::unique_ptr< DynExp::QModuleWidget > MakeUIWidget() override final
Used by InitUI() as a factory function for the module's user interface widget. Create the widget here...
Definition: Stage1D.cpp:62
void OnVelocityValueChanged(DynExp::ModuleInstance *Instance, const double Value) const
Definition: Stage1D.cpp:188
void OnMoveLastClicked(DynExp::ModuleInstance *Instance, bool) const
Definition: Stage1D.cpp:158
void OnCalibrateClicked(DynExp::ModuleInstance *Instance, bool) const
Definition: Stage1D.cpp:146
void OnFindReferenceClicked(DynExp::ModuleInstance *Instance, bool) const
Definition: Stage1D.cpp:134
void OnStopClicked(DynExp::ModuleInstance *Instance, bool) const
Definition: Stage1D.cpp:182
void OnMoveRightClicked(DynExp::ModuleInstance *Instance, bool) const
Definition: Stage1D.cpp:170
void OnInit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread starts. Override it to lock instruments this m...
Definition: Stage1D.cpp:119
void OnExit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread terminates (not due to an exception,...
Definition: Stage1D.cpp:127
Util::DynExpErrorCodes::DynExpErrorCodes ModuleMainLoop(DynExp::ModuleInstance &Instance) override final
Module main loop. The function is executed periodically by the module thread. Also refer to GetMainLo...
Definition: Stage1D.cpp:33
void OnMoveLeftClicked(DynExp::ModuleInstance *Instance, bool) const
Definition: Stage1D.cpp:164
void OnPositionValueChanged(DynExp::ModuleInstance *Instance, const double Value) const
Definition: Stage1D.cpp:194
size_t NumFailedUpdateAttempts
Definition: Stage1D.h:124
void OnMoveHomeClicked(DynExp::ModuleInstance *Instance, bool) const
Definition: Stage1D.cpp:176
const std::unique_ptr< ModuleDataType > ModuleData
Module data belonging to this ModuleBase instance.
Definition: Module.h:743
Refer to ParamsBase::dispatch_tag.
Definition: Module.h:189
Defines data for a thread belonging to a ModuleBase instance. Refer to RunnableInstance.
Definition: Module.h:793
const ModuleBase::ModuleDataGetterType ModuleDataGetter
Getter for module's data. Refer to ModuleBase::ModuleDataGetterType.
Definition: Module.h:825
Refer to ParamsBase::dispatch_tag.
Definition: Object.h:2018
QModuleWidget * Widget
User interface widget belonging to the module.
Definition: Module.h:1491
void Connect(SenderType *Sender, SignalType Signal, ReceiverType *Receiver, EventType Event)
Uses Qt's connect mechanism to connect a QObject's signal to a DynExp module's event....
Definition: Module.h:1500
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
Definition: Object.h:3671
void UnlockObject(LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer)
Unlocks an Object instance stored in the LinkedObjectWrapperContainer ObjectWrapperContainer....
Definition: Object.h:3570
void LockObject(const ParamsBase::Param< ObjectLink< ObjectT >> &LinkParam, LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer, std::chrono::milliseconds Timeout=ObjectLinkBase::LockObjectTimeoutDefault)
Locks an Object instance referenced by a parameter LinkParam of type ParamsBase::Param< ObjectLink< O...
Definition: Object.h:3554
const auto & GetOwner() const noexcept
Returns Owner.
Definition: Object.h:3524
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
Definition: Exception.h:261
DynExp's module namespace contains the implementation of DynExp modules which extend DynExp's core fu...
DynExpErrorCodes
DynExp's error codes
Definition: Exception.h:22
Accumulates include statements to provide a precompiled header.