DynExp
Highly flexible laboratory automation for dynamically changing experiments.
FunctionGenerator.cpp
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
3 #include "stdafx.h"
4 #include "FunctionGenerator.h"
5 
6 namespace DynExpInstr
7 {
9  : Pulses(std::move(Other.Pulses)), Offset(Other.Offset)
10  {
11  Other.Reset();
12  }
13 
15  : Pulses(std::move(Pulses)), Offset(0.0)
16  {
17  Pulses.clear();
18  }
19 
20  FunctionGeneratorDefs::PulsesDescType::PulsesDescType(const std::vector<double>& PulseStarts, const std::vector<double>& PulseAmplitudes, double Offset)
21  : Offset(Offset)
22  {
23  if (PulseStarts.size() != PulseAmplitudes.size())
24  throw Util::InvalidArgException("The given vectors of pulse start times and pulse lengths do not have the sime size.");
25 
26  std::transform(PulseStarts.cbegin(), PulseStarts.cend(), PulseAmplitudes.cbegin(),
27  std::inserter(Pulses, Pulses.begin()),
28  [](typename PulsesType::key_type key, typename PulsesType::mapped_type value) { return std::make_pair(key, value); });
29  }
30 
32  {
33  Pulses = std::move(Other.Pulses);
34  Offset = Other.Offset;
35 
36  Other.Reset();
37 
38  return *this;
39  }
40 
42  {
43  return Util::seconds(1.0 / FunctionDesc.FrequencyInHz);
44  }
45 
46  // returns Heaviside(-(Phase mod 2*pi) + 2*pi * DutyCycle)
47  double FunctionGeneratorDefs::RectFunc(double DutyCycle, double Phase)
48  {
49  return std::fmod(Phase, 2.0 * std::numbers::pi) <= 2.0 * std::numbers::pi * DutyCycle;
50  }
51 
52  // returns Heaviside((Phase mod 2*pi) - 2*pi * DutyCycle)
53  double FunctionGeneratorDefs::InvRectFunc(double DutyCycle, double Phase)
54  {
55  return std::fmod(Phase, 2.0 * std::numbers::pi) > 2.0 * std::numbers::pi * DutyCycle;
56  }
57 
58  // returns RectFunc(Phase, RiseFallRatio) * (Phase mod(2*pi)) / (pi * RiseFallRatio)
59  // + InvRectFunc(Phase, RiseFallRatio) * ((-Phase) mod(2*pi)) / (pi * (1 - RiseFallRatio))
60  // - 1
61  double FunctionGeneratorDefs::RampFunc(double RiseFallRatio, double Phase)
62  {
63  // RiseFallRatio = 0 or RiseFallRatio = 1 lead to division by 0.
64  constexpr double MaxPrecision = 1e-6;
65  RiseFallRatio = std::min(1.0 - MaxPrecision, RiseFallRatio);
66  RiseFallRatio = std::max(MaxPrecision, RiseFallRatio);
67 
68  return RectFunc(RiseFallRatio, Phase) * std::fmod(Phase, 2.0 * std::numbers::pi) / (std::numbers::pi * RiseFallRatio)
69  + InvRectFunc(RiseFallRatio, Phase) * (std::fmod(-Phase, 2.0 * std::numbers::pi) + 2.0 * std::numbers::pi) / (std::numbers::pi * (1 - RiseFallRatio))
70  - 1;
71  }
72 
74  {
75  // Initialize this FunctionGenerator meta instrument first.
76  // -> Nothing to be done.
77 
78  // Initialize derived classes next since only tasks generating certain waveform and setting up the trigger
79  // are enqueued afterwards. These tasks may rely on the derived classes being fully initialized.
80  InitFuncImpl(dispatch_tag<InitTask>(), Instance);
81 
82  auto InstrParams = DynExp::dynamic_Params_cast<FunctionGenerator>(Instance.ParamsGetter());
83  auto InstrData = DynExp::dynamic_InstrumentData_cast<FunctionGenerator>(Instance.InstrumentDataGetter());
84  auto Owner = DynExp::dynamic_Object_cast<FunctionGenerator>(&Instance.GetOwner());
85 
86  if (InstrParams->WaveformType == FunctionGeneratorDefs::WaveformTypes::Sine)
87  Owner->SetSineFunction(FunctionGeneratorDefs::SineFunctionDescType(
88  InstrParams->FrequencyInHz, InstrParams->Amplitude, InstrParams->Offset, InstrParams->PhaseInRad),
89  false, InstrParams->Autostart.Get());
90  if (InstrParams->WaveformType == FunctionGeneratorDefs::WaveformTypes::Rect)
91  Owner->SetRectFunction(FunctionGeneratorDefs::RectFunctionDescType(
92  InstrParams->FrequencyInHz, InstrParams->Amplitude, InstrParams->Offset, InstrParams->PhaseInRad, InstrParams->DutyCycle),
93  false, InstrParams->Autostart.Get());
94  if (InstrParams->WaveformType == FunctionGeneratorDefs::WaveformTypes::Ramp)
95  Owner->SetRampFunction(FunctionGeneratorDefs::RampFunctionDescType(
96  InstrParams->FrequencyInHz, InstrParams->Amplitude, InstrParams->Offset, InstrParams->PhaseInRad, InstrParams->DutyCycle),
97  false, InstrParams->Autostart.Get());
98  if (InstrParams->WaveformType == FunctionGeneratorDefs::WaveformTypes::Pulse)
99  Owner->SetPulseFunction(FunctionGeneratorDefs::PulsesDescType(
100  InstrParams->PulseStarts.Get(), InstrParams->PulseAmplitudes.Get(), InstrParams->Offset),
101  false, InstrParams->Autostart.Get());
102 
103  if (Owner->GetTriggerCaps().Test(FunctionGenerator::TriggerCapsType::CanConfigure))
104  Owner->SetTrigger(FunctionGeneratorDefs::TriggerDescType(
105  InstrParams->TriggerMode, InstrParams->TriggerEdge),
106  false);
107  }
108 
110  {
111  {
112  auto InstrData = DynExp::dynamic_InstrumentData_cast<FunctionGenerator>(Instance.InstrumentDataGetter());
113  if (InstrData->DataHasBeenUpdated)
114  if (InstrData->GetSampleStream()->GetNumSamplesWritten() >= InstrData->GetSampleStream()->GetStreamSizeWrite())
115  {
116  DynExp::dynamic_Object_cast<FunctionGenerator>(&Instance.GetOwner())->WriteData();
117  InstrData->DataHasBeenUpdated = false;
118 
119  if (InstrData->ShouldAutostart)
120  DynExp::dynamic_Object_cast<FunctionGenerator>(&Instance.GetOwner())->Start();
121  }
122  } // InstrData unlocked here.
123 
124  UpdateFuncImpl(dispatch_tag<UpdateTask>(), Instance);
125  }
126 
128  {
129  auto InstrData = DynExp::dynamic_InstrumentData_cast<FunctionGenerator>(Instance.InstrumentDataGetter());
130 
131  auto SampleStream = InstrData->GetSampleStream();
132  SampleStream->Clear();
133 
134  auto NumSamples = SampleStream->GetStreamSizeWrite();
135  for (decltype(NumSamples) i = 0; i < NumSamples; ++i)
136  {
137  auto t = FunctionGeneratorDefs::PeriodFromFunctionDesc(FunctionDesc) / NumSamples * i;
138  double Value = FunctionDesc.Amplitude * std::sin(FunctionDesc.FrequencyInHz * 2 * std::numbers::pi
139  * t.count() + FunctionDesc.PhaseInRad) + FunctionDesc.Offset;
140 
141  SampleStream->WriteBasicSample({ Value, t.count() });
142  }
143 
144  InstrData->DataHasBeenUpdated = true;
145  InstrData->CurrentWaveformType = FunctionGeneratorDefs::WaveformTypes::Sine;
146  InstrData->CurrentFrequencyInHz = FunctionDesc.FrequencyInHz;
147  InstrData->CurrentAmplitude = FunctionDesc.Amplitude;
148  InstrData->CurrentOffset = FunctionDesc.Offset;
149  InstrData->CurrentPhaseInRad = FunctionDesc.PhaseInRad;
150  InstrData->ShouldAutostart = Autostart;
151 
152  return {};
153  }
154 
156  {
157  auto InstrData = DynExp::dynamic_InstrumentData_cast<FunctionGenerator>(Instance.InstrumentDataGetter());
158 
159  auto SampleStream = InstrData->GetSampleStream();
160  SampleStream->Clear();
161 
162  auto NumSamples = SampleStream->GetStreamSizeWrite();
163  for (decltype(NumSamples) i = 0; i < NumSamples; ++i)
164  {
165  auto t = FunctionGeneratorDefs::PeriodFromFunctionDesc(FunctionDesc) / NumSamples * i;
166  double Value = FunctionDesc.Amplitude * FunctionGeneratorDefs::RectFunc(FunctionDesc.DutyCycle,
167  FunctionDesc.FrequencyInHz * 2 * std::numbers::pi * t.count() + FunctionDesc.PhaseInRad) + FunctionDesc.Offset;
168 
169  SampleStream->WriteBasicSample({ Value, t.count() });
170  }
171 
172  InstrData->DataHasBeenUpdated = true;
173  InstrData->CurrentWaveformType = FunctionGeneratorDefs::WaveformTypes::Rect;
174  InstrData->CurrentFrequencyInHz = FunctionDesc.FrequencyInHz;
175  InstrData->CurrentAmplitude = FunctionDesc.Amplitude;
176  InstrData->CurrentOffset = FunctionDesc.Offset;
177  InstrData->CurrentPhaseInRad = FunctionDesc.PhaseInRad;
178  InstrData->CurrentDutyCycle = FunctionDesc.DutyCycle;
179  InstrData->ShouldAutostart = Autostart;
180 
181  return {};
182  }
183 
185  {
186  auto InstrData = DynExp::dynamic_InstrumentData_cast<FunctionGenerator>(Instance.InstrumentDataGetter());
187 
188  auto SampleStream = InstrData->GetSampleStream();
189  SampleStream->Clear();
190 
191  auto NumSamples = SampleStream->GetStreamSizeWrite();
192  for (decltype(NumSamples) i = 0; i < NumSamples; ++i)
193  {
194  auto t = FunctionGeneratorDefs::PeriodFromFunctionDesc(FunctionDesc) / NumSamples * i;
195  double Value = FunctionDesc.Amplitude * FunctionGeneratorDefs::RampFunc(FunctionDesc.RiseFallRatio,
196  FunctionDesc.FrequencyInHz * 2 * std::numbers::pi * t.count() + FunctionDesc.PhaseInRad) + FunctionDesc.Offset;
197 
198  SampleStream->WriteBasicSample({ Value, t.count() });
199  }
200 
201  InstrData->DataHasBeenUpdated = true;
202  InstrData->CurrentWaveformType = FunctionGeneratorDefs::WaveformTypes::Ramp;
203  InstrData->CurrentFrequencyInHz = FunctionDesc.FrequencyInHz;
204  InstrData->CurrentAmplitude = FunctionDesc.Amplitude;
205  InstrData->CurrentOffset = FunctionDesc.Offset;
206  InstrData->CurrentPhaseInRad = FunctionDesc.PhaseInRad;
207  InstrData->CurrentDutyCycle = FunctionDesc.RiseFallRatio;
208  InstrData->ShouldAutostart = Autostart;
209 
210  return {};
211  }
212 
214  {
215  auto InstrData = DynExp::dynamic_InstrumentData_cast<FunctionGenerator>(Instance.InstrumentDataGetter());
216 
217  if (FunctionDesc.Pulses.size() > 1)
218  {
219  auto SampleStream = InstrData->GetSampleStream();
220  SampleStream->Clear();
221 
222  auto NumSamples = SampleStream->GetStreamSizeWrite();
223  auto StartTime = FunctionDesc.Pulses.cbegin()->first;
224  auto TimePerSample = (std::prev(FunctionDesc.Pulses.cend())->first - StartTime) / (NumSamples - 1);
225  auto PulseIt = FunctionDesc.Pulses.cbegin();
226  for (decltype(NumSamples) i = 0; i < NumSamples; ++i)
227  {
228  auto t = StartTime + i * TimePerSample;
229  while (std::next(PulseIt) != FunctionDesc.Pulses.cend() && t >= std::next(PulseIt)->first)
230  ++PulseIt;
231 
232  SampleStream->WriteBasicSample({ PulseIt->second + FunctionDesc.Offset, t });
233  }
234  }
235 
236  InstrData->DataHasBeenUpdated = true;
237  InstrData->CurrentWaveformType = FunctionGeneratorDefs::WaveformTypes::Pulse;
238  InstrData->CurrentPulses = FunctionDesc.Pulses;
239  InstrData->ShouldAutostart = Autostart;
240 
241  return {};
242  }
243 
245  {
246  auto InstrData = DynExp::dynamic_InstrumentData_cast<FunctionGenerator>(Instance.InstrumentDataGetter());
247 
248  auto SampleStream = InstrData->GetSampleStream();
249  SampleStream->Clear();
250  SampleStream->SetStreamSize(Samples.size());
251  SampleStream->WriteBasicSamples(Samples);
252 
253  InstrData->DataHasBeenUpdated = true;
254  InstrData->CurrentWaveformType = FunctionGeneratorDefs::WaveformTypes::None;
255  InstrData->ShouldAutostart = Autostart;
256 
257  return {};
258  }
259 
261  {
262  auto InstrData = DynExp::dynamic_InstrumentData_cast<FunctionGenerator>(Instance.InstrumentDataGetter());
263 
264  InstrData->CurrentTriggerMode = TriggerDesc.TriggerMode;
265  InstrData->CurrentTriggerEdge = TriggerDesc.TriggerEdge;
266 
267  return {};
268  }
269 
271  {
272  DataHasBeenUpdated = false;
273 
274  CurrentWaveformType = FunctionGeneratorDefs::WaveformTypes::None;
278  CurrentPhaseInRad = 0;
279  CurrentDutyCycle = .5;
282  ShouldAutostart = false;
283 
284  CurrentPulses.Reset();
285 
287  }
288 
290  {
291  }
292 
294  {
295  }
296 
298  {
299  }
300 
302  bool PersistParams, bool Autostart, DynExp::TaskBase::CallbackType CallbackFunc) const
303  {
304  if (!GetWaveformCaps().Test(WaveformCapsType::UserDefined))
306  "The function generator of type " + GetCategoryAndName() + " is not capable to generate a user-defined function.", Util::ErrorType::Error);
307 
308  if (PersistParams)
309  {
310  auto InstrParams = DynExp::dynamic_Params_cast<FunctionGenerator>(GetNonConstParams());
311  InstrParams->WaveformType = FunctionGeneratorDefs::WaveformTypes::Sine;
312  InstrParams->FrequencyInHz = FunctionDesc.FrequencyInHz;
313  InstrParams->Amplitude = FunctionDesc.Amplitude;
314  InstrParams->Offset = FunctionDesc.Offset;
315  InstrParams->PhaseInRad = IsPhaseAdjustable() ? FunctionDesc.PhaseInRad : 0;
316  InstrParams->DutyCycle = .5;
317  InstrParams->Autostart = Autostart;
318  } // InstrParams unlocked here.
319 
320  MakeAndEnqueueTask<FunctionGeneratorTasks::SetSineFunctionTask>(FunctionDesc, Autostart, CallbackFunc);
321  UpdateData();
322  }
323 
325  bool PersistParams, bool Autostart, DynExp::TaskBase::CallbackType CallbackFunc) const
326  {
327  if (!GetWaveformCaps().Test(WaveformCapsType::UserDefined))
329  "The function generator of type " + GetCategoryAndName() + " is not capable to generate a user-defined function.", Util::ErrorType::Error);
330 
331  if (PersistParams)
332  {
333  auto InstrParams = DynExp::dynamic_Params_cast<FunctionGenerator>(GetNonConstParams());
334  InstrParams->WaveformType = FunctionGeneratorDefs::WaveformTypes::Rect;
335  InstrParams->FrequencyInHz = FunctionDesc.FrequencyInHz;
336  InstrParams->Amplitude = FunctionDesc.Amplitude;
337  InstrParams->Offset = FunctionDesc.Offset;
338  InstrParams->PhaseInRad = IsPhaseAdjustable() ? FunctionDesc.PhaseInRad : 0;
339  InstrParams->DutyCycle = FunctionDesc.DutyCycle;
340  InstrParams->Autostart = Autostart;
341  } // InstrParams unlocked here.
342 
343  MakeAndEnqueueTask<FunctionGeneratorTasks::SetRectFunctionTask>(FunctionDesc, Autostart, CallbackFunc);
344  UpdateData();
345  }
346 
348  bool PersistParams, bool Autostart, DynExp::TaskBase::CallbackType CallbackFunc) const
349  {
350  if (!GetWaveformCaps().Test(WaveformCapsType::UserDefined))
352  "The function generator of type " + GetCategoryAndName() + " is not capable to generate a user-defined function.", Util::ErrorType::Error);
353 
354  if (PersistParams)
355  {
356  auto InstrParams = DynExp::dynamic_Params_cast<FunctionGenerator>(GetNonConstParams());
357  InstrParams->WaveformType = FunctionGeneratorDefs::WaveformTypes::Ramp;
358  InstrParams->FrequencyInHz = FunctionDesc.FrequencyInHz;
359  InstrParams->Amplitude = FunctionDesc.Amplitude;
360  InstrParams->Offset = FunctionDesc.Offset;
361  InstrParams->PhaseInRad = IsPhaseAdjustable() ? FunctionDesc.PhaseInRad : 0;
362  InstrParams->DutyCycle = FunctionDesc.RiseFallRatio;
363  InstrParams->Autostart = Autostart;
364  } // InstrParams unlocked here.
365 
366  MakeAndEnqueueTask<FunctionGeneratorTasks::SetRampFunctionTask>(FunctionDesc, Autostart, CallbackFunc);
367  UpdateData();
368  }
369 
371  bool PersistParams, bool Autostart, DynExp::TaskBase::CallbackType CallbackFunc) const
372  {
373  if (!GetWaveformCaps().Test(WaveformCapsType::UserDefined))
375  "The function generator of type " + GetCategoryAndName() + " is not capable to generate a user-defined function.", Util::ErrorType::Error);
376 
377  // Valid pulse sequency consists of at least two edges.
378  if (FunctionDesc.Pulses.size() < 1)
379  return;
380 
381  if (PersistParams)
382  {
383  auto InstrParams = DynExp::dynamic_Params_cast<FunctionGenerator>(GetNonConstParams());
384  InstrParams->WaveformType = FunctionGeneratorDefs::WaveformTypes::Pulse;
385  InstrParams->Offset = FunctionDesc.Offset;
386 
387  auto PulsesKeys = std::views::keys(FunctionDesc.Pulses);
388  auto PulsesValues = std::views::values(FunctionDesc.Pulses);
389  InstrParams->PulseStarts = { PulsesKeys.begin(), PulsesKeys.end() };
390  InstrParams->PulseAmplitudes = { PulsesValues.begin(), PulsesValues.end() };
391 
392  InstrParams->Autostart = Autostart;
393  } // InstrParams unlocked here.
394 
395  MakeAndEnqueueTask<FunctionGeneratorTasks::SetPulseFunctionTask>(FunctionDesc, Autostart, CallbackFunc);
396  UpdateData();
397  }
398 
400  bool Autostart, DynExp::TaskBase::CallbackType CallbackFunc) const
401  {
402  if (!GetWaveformCaps().Test(WaveformCapsType::UserDefined))
404  "The function generator of type " + GetCategoryAndName() + " is not capable to generate a user-defined function.", Util::ErrorType::Error);
405 
406  MakeAndEnqueueTask<FunctionGeneratorTasks::SetArbitraryFunctionTask>(std::move(Samples), Autostart, CallbackFunc);
407  UpdateData();
408  }
409 
411  bool PersistParams, DynExp::TaskBase::CallbackType CallbackFunc) const
412  {
414  }
415 
417  bool PersistParams, DynExp::TaskBase::CallbackType CallbackFunc) const
418  {
420  }
421 
423  bool PersistParams, DynExp::TaskBase::CallbackType CallbackFunc) const
424  {
425  if (PersistParams)
426  {
427  auto InstrParams = DynExp::dynamic_Params_cast<FunctionGenerator>(GetNonConstParams());
428  InstrParams->TriggerMode = TriggerDesc.TriggerMode;
429  InstrParams->TriggerEdge = TriggerDesc.TriggerEdge;
430  } // InstrParams unlocked here.
431 
432  // CallbackFunc is to be called by task issued by overridden SetTriggerChild().
433  MakeAndEnqueueTask<FunctionGeneratorTasks::SetTriggerTask>(TriggerDesc);
434 
435  SetTriggerChild(TriggerDesc, PersistParams, CallbackFunc);
436  }
437 
439  {
441  }
442 
444  {
445  AsSyncTask(&FunctionGenerator::ForceTrigger);
446  }
447 
449  {
450  ResetImpl(dispatch_tag<FunctionGenerator>());
451  }
452 
454  bool PersistParams, DynExp::TaskBase::CallbackType CallbackFunc) const
455  {
457  }
458 }
Implementation of a function generator meta instrument to generate waveforms.
std::vector< BasicSample > BasicSampleListType
Type of a list containing data stream samples of type BasicSample.
void ResetImpl(dispatch_tag< DataStreamInstrumentData >) override final
void InitFuncImpl(dispatch_tag< DataStreamInstrumentTasks::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...
void UpdateFuncImpl(dispatch_tag< DataStreamInstrumentTasks::UpdateTask >, DynExp::InstrumentInstance &Instance) override final
Updates the respective instrument within the instrument inheritance hierarchy. Call UpdateFuncImpl() ...
virtual void ForceTriggerSync() const
Synchronized version of ForceTrigger(), which blocks until the task enqueued by ForceTrigger() has be...
virtual void SetModulation(const FunctionGeneratorDefs::ModulationDescType &ModulationDesc, bool PersistParams=false, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const
Configures the function generator to perform a modulation.
void ResetImpl(dispatch_tag< DataStreamInstrument >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
virtual void SetRampFunction(const FunctionGeneratorDefs::RampFunctionDescType &FunctionDesc, bool PersistParams=false, bool Autostart=false, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const
Generates a ramp function.
virtual void SetRectFunction(const FunctionGeneratorDefs::RectFunctionDescType &FunctionDesc, bool PersistParams=false, bool Autostart=false, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const
Generates a rectangular function.
virtual void SetTriggerChild(const FunctionGeneratorDefs::TriggerDescType &TriggerDesc, bool PersistParams, DynExp::TaskBase::CallbackType CallbackFunc) const
SetTrigger() configures the function generator's trigger, which determines when the waveform generati...
virtual void SetSweep(const FunctionGeneratorDefs::SweepDescType &SweepDesc, bool PersistParams=false, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const
Configures the function generator to perform a sweep.
virtual void SetPulseFunction(const FunctionGeneratorDefs::PulsesDescType &FunctionDesc, bool PersistParams=false, bool Autostart=false, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const
Generates a function consisting of pulse segments.
@ CanConfigure
Trigger settings can be adjusted by the software.
virtual void SetSineFunction(const FunctionGeneratorDefs::SineFunctionDescType &FunctionDesc, bool PersistParams=false, bool Autostart=false, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const
Generates a sine function.
virtual void ForceTrigger(DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const
Forces the generation of the waveform ignoring the trigger.
virtual void SetArbitraryFunction(DataStreamBase::BasicSampleListType &&Samples, bool Autostart=false, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const
Generates an arbitrary function defined by the function samples.
void SetTrigger(const FunctionGeneratorDefs::TriggerDescType &TriggerDesc, bool PersistParams=false, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const
SetTrigger() configures the function generator's trigger, which determines when the waveform generati...
Refer to DynExp::ParamsBase::dispatch_tag.
Definition: Instrument.h:1120
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
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
An invalid argument like a null pointer has been passed to a function.
Definition: Exception.h:137
Thrown when some operation or feature is temporarily or permanently not available.
Definition: Exception.h:286
Thrown when a requested feature is either under development and thus not implemented yet or when a sp...
Definition: Exception.h:299
double RectFunc(double DutyCycle, double Phase)
Calculates the value of a rectangular function depending on the current Phase.
constexpr Util::seconds PeriodFromFunctionDesc(const FunctionDescType &FunctionDesc)
Calculates the period from the given function description.
double InvRectFunc(double DutyCycle, double Phase)
Calculates the value of an inverse rectangular function depending on the current Phase.
@ Pulse
Manually defined pulses.
@ None
Unspecified/arbitrary waveform.
double RampFunc(double RiseFallRatio, double Phase)
Calculates the value of a ramp function depending on the current Phase.
constexpr FunctionDescType GetDefaultDefaultFunctionDesc()
Determines default values to assign to a description of a generic periodic function.
@ Rise
Trigger on rising edge.
@ 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::chrono::duration< double > seconds
Extends std::chrono by a duration data type for seconds capable of storing fractions of seconds.
Definition: Util.h:761
Accumulates include statements to provide a precompiled header.
Type describing a generic periodic function.
double Offset
Offset of the function to be added to each sample.
double FrequencyInHz
Frequency of the function in Hz.
Type describing modulation parameters for a waveform.
Type describing function consisting of a series of pulses.
double Offset
Offset of the function to be added to each sample.
PulsesDescType & operator=(PulsesDescType &&Other)
Move assignment operator. Reset() is called on Other after the operation.
PulsesType Pulses
Series of segments forming the pulse sequence. The resulting function stays constant during a segment...
std::map< double, double > PulsesType
Type containing pulses as tuples (time [s], value). The time refers to the beginning of a segment whe...
double PhaseInRad
Phase of the function in radians.
double RiseFallRatio
Ratio between the ramp's falling and rising edge lengths (in between 0 and 1)
double PhaseInRad
Phase of the function in radians.
double DutyCycle
Duty cycle of the function (in between 0 and 1)
double PhaseInRad
Phase of the function in radians.
Type describing sweep parameters for a waveform.
Type describing trigger parameters determining when the waveform is generated.
TriggerEdgeType TriggerEdge
Edge to trigger on.