DynExp
Highly flexible laboratory automation for dynamically changing experiments.
SwabianInstrumentsPulseStreamer.cpp
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
3 #include "stdafx.h"
5 
6 namespace DynExpInstr
7 {
9  {
10  auto InstrParams = DynExp::dynamic_Params_cast<SwabianInstrumentsPulseStreamer>(Instance.ParamsGetter());
11  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
12 
13  InstrData->Channel = InstrParams->Channel;
14  Instance.LockObject(InstrParams->HardwareAdapter, InstrData->HardwareAdapter);
15  InstrData->GetSampleStream()->SetStreamSize(InstrParams->StreamSizeParams.StreamSize);
16 
18  }
19 
21  {
22  ExitFuncImpl(dispatch_tag<ExitTask>(), Instance);
23 
24  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
25 
26  Instance.UnlockObject(InstrData->HardwareAdapter);
27  }
28 
30  {
31  try
32  {
33  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
34  bool UpdateError = false;
35 
36  try
37  {
38  auto InstrParams = DynExp::dynamic_Params_cast<SwabianInstrumentsPulseStreamer>(Instance.ParamsGetter());
39  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
40 
41  InstrData->Streaming = InstrData->HardwareAdapter->IsStreaming();
42  InstrData->Finished = InstrData->HardwareAdapter->HasFinished();
43  }
44  catch ([[maybe_unused]] const DynExpHardware::gRPCException& e)
45  {
46  UpdateError = true;
47 
48  // Swallow if just one or two subsequent updates failed.
49  if (InstrData->NumFailedStatusUpdateAttempts++ >= 3)
50  throw;
51  }
52 
53  if (!UpdateError)
54  InstrData->NumFailedStatusUpdateAttempts = 0;
55  }
56  // Issued if a mutex is blocked by another operation.
57  catch (const Util::TimeoutException& e)
58  {
59  Instance.GetOwner().SetWarning(e);
60 
61  return;
62  }
63 
64  UpdateFuncImpl(dispatch_tag<UpdateTask>(), Instance);
65  }
66 
68  {
69  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
70 
71  const auto SampleStream = InstrData->GetCastSampleStream<SwabianInstrumentsPulseStreamerData::SampleStreamType>();
72  const auto Samples = SampleStream->ReadSamples(SampleStream->GetStreamSizeRead());
73  if (Samples.empty())
74  return {};
75 
76  std::vector<DynExpHardware::SIPulseStreamerHardwareAdapter::SampleType> TransformedSamples;
77  for (const auto& Sample : Samples)
78  {
79  const auto Timestamp = std::chrono::nanoseconds(Util::NumToT<std::chrono::nanoseconds::rep>(Sample.Time * std::nano::den));
80 
81  if (InstrData->IsDigitalChannel())
82  TransformedSamples.emplace_back(InstrData->GetChannel(), Timestamp, Sample.Value != 0);
83  else
84  TransformedSamples.emplace_back(InstrData->GetChannel(), Timestamp,
86  }
87 
88  InstrData->HardwareAdapter->SetSamples(InstrData->GetChannel(), TransformedSamples);
89 
90  return {};
91  }
92 
94  {
95  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
96 
97  InstrData->HardwareAdapter->SetSamples(InstrData->GetChannel(), { { InstrData->GetChannel(), std::chrono::nanoseconds(0), 0 } });
98 
99  return {};
100  }
101 
103  {
104  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
105 
106  InstrData->HardwareAdapter->RearmTrigger();
107 
108  return {};
109  }
110 
112  {
113  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
114 
115  InstrData->HardwareAdapter->SetConstantOutput();
116 
117  return {};
118  }
119 
121  {
122  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
123 
124  InstrData->HardwareAdapter->RearmTrigger();
125 
126  return {};
127  }
128 
130  {
131  auto InstrParams = DynExp::dynamic_Params_cast<SwabianInstrumentsPulseStreamer>(Instance.ParamsGetter());
132  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
133 
134  InstrData->GetSampleStream()->SetStreamSize(InstrParams->StreamSizeParams.StreamSize);
135 
136  return {};
137  }
138 
140  {
141  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
142 
143  InstrData->HardwareAdapter->ForceTrigger();
144 
145  return {};
146  }
147 
149  {
150  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
151 
152  auto TriggerMode = TriggerDesc.TriggerMode == FunctionGeneratorDefs::TriggerDescType::TriggerModeType::Continuous ?
153  DynExpHardware::SIPulseStreamerHardwareAdapterParams::TriggerModeType::Normal : DynExpHardware::SIPulseStreamerHardwareAdapterParams::TriggerModeType::Single;
154  auto TriggerEdge = DynExpHardware::SIPulseStreamerHardwareAdapterParams::TriggerEdgeType::Software;
155  switch (TriggerDesc.TriggerMode)
156  {
158  TriggerEdge = DynExpHardware::SIPulseStreamerHardwareAdapterParams::TriggerEdgeType::Immediate;
159  break;
161  case FunctionGeneratorDefs::TriggerDescType::TriggerModeType::ExternStep:
162  TriggerEdge = TriggerDesc.TriggerEdge == FunctionGeneratorDefs::TriggerDescType::TriggerEdgeType::Fall ?
163  DynExpHardware::SIPulseStreamerHardwareAdapterParams::TriggerEdgeType::FallingEdge : DynExpHardware::SIPulseStreamerHardwareAdapterParams::TriggerEdgeType::RisingEdge;
164  }
165 
166  InstrData->HardwareAdapter->SetTrigger(TriggerEdge, TriggerMode);
167 
168  return {};
169  }
170 
172  {
173  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
174 
175  InstrData->HardwareAdapter->SetConstantOutput(Pulse);
176 
177  return {};
178  }
179 
181  {
182  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
183 
184  InstrData->HardwareAdapter->ForceFinalSample();
185 
186  return {};
187  }
188 
190  {
191  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(Instance.InstrumentDataGetter());
192 
193  InstrData->HardwareAdapter->SetNumRuns(NumRuns);
194 
195  return {};
196  }
197 
199  {
200  return GetChannel() != DynExpHardware::SIPulseStreamerHardwareAdapterParams::OutputChannelType::AO0 &&
201  GetChannel() != DynExpHardware::SIPulseStreamerHardwareAdapterParams::OutputChannelType::AO1;
202  }
203 
205  {
206  Channel = {};
207  Streaming = false;
208  Finished = false;
209  NumFailedStatusUpdateAttempts = 0;
210 
212  }
213 
215  : FunctionGenerator(OwnerThreadID, std::move(Params))
216  {
217  }
218 
220  {
221  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(GetInstrumentData());
222 
224  }
225 
227  {
228  return MakeAndEnqueueTask<SwabianInstrumentsPulseStreamerTasks::SetConstantOutputTask>(Pulse, CallbackFunc);
229  }
230 
232  {
233  return MakeAndEnqueueTask<SwabianInstrumentsPulseStreamerTasks::SetNumRunsTask>(NumRuns, CallbackFunc);
234  }
235 
237  {
238  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(GetInstrumentData());
239 
240  return InstrData->HardwareAdapter->HasFinished();
241  }
242 
244  {
245  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(GetInstrumentData());
246 
247  return InstrData->HardwareAdapter->IsStreaming();
248  }
249 
251  {
253  }
254 
256  {
257  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(GetInstrumentData());
258 
259  return InstrData->IsDigitalChannel() ?
261  }
262 
264  {
265  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(GetInstrumentData());
266 
267  return InstrData->IsDigitalChannel() ?
269  }
270 
272  {
273  auto InstrData = DynExp::dynamic_InstrumentData_cast<SwabianInstrumentsPulseStreamer>(GetInstrumentData());
274 
275  return InstrData->IsDigitalChannel() ?
277  }
278 
280  bool PersistParams, DynExp::TaskBase::CallbackType CallbackFunc) const
281  {
282  MakeAndEnqueueTask<SwabianInstrumentsPulseStreamerTasks::SetTriggerTask>(TriggerDesc, CallbackFunc);
283  }
284 }
Implementation of an instrument to control a single output of the Swabian Instruments Pulse Streamer ...
Defines an exception caused by an operation involving the gRPC library and communication over a TCP s...
Implements a circular data stream based on Util::circularbuf using samples of type BasicSample.
std::vector< SampleT > ReadSamples(size_t Count)
Reads multiple samples from the stream's buffer StreamBuffer.
UnitType
Units which can be used for data stream instruments.
@ LogicLevel
Logic level (TTL) units (1 or 0)
Function generator meta instrument based on the data stream meta instrument to generate waveforms by ...
void ResetImpl(dispatch_tag< FunctionGeneratorData >) override final
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...
void ExitFuncImpl(dispatch_tag< FunctionGeneratorTasks::ExitTask >, DynExp::InstrumentInstance &Instance) override final
Deinitializes the respective instrument within the instrument inheritance hierarchy....
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...
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...
void InitFuncImpl(dispatch_tag< FunctionGeneratorTasks::InitTask >, DynExp::InstrumentInstance &Instance) override final
Initializes the respective instrument within the instrument inheritance hierarchy....
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...
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...
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...
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...
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...
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...
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...
void UpdateFuncImpl(dispatch_tag< FunctionGeneratorTasks::UpdateTask >, DynExp::InstrumentInstance &Instance) override final
Updates the respective instrument within the instrument inheritance hierarchy. Call UpdateFuncImpl() ...
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...
virtual FunctionGeneratorDefs::FunctionDescType GetMaxCapsChild() const override
Returns the maximal values assignable to a description of a generic periodic function.
virtual Util::OptionalBool IsRunning() const override
Determines whether the underlying hardware adapter is running a data acquisition or writing data.
virtual FunctionGeneratorDefs::FunctionDescType GetParamDefaultsChild() const override
Returns the default values to assign to a description of a generic periodic function.
virtual void SetTriggerChild(const FunctionGeneratorDefs::TriggerDescType &TriggerDesc, bool PersistParams, DynExp::TaskBase::CallbackType CallbackFunc) const override
SetTrigger() configures the function generator's trigger, which determines when the waveform generati...
virtual FunctionGeneratorDefs::FunctionDescType GetMinCapsChild() const override
Returns the minimal values assignable to a description of a generic periodic function.
virtual void SetConstantOutput(const DynExpHardware::SIPulseStreamerHardwareAdapter::PulseType &Pulse, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const
virtual void SetNumRuns(int64_t NumRuns, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const
virtual DataStreamInstrumentData::UnitType GetValueUnit() const noexcept override
Determines which unit corresponds to the values managed by this DataStreamInstrument instance....
virtual Util::OptionalBool HasFinished() const override
Determines whether the underlying hardware adapter finished data acquisition or writing data.
SwabianInstrumentsPulseStreamer(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType &&Params)
void ResetImpl(dispatch_tag< FunctionGenerator >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
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
std::function< void(const TaskBase &, ExceptionContainer &)> CallbackType
Type of a callback function which is invoked when a task has finished, failed or has been aborted....
Definition: Instrument.h:939
Defines the return type of task functions.
Definition: Instrument.h:824
Refer to DynExp::ParamsBase::dispatch_tag.
Definition: Instrument.h:1182
Data type which stores an optional bool value (unknown, false, true). The type evaluates to bool whil...
Definition: Util.h:549
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
Definition: Exception.h:261
@ Pulse
Manually defined pulses.
@ Fall
Trigger on falling edge.
@ ExternSingle
Run once after an external trigger signal has been detected.
@ Continuous
Run continuously disabling the trigger.
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
Accumulates include statements to provide a precompiled header.
Swabian Instruments Pulse Streamer 8/2's internal representation of a single pulse.
Type describing a generic periodic function.
Type describing trigger parameters determining when the waveform is generated.