DynExp
Highly flexible laboratory automation for dynamically changing experiments.
PI-C-862.cpp
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
3 #include "stdafx.h"
4 #include "PI-C-862.h"
5 
6 namespace DynExpInstr
7 {
9  {
10  {
11  auto InstrParams = DynExp::dynamic_Params_cast<PI_C_862>(Instance.ParamsGetter());
12  auto InstrData = DynExp::dynamic_InstrumentData_cast<PI_C_862>(Instance.InstrumentDataGetter());
13 
14  Instance.LockObject(InstrParams->HardwareAdapter, InstrData->HardwareAdapter);
15  InstrData->HardwareAdapter->Clear();
16 
17  // Reset and select controller.
18  *InstrData->HardwareAdapter << "RT";
19  *InstrData->HardwareAdapter << std::string(1, static_cast<char>(1)) + InstrParams->MercuryAddress.Get();
20 
21  // Ignore version and factory string and await startup.
22  InstrData->HardwareAdapter->WaitForLine(3, std::chrono::milliseconds(50));
23  } // InstrParams and InstrData unlocked here.
24 
26  }
27 
29  {
31 
32  auto InstrData = DynExp::dynamic_InstrumentData_cast<PI_C_862>(Instance.InstrumentDataGetter());
33 
34  try
35  {
36  // Abort motion.
37  *InstrData->HardwareAdapter << "AB";
38  }
39  catch (...)
40  {
41  // Swallow any exception which might arise from HardwareAdapter->operator<<() since a failure
42  // of this function is not considered a severe error.
43  }
44 
45  Instance.UnlockObject(InstrData->HardwareAdapter);
46  }
47 
49  {
50  try
51  {
52  auto InstrData = DynExp::dynamic_InstrumentData_cast<PI_C_862>(Instance.InstrumentDataGetter());
53  bool UpdateError = false;
54 
55  try
56  {
57  // Tell position
58  *InstrData->HardwareAdapter << "TP";
59  InstrData->SetCurrentPosition(Util::StrToT<PositionerStageData::PositionType>(
60  PI_C_862::AnswerToNumberString(InstrData->HardwareAdapter->WaitForLine(3), "P:")));
61 
62  // Tell programmed velocity
63  *InstrData->HardwareAdapter << "TY";
64  InstrData->SetVelocity(Util::StrToT<PositionerStageData::PositionType>(
65  PI_C_862::AnswerToNumberString(InstrData->HardwareAdapter->WaitForLine(3), "Y:")));
66 
67  // Tell status
68  *InstrData->HardwareAdapter << "TS";
69  std::stringstream StatusStream(PI_C_862::AnswerToNumberString(InstrData->HardwareAdapter->WaitForLine(3), "S:"));
70  StatusStream.exceptions(std::ofstream::failbit | std::ofstream::badbit);
71  StatusStream << std::hex;
72 
73  uint16_t Byte; // Since stringstream handles uint8_t as character...
74  StatusStream >> Byte; // Extract LM629 status
75  if (Byte > 0xFF)
76  throw Util::InvalidDataException("Received an unexpected LM629 status.");
77  InstrData->LM629Status.Set(static_cast<uint8_t>(Byte));
78 
79  StatusStream.seekg(15);
80  StatusStream >> Byte; // Extract error codes
81  if (Byte > 0xFF)
82  throw Util::InvalidDataException("Received an unexpected error code.");
83  InstrData->ErrorCode = static_cast<PI_C_862StageData::ErrorCodeType>(Byte);
84  }
85  catch ([[maybe_unused]] const Util::InvalidDataException& e)
86  {
87  UpdateError = true;
88 
89  // Swallow if just one or two subsequent updates failed.
90  if (InstrData->NumFailedStatusUpdateAttempts++ >= 3)
91  throw;
92  }
93 
94  if (!UpdateError)
95  InstrData->NumFailedStatusUpdateAttempts = 0;
96  }
97  // Issued if a mutex is blocked by another operation.
98  catch (const Util::TimeoutException& e)
99  {
100  Instance.GetOwner().SetWarning(e);
101 
102  return;
103  }
104  // Issued by PI_C_862::AnswerToNumberString() or StrToT() if unexpected or no data has been received.
105  catch (const Util::InvalidDataException& e)
106  {
107  Instance.GetOwner().SetWarning(e);
108 
109  return;
110  }
111  // Issued by std::stringstream if extracting data fails.
112  catch (const std::stringstream::failure& e)
113  {
114  Instance.GetOwner().SetWarning(e.what(), Util::DynExpErrorCodes::InvalidData);
115 
116  return;
117  }
118 
119  UpdateFuncImpl(dispatch_tag<UpdateTask>(), Instance);
120  }
121 
123  {
124  auto InstrData = DynExp::dynamic_InstrumentData_cast<PI_C_862>(Instance.InstrumentDataGetter());
125 
126  // Define home
127  *InstrData->HardwareAdapter << "DH";
128 
129  return {};
130  }
131 
133  {
134  auto InstrData = DynExp::dynamic_InstrumentData_cast<PI_C_862>(Instance.InstrumentDataGetter());
135 
136  // Find edge
138  *InstrData->HardwareAdapter << "FE0";
139  else
140  *InstrData->HardwareAdapter << "FE1";
141 
142  return {};
143  }
144 
146  {
147  auto InstrData = DynExp::dynamic_InstrumentData_cast<PI_C_862>(Instance.InstrumentDataGetter());
148 
149  // Set velocity
150  *InstrData->HardwareAdapter << "SV" + Util::ToStr(Velocity);
151 
152  return {};
153  }
154 
156  {
157  auto InstrData = DynExp::dynamic_InstrumentData_cast<PI_C_862>(Instance.InstrumentDataGetter());
158 
159  // Go home
160  *InstrData->HardwareAdapter << "GH";
161 
162  return {};
163  }
164 
166  {
167  auto InstrData = DynExp::dynamic_InstrumentData_cast<PI_C_862>(Instance.InstrumentDataGetter());
168 
169  // Move absolute
170  *InstrData->HardwareAdapter << "MA" + Util::ToStr(Position);
171 
172  return {};
173  }
174 
176  {
177  auto InstrData = DynExp::dynamic_InstrumentData_cast<PI_C_862>(Instance.InstrumentDataGetter());
178 
179  // Move relative
180  *InstrData->HardwareAdapter << "MR" + Util::ToStr(Position);
181 
182  return {};
183  }
184 
186  {
187  auto InstrData = DynExp::dynamic_InstrumentData_cast<PI_C_862>(Instance.InstrumentDataGetter());
188 
189  // Abort motion
190  *InstrData->HardwareAdapter << "AB";
191 
192  return DynExp::TaskResultType();
193  }
194 
196  {
197  LM629Status.Set(0);
198  ErrorCode = NoError;
199  NumFailedStatusUpdateAttempts = 0;
200 
201  ResetImpl(dispatch_tag<PI_C_862StageData>());
202  }
203 
204  bool PI_C_862StageData::IsMovingChild() const noexcept
205  {
206  return !LM629Status.TrajectoryComplete();
207  }
208 
210  {
211  return LM629Status.TrajectoryComplete();
212  }
213 
214  bool PI_C_862StageData::HasFailedChild() const noexcept
215  {
216  return ErrorCode != 0
217  || LM629Status.CommandError() || LM629Status.PositionLimitExceeded()
218  || LM629Status.ExcessivePositionError() || LM629Status.BreakpointReached();
219  }
220 
221  // StartCode is something like "X:". In any case, it has a length of two characters
222  std::string PI_C_862::AnswerToNumberString(std::string&& Answer, const char* StartCode)
223  {
224  auto Pos = Answer.find(StartCode);
225 
226  if (Pos == std::string::npos)
227  throw Util::InvalidDataException("Received an unexpected answer.");
228 
229  return Answer.substr(Pos + 2);
230  }
231 
232  PI_C_862::PI_C_862(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType&& Params)
233  : PositionerStage(OwnerThreadID, std::move(Params))
234  {
235  }
236 
238  {
239  auto InstrData = DynExp::dynamic_InstrumentData_cast<PI_C_862>(GetInstrumentData());
240 
241  // Abort motion.
242  *InstrData->HardwareAdapter << "AB";
243  }
244 
246  {
248  }
249 }
Implementation of an instrument to control the Physik Instrumente (PI) C-862 positioner stage.
virtual bool HasArrivedChild() const noexcept override
Returns whether the stage has arrived at its destiny position (result of HasArrivedChild())
Definition: PI-C-862.cpp:209
virtual bool HasFailedChild() const noexcept override
Returns whether the stage is in an error state, i.e. moving has failed (result of HasFailedChild())
Definition: PI-C-862.cpp:214
virtual bool IsMovingChild() const noexcept override
Returns whether the stage is currently moving (result of IsMovingChild())
Definition: PI-C-862.cpp:204
void ResetImpl(dispatch_tag< PositionerStageData >) override final
Refer to DynExp::InstrumentDataBase::Reset(). Using tag dispatch mechanism to ensure that ResetImpl()...
Definition: PI-C-862.cpp:195
void ExitFuncImpl(dispatch_tag< PositionerStageTasks::ExitTask >, DynExp::InstrumentInstance &Instance) override final
Deinitializes the respective instrument within the instrument inheritance hierarchy....
Definition: PI-C-862.cpp:28
void InitFuncImpl(dispatch_tag< PositionerStageTasks::InitTask >, DynExp::InstrumentInstance &Instance) override final
Initializes the respective instrument within the instrument inheritance hierarchy....
Definition: PI-C-862.cpp:8
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PI-C-862.cpp:165
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PI-C-862.cpp:175
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PI-C-862.cpp:155
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PI-C-862.cpp:132
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PI-C-862.cpp:122
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PI-C-862.cpp:145
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PI-C-862.cpp:185
void UpdateFuncImpl(dispatch_tag< PositionerStageTasks::UpdateTask >, DynExp::InstrumentInstance &Instance) override final
Updates the respective instrument within the instrument inheritance hierarchy. Call UpdateFuncImpl() ...
Definition: PI-C-862.cpp:48
void ResetImpl(dispatch_tag< PositionerStage >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
Definition: PI-C-862.cpp:245
virtual void OnErrorChild() const override
Derived classes can perform critical shutdown actions after an error has occurred....
Definition: PI-C-862.cpp:237
PI_C_862(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType &&Params)
Definition: PI-C-862.cpp:232
static std::string AnswerToNumberString(std::string &&Answer, const char *StartCode)
Definition: PI-C-862.cpp:222
Implementation of a meta instrument to control single-axis positioner stages.
Definition: Stage.h:155
Refer to DynExp::ParamsBase::dispatch_tag.
Definition: Instrument.h:1151
Refer to DynExp::ParamsBase::dispatch_tag.
Definition: Instrument.h:1120
InstrumentDataTypeSyncPtrType GetInstrumentData(const std::chrono::milliseconds Timeout=GetInstrumentDataTimeoutDefault)
Locks the mutex of the instrument data class instance InstrumentData assigned to this InstrumentBase ...
Definition: Instrument.cpp:222
Refer to ParamsBase::dispatch_tag.
Definition: Instrument.h:146
Defines data for a thread belonging to a InstrumentBase instance. Refer to RunnableInstance.
Definition: Instrument.h:772
const InstrumentBase::InstrumentDataGetterType InstrumentDataGetter
Getter for instrument's data. Refer to InstrumentBase::InstrumentDataGetterType.
Definition: Instrument.h:791
Refer to ParamsBase::dispatch_tag.
Definition: Object.h:2018
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
Defines the return type of task functions.
Definition: Instrument.h:824
Refer to DynExp::ParamsBase::dispatch_tag.
Definition: Instrument.h:1182
Data to operate on is invalid for a specific purpose. This indicates a corrupted data structure or fu...
Definition: Exception.h:163
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
Definition: Exception.h:261
DynExp's instrument namespace contains the implementation of DynExp instruments which extend DynExp's...
Definition: Instrument.h:1254
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
Definition: Object.h:1807
std::string ToStr(const T &Value, int Precision=-1)
Converts a (numeric) value of type T to a std::string using operator<< of std::stringstream.
Definition: Util.h:625
Accumulates include statements to provide a precompiled header.