18 #define MRPT_HAS_SOME_NIDAQMX (MRPT_HAS_NIDAQMXBASE || MRPT_HAS_NIDAQMX)
20 #define MRPT_USE_NIDAQMXBASE (MRPT_HAS_NIDAQMXBASE && !MRPT_HAS_NIDAQMX)
21 #define MRPT_USE_NIDAQMX (MRPT_HAS_NIDAQMX)
23 #if MRPT_USE_NIDAQMXBASE
24 #include "NIDAQmxBase.h"
32 #if MRPT_USE_NIDAQMXBASE
33 #define MRPT_DAQmxGetExtendedErrorInfo DAQmxBaseGetExtendedErrorInfo
34 #define MRPT_DAQmxCreateTask DAQmxBaseCreateTask
35 #define MRPT_DAQmxCreateAIVoltageChan DAQmxBaseCreateAIVoltageChan
36 #define MRPT_DAQmxCreateAOVoltageChan DAQmxBaseCreateAOVoltageChan
37 #define MRPT_DAQmxCreateDIChan DAQmxBaseCreateDIChan
38 #define MRPT_DAQmxCreateDOChan DAQmxBaseCreateDOChan
39 #define MRPT_DAQmxCreateCIPeriodChan DAQmxBaseCreateCIPeriodChan
40 #define MRPT_DAQmxCreateCICountEdgesChan DAQmxBaseCreateCICountEdgesChan
41 #define MRPT_DAQmxCreateCIPulseWidthChan DAQmxBaseCreateCIPulseWidthChan
42 #define MRPT_DAQmxCreateCILinEncoderChan DAQmxBaseCreateCILinEncoderChan
43 #define MRPT_DAQmxCreateCIAngEncoderChan DAQmxBaseCreateCIAngEncoderChan
44 #define MRPT_DAQmxCreateCOPulseChanFreq DAQmxBaseCreateCOPulseChanFreq
45 #define MRPT_DAQmxCfgSampClkTiming DAQmxBaseCfgSampClkTiming
46 #define MRPT_DAQmxCfgInputBuffer DAQmxBaseCfgInputBuffer
47 #define MRPT_DAQmxCfgOutputBuffer DAQmxBaseCfgOutputBuffer
48 #define MRPT_DAQmxStartTask DAQmxBaseStartTask
49 #define MRPT_DAQmxStopTask DAQmxBaseStopTask
50 #define MRPT_DAQmxClearTask DAQmxBaseClearTask
51 #define MRPT_DAQmxReadAnalogF64 DAQmxBaseReadAnalogF64
52 #define MRPT_DAQmxReadCounterF64 DAQmxBaseReadCounterF64
53 #define MRPT_DAQmxReadDigitalU8 DAQmxBaseReadDigitalU8
54 #define MRPT_DAQmxWriteAnalogF64 DAQmxBaseWriteAnalogF64
55 #define MRPT_DAQmxWriteDigitalU32 DAQmxBaseWriteDigitalU32
56 #define MRPT_DAQmxWriteDigitalLines DAQmxBaseWriteDigitalLines
58 #define MRPT_DAQmxGetExtendedErrorInfo DAQmxGetExtendedErrorInfo
59 #define MRPT_DAQmxCreateTask DAQmxCreateTask
60 #define MRPT_DAQmxCreateAIVoltageChan DAQmxCreateAIVoltageChan
61 #define MRPT_DAQmxCreateAOVoltageChan DAQmxCreateAOVoltageChan
62 #define MRPT_DAQmxCreateDIChan DAQmxCreateDIChan
63 #define MRPT_DAQmxCreateDOChan DAQmxCreateDOChan
64 #define MRPT_DAQmxCreateCIPeriodChan DAQmxCreateCIPeriodChan
65 #define MRPT_DAQmxCreateCICountEdgesChan DAQmxCreateCICountEdgesChan
66 #define MRPT_DAQmxCreateCIPulseWidthChan DAQmxCreateCIPulseWidthChan
67 #define MRPT_DAQmxCreateCILinEncoderChan DAQmxCreateCILinEncoderChan
68 #define MRPT_DAQmxCreateCIAngEncoderChan DAQmxCreateCIAngEncoderChan
69 #define MRPT_DAQmxCreateCOPulseChanFreq DAQmxCreateCOPulseChanFreq
70 #define MRPT_DAQmxCfgSampClkTiming DAQmxCfgSampClkTiming
71 #define MRPT_DAQmxCfgInputBuffer DAQmxCfgInputBuffer
72 #define MRPT_DAQmxCfgOutputBuffer DAQmxCfgOutputBuffer
73 #define MRPT_DAQmxStartTask DAQmxStartTask
74 #define MRPT_DAQmxStopTask DAQmxStopTask
75 #define MRPT_DAQmxClearTask DAQmxClearTask
76 #define MRPT_DAQmxReadAnalogF64 DAQmxReadAnalogF64
77 #define MRPT_DAQmxReadCounterF64 DAQmxReadCounterF64
78 #define MRPT_DAQmxReadDigitalU8 DAQmxReadDigitalU8
79 #define MRPT_DAQmxWriteAnalogF64 DAQmxWriteAnalogF64
80 #define MRPT_DAQmxWriteDigitalU32 DAQmxWriteDigitalU32
81 #define MRPT_DAQmxWriteDigitalLines DAQmxWriteDigitalLines
86 #define MRPT_DAQmx_ErrChk(functionCall) \
87 if ((functionCall) < 0) \
90 MRPT_DAQmxGetExtendedErrorInfo(errBuff, 2048); \
91 std::string sErr = mrpt::format( \
92 "DAQ error: '%s'\nCalling: '%s'", errBuff, #functionCall); \
93 THROW_EXCEPTION(sErr); \
109 new_obs_available(0),
124 #define MY_LOAD_HERE_CONFIG_VAR( \
125 variableName, variableType, targetVariable, configFileObject, \
127 targetVariable = configFileObject.read_##variableType( \
128 sectionNameStr, variableName, targetVariable, false);
130 #define MY_LOAD_HERE_CONFIG_VAR_NO_DEFAULT( \
131 variableName, variableType, targetVariable, configFileObject, \
136 targetVariable = configFileObject.read_##variableType( \
137 sectionNameStr, variableName, targetVariable, true); \
139 catch (std::exception&) \
143 "Value for '%s' not found in config file", \
144 std::string(variableName).c_str())); \
157 const unsigned int nTasks = cfg.
read_uint64_t(sect,
"num_tasks", 0,
true);
160 std::cerr <<
"[CNationalInstrumentsDAQ] Warning: Number of tasks is "
161 "zero. No datalogging will be done.\n";
165 for (
unsigned int i = 0; i < nTasks; i++)
172 const string sChanns =
173 cfg.
read_string(sect, sTask +
string(
".channels"),
"",
true);
174 vector<string> lstStrChanns;
176 if (lstStrChanns.empty())
180 sTask +
string(
".samplesPerSecond"),
double,
t.samplesPerSecond,
183 sTask +
string(
".samplesPerChannelToRead"),
double,
184 t.samplesPerChannelToRead, cfg, sect)
186 sTask +
string(
".sampleClkSource"),
string,
t.sampleClkSource, cfg,
189 sTask +
string(
".bufferSamplesPerChannel"),
double,
190 t.bufferSamplesPerChannel, cfg, sect)
192 cfg.
read_string(sect, sTask +
string(
".taskLabel"), sTask,
false);
194 for (
size_t j = 0; j < lstStrChanns.size(); j++)
196 if (
strCmpI(lstStrChanns[j],
"ai"))
200 sTask +
string(
".ai.physicalChannel"),
string,
201 t.ai.physicalChannel, cfg, sect)
203 sTask +
string(
".ai.physicalChannelCount"),
uint64_t,
204 t.ai.physicalChannelCount, cfg, sect)
206 sTask +
string(
".ai.terminalConfig"),
string,
207 t.ai.terminalConfig, cfg, sect)
209 sTask +
string(
".ai.minVal"),
double,
t.ai.minVal, cfg,
212 sTask +
string(
".ai.maxVal"),
double,
t.ai.maxVal, cfg,
215 else if (
strCmpI(lstStrChanns[j],
"ao"))
219 sTask +
string(
".ao.physicalChannel"),
string,
220 t.ao.physicalChannel, cfg, sect)
222 sTask +
string(
".ao.physicalChannelCount"),
uint64_t,
223 t.ao.physicalChannelCount, cfg, sect)
225 sTask +
string(
".ao.minVal"),
double,
t.ao.minVal, cfg,
228 sTask +
string(
".ao.maxVal"),
double,
t.ao.maxVal, cfg,
231 else if (
strCmpI(lstStrChanns[j],
"di"))
235 sTask +
string(
".di.line"),
string,
t.di.line, cfg, sect)
237 else if (
strCmpI(lstStrChanns[j],
"do"))
241 sTask +
string(
".do.line"),
string,
t.douts.line, cfg, sect)
243 else if (
strCmpI(lstStrChanns[j],
"ci_period"))
245 t.has_ci_period =
true;
247 sTask +
string(
".ci_period.counter"),
string,
248 t.ci_period.counter, cfg, sect)
250 sTask +
string(
".ci_period.minVal"),
double,
251 t.ci_period.minVal, cfg, sect)
253 sTask +
string(
".ci_period.maxVal"),
double,
254 t.ci_period.maxVal, cfg, sect)
256 sTask +
string(
".ci_period.units"),
string,
257 t.ci_period.units, cfg, sect)
259 sTask +
string(
".ci_period.edge"),
string,
t.ci_period.edge,
262 sTask +
string(
".ci_period.measTime"),
double,
263 t.ci_period.measTime, cfg, sect)
265 sTask +
string(
".ci_period.divisor"),
int,
266 t.ci_period.divisor, cfg, sect)
268 else if (
strCmpI(lstStrChanns[j],
"ci_count_edges"))
270 t.has_ci_count_edges =
true;
272 sTask +
string(
".ci_count_edges.counter"),
string,
273 t.ci_count_edges.counter, cfg, sect)
275 sTask +
string(
".ci_count_edges.edge"),
string,
276 t.ci_count_edges.edge, cfg, sect)
278 sTask +
string(
".ci_count_edges.initialCount"),
int,
279 t.ci_count_edges.initialCount, cfg, sect)
281 sTask +
string(
".ci_count_edges.countDirection"),
string,
282 t.ci_count_edges.countDirection, cfg, sect)
284 else if (
strCmpI(lstStrChanns[j],
"ci_pulse_width"))
286 t.has_ci_pulse_width =
true;
288 sTask +
string(
".ci_pulse_width.counter"),
string,
289 t.ci_pulse_width.counter, cfg, sect)
291 sTask +
string(
".ci_pulse_width.minVal"),
double,
292 t.ci_pulse_width.minVal, cfg, sect)
294 sTask +
string(
".ci_pulse_width.maxVal"),
double,
295 t.ci_pulse_width.maxVal, cfg, sect)
297 sTask +
string(
".ci_pulse_width.units"),
string,
298 t.ci_pulse_width.units, cfg, sect)
300 sTask +
string(
".ci_pulse_width.startingEdge"),
string,
301 t.ci_pulse_width.startingEdge, cfg, sect)
303 else if (
strCmpI(lstStrChanns[j],
"ci_lin_encoder"))
305 t.has_ci_lin_encoder =
true;
307 sTask +
string(
".ci_lin_encoder.counter"),
string,
308 t.ci_lin_encoder.counter, cfg, sect)
310 sTask +
string(
".ci_lin_encoder.decodingType"),
string,
311 t.ci_lin_encoder.decodingType, cfg, sect)
313 sTask +
string(
".ci_lin_encoder.ZidxEnable"),
bool,
314 t.ci_lin_encoder.ZidxEnable, cfg, sect)
316 sTask +
string(
".ci_lin_encoder.ZidxVal"),
double,
317 t.ci_lin_encoder.ZidxVal, cfg, sect)
319 sTask +
string(
".ci_lin_encoder.ZidxPhase"),
string,
320 t.ci_lin_encoder.ZidxPhase, cfg, sect)
322 sTask +
string(
".ci_lin_encoder.units"),
string,
323 t.ci_lin_encoder.units, cfg, sect)
325 sTask +
string(
".ci_lin_encoder.distPerPulse"),
double,
326 t.ci_lin_encoder.distPerPulse, cfg, sect)
328 sTask +
string(
".ci_lin_encoder.initialPos"),
double,
329 t.ci_lin_encoder.initialPos, cfg, sect)
331 else if (
strCmpI(lstStrChanns[j],
"ci_ang_encoder"))
333 t.has_ci_ang_encoder =
true;
335 sTask +
string(
".ci_ang_encoder.counter"),
string,
336 t.ci_ang_encoder.counter, cfg, sect)
338 sTask +
string(
".ci_ang_encoder.decodingType"),
string,
339 t.ci_ang_encoder.decodingType, cfg, sect)
341 sTask +
string(
".ci_ang_encoder.ZidxEnable"),
bool,
342 t.ci_ang_encoder.ZidxEnable, cfg, sect)
344 sTask +
string(
".ci_ang_encoder.ZidxVal"),
double,
345 t.ci_ang_encoder.ZidxVal, cfg, sect)
347 sTask +
string(
".ci_ang_encoder.ZidxPhase"),
string,
348 t.ci_ang_encoder.ZidxPhase, cfg, sect)
350 sTask +
string(
".ci_ang_encoder.units"),
string,
351 t.ci_ang_encoder.units, cfg, sect)
353 sTask +
string(
".ci_ang_encoder.pulsesPerRev"),
int,
354 t.ci_ang_encoder.pulsesPerRev, cfg, sect)
356 sTask +
string(
".ci_ang_encoder.initialAngle"),
double,
357 t.ci_ang_encoder.initialAngle, cfg, sect)
359 sTask +
string(
".ci_ang_encoder.decimate"),
int,
360 t.ci_ang_encoder.decimate, cfg, sect)
362 else if (
strCmpI(lstStrChanns[j],
"co_pulses"))
364 t.has_co_pulses =
true;
366 sTask +
string(
".co_pulses.counter"),
string,
367 t.co_pulses.counter, cfg, sect)
369 sTask +
string(
".co_pulses.idleState"),
string,
370 t.co_pulses.idleState, cfg, sect)
372 sTask +
string(
".co_pulses.initialDelay"),
double,
373 t.co_pulses.initialDelay, cfg, sect)
375 sTask +
string(
".co_pulses.freq"),
double,
t.co_pulses.freq,
378 sTask +
string(
".co_pulses.dutyCycle"),
double,
379 t.co_pulses.dutyCycle, cfg, sect)
384 "Unknown channel type '%s'! See the docs of "
385 "CNationalInstrumentsDAQ",
386 lstStrChanns[j].c_str())
396 #if MRPT_HAS_SOME_NIDAQMX
404 const daqmx_str_val daqmx_vals[] = {
405 {
"DAQmx_Val_Cfg_Default", DAQmx_Val_Cfg_Default},
406 {
"DAQmx_Val_RSE", DAQmx_Val_RSE},
407 {
"DAQmx_Val_NRSE", DAQmx_Val_NRSE},
408 {
"DAQmx_Val_Diff", DAQmx_Val_Diff},
409 {
"DAQmx_Val_Seconds", DAQmx_Val_Seconds},
410 {
"DAQmx_Val_Rising", DAQmx_Val_Rising},
411 {
"DAQmx_Val_Falling", DAQmx_Val_Falling},
412 {
"DAQmx_Val_CountUp", DAQmx_Val_CountUp},
413 {
"DAQmx_Val_CountDown", DAQmx_Val_CountDown},
414 {
"DAQmx_Val_ExtControlled", DAQmx_Val_ExtControlled},
415 {
"DAQmx_Val_AHighBHigh", DAQmx_Val_AHighBHigh},
416 {
"DAQmx_Val_AHighBLow", DAQmx_Val_AHighBLow},
417 {
"DAQmx_Val_ALowBHigh", DAQmx_Val_ALowBHigh},
418 {
"DAQmx_Val_ALowBLow", DAQmx_Val_ALowBLow},
419 {
"DAQmx_Val_X1", DAQmx_Val_X1},
420 {
"DAQmx_Val_X2", DAQmx_Val_X2},
421 {
"DAQmx_Val_X4", DAQmx_Val_X4},
422 {
"DAQmx_Val_Meters", DAQmx_Val_Meters},
423 {
"DAQmx_Val_Inches", DAQmx_Val_Inches},
424 {
"DAQmx_Val_Ticks", DAQmx_Val_Ticks},
425 {
"DAQmx_Val_Degrees", DAQmx_Val_Degrees},
426 {
"DAQmx_Val_Radians", DAQmx_Val_Radians},
427 {
"DAQmx_Val_High", DAQmx_Val_High},
428 {
"DAQmx_Val_Low", DAQmx_Val_Low}};
434 for (
unsigned int i = 0; i <
sizeof(daqmx_vals) /
sizeof(daqmx_vals[0]);
437 if (
strCmpI(daqmx_vals[i].str,
s.c_str()))
return daqmx_vals[i].
val;
448 #if MRPT_HAS_SOME_NIDAQMX
463 TaskHandle& taskHandle =
464 *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
472 "ai.physicalChannelCount is zero! Please, define it "
479 tf.
ai.
maxVal, DAQmx_Val_Volts,
nullptr));
485 "ai.physicalChannelCount is zero! Please, define it "
497 taskHandle, tf.
di.
line.c_str(),
nullptr,
498 DAQmx_Val_ChanPerLine));
504 taskHandle, tf.
douts.
line.c_str(),
nullptr,
505 DAQmx_Val_ChanPerLine));
610 ipt.
read_pipe->timeout_read_start_us = 100000;
611 ipt.
read_pipe->timeout_read_between_us = 100000;
618 catch (std::exception
const& e)
620 std::cerr <<
"[CNationalInstrumentsDAQ] Error:" << std::endl
621 << e.what() << std::endl;
624 TaskHandle& taskHandle =
625 *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
634 cerr <<
"[CNationalInstrumentsDAQ::initialize] Waiting for the "
635 "grabbing thread to end due to exception...\n";
637 cerr <<
"[CNationalInstrumentsDAQ::initialize] Grabbing thread "
644 std::cerr <<
"[CNationalInstrumentsDAQ] Error while creating "
645 "tasks. Closing other tasks before returning...\n";
647 std::cerr <<
"[CNationalInstrumentsDAQ] Closing tasks done.\n";
666 it->must_close =
true;
669 cout <<
"[CNationalInstrumentsDAQ::stop] Waiting for grabbing threads "
675 if (it->hThread.joinable()) it->hThread.join();
682 cout <<
"[CNationalInstrumentsDAQ::stop] All threads ended.\n";
685 #if MRPT_HAS_SOME_NIDAQMX
689 TaskHandle& taskHandle =
690 *
reinterpret_cast<TaskHandle*
>(&it->taskHandle);
694 taskHandle =
nullptr;
709 std::vector<mrpt::obs::CObservationRawDAQ::Ptr>& outObservations,
712 hardwareError =
false;
713 outObservations.clear();
717 hardwareError =
true;
730 if (it->new_obs_available != 0)
733 arch.ReadObject(&tmp_obs);
734 --(it->new_obs_available);
737 outObservations.push_back(
766 std::vector<mrpt::serialization::CSerializable::Ptr> new_obs;
781 #if MRPT_HAS_SOME_NIDAQMX
784 TaskHandle& taskHandle =
785 *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
787 cout <<
"[CNationalInstrumentsDAQ::grabbing_thread] Starting "
794 const float timeout =
799 vector<uint8_t> u8Buf;
813 bool there_are_data =
false;
825 dBuf.resize(totalSamplesToRead);
826 int32 pointsReadPerChan = -1;
830 : DAQmx_Val_GroupByChannel,
831 &dBuf[0], dBuf.size(), &pointsReadPerChan,
nullptr)) <
833 err != DAQmxErrorSamplesNotYetAvailable)
837 else if (pointsReadPerChan > 0)
843 there_are_data =
true;
845 cout <<
"[CNationalInstrumentsDAQ::grabbing_thread] "
846 << pointsReadPerChan <<
" analog samples read.\n";
853 u8Buf.resize(totalSamplesToRead);
855 int32 pointsReadPerChan = -1;
858 DAQmx_Val_GroupByChannel, &u8Buf[0], u8Buf.size(),
859 &pointsReadPerChan,
nullptr)) < 0 &&
860 err != DAQmxErrorSamplesNotYetAvailable)
864 else if (pointsReadPerChan > 0)
870 there_are_data =
true;
872 cout <<
"[CNationalInstrumentsDAQ::grabbing_thread] "
873 << pointsReadPerChan <<
" digital samples read.\n";
878 const int32 totalSamplesToRead =
880 dBuf.resize(totalSamplesToRead);
881 int32 pointsReadPerChan = -1;
883 taskHandle, totalSamplesToRead, timeout, &dBuf[0],
884 dBuf.size(), &pointsReadPerChan,
nullptr)) < 0 &&
885 err != DAQmxErrorSamplesNotYetAvailable)
889 else if (pointsReadPerChan > 0)
899 there_are_data =
true;
902 static int decim = 0;
904 cout <<
"[CNationalInstrumentsDAQ::grabbing_"
907 <<
" counter samples read ([0]="
909 if (++decim > 100) decim = 0;
925 std::this_thread::sleep_for(1ms);
930 catch (std::exception& e)
932 std::cerr <<
"[CNationalInstrumentsDAQ::grabbing_thread] Exception:\n"
933 << e.what() << std::endl;
941 size_t task_index,
size_t nSamplesPerChannel,
const double* volt_values,
942 double timeout,
bool groupedByChannel)
944 #if MRPT_HAS_SOME_NIDAQMX
947 std::advance(it, task_index);
949 TaskHandle& taskHandle = *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
951 int32 samplesWritten = 0;
954 taskHandle, nSamplesPerChannel,
FALSE, timeout,
955 groupedByChannel ? DAQmx_Val_GroupByChannel
956 : DAQmx_Val_GroupByScanNumber,
957 const_cast<float64*
>(volt_values), &samplesWritten,
nullptr))
971 size_t task_index,
bool line_value,
double timeout)
973 #if MRPT_HAS_SOME_NIDAQMX
976 std::advance(it, task_index);
978 TaskHandle& taskHandle = *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
980 uInt8 dat = line_value ? 1 : 0;
982 int32 samplesWritten = 0;
983 int32 nSamplesPerChannel = 1;
986 taskHandle, nSamplesPerChannel,
FALSE, timeout,
987 DAQmx_Val_GroupByScanNumber, &dat, &samplesWritten,
nullptr))
1005 has_ci_period(false),
1006 has_ci_count_edges(false),
1007 has_ci_pulse_width(false),
1008 has_ci_lin_encoder(false),
1009 has_ci_ang_encoder(false),
1010 has_co_pulses(false),
1011 samplesPerSecond(1000.0),
1012 bufferSamplesPerChannel(200000),
1013 samplesPerChannelToRead(1000)
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
#define MRPT_DAQmxCreateCOPulseChanFreq
#define MRPT_DAQmxCreateCICountEdgesChan
#define MRPT_DAQmxWriteDigitalLines
#define MRPT_DAQmxCfgInputBuffer
#define MRPT_DAQmxCfgSampClkTiming
#define MRPT_DAQmxStopTask
#define MRPT_DAQmxStartTask
#define MRPT_DAQmxCreateCILinEncoderChan
#define MRPT_DAQmxCreateCIPulseWidthChan
#define MRPT_DAQmxCreateTask
#define MRPT_DAQmxReadCounterF64
#define MRPT_DAQmxCreateAIVoltageChan
#define MRPT_DAQmxReadDigitalU8
#define MRPT_DAQmxCreateCIAngEncoderChan
#define MY_LOAD_HERE_CONFIG_VAR_NO_DEFAULT( variableName, variableType, targetVariable, configFileObject, sectionNameStr)
#define MRPT_DAQmxCreateCIPeriodChan
#define MRPT_DAQmxCreateAOVoltageChan
#define MRPT_DAQmxCreateDOChan
#define MY_LOAD_HERE_CONFIG_VAR( variableName, variableType, targetVariable, configFileObject, sectionNameStr)
#define MRPT_DAQmx_ErrChk(functionCall)
#define MRPT_DAQmxCreateDIChan
#define MRPT_DAQmxClearTask
#define MRPT_DAQmxReadAnalogF64
#define MRPT_DAQmxWriteAnalogF64
This class allows loading and storing values and vectors of different types from a configuration text...
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
uint64_t read_uint64_t(const std::string §ion, const std::string &name, uint64_t defaultValue, bool failIfNotFound=false) const
void appendObservations(const std::vector< mrpt::serialization::CSerializable::Ptr > &obj)
This method must be called by derived classes to enqueue a new observation in the list to be returned...
std::string m_sensorLabel
See CGenericSensor.
An interface to read from data acquisition boards compatible with National Instruments "DAQmx Base" o...
void stop()
Stop the grabbing threads for DAQ tasks.
virtual void initialize()
Setup and launch the DAQ tasks, in parallel threads.
std::list< TInfoPerTask > m_running_tasks
std::vector< mrpt::obs::CObservationRawDAQ::Ptr > m_nextObservations
A buffer for doProcess.
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
void writeAnalogOutputTask(size_t task_index, size_t nSamplesPerChannel, const double *volt_values, double timeout, bool groupedByChannel)
Set voltage outputs to all the outputs in an AOUT task For the meaning of parameters,...
bool checkDAQIsWorking() const
Returns true if initialize() was called and at least one task is running.
void readFromDAQ(std::vector< mrpt::obs::CObservationRawDAQ::Ptr > &outObservations, bool &hardwareError)
Receives data from the DAQ thread(s).
void writeDigitalOutputTask(size_t task_index, bool line_value, double timeout)
Changes the boolean state of one digital output line.
virtual ~CNationalInstrumentsDAQ()
Destructor.
std::vector< TaskDescription > task_definitions
Publicly accessible vector with the list of tasks to be launched upon call to CNationalInstrumentsDAQ...
void grabbing_thread(TInfoPerTask &ipt)
Method to be executed in each parallel thread.
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)
CNationalInstrumentsDAQ()
Constructor.
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp.
Store raw data from a Data Acquisition (DAQ) device, such that input or output analog and digital cha...
std::vector< double > CNTRIN_double
Readings from ticks counters, such as quadrature encoders.
uint16_t AIN_channel_count
Readings from analog input (ADCs) channels (vector length=channel count) in Volts.
double sample_rate
Readings from ticks counters, such as quadrature encoders.
bool AIN_interleaved
Whether the channels are interleaved (A0 A1 A2 A0 A1 A2...) or not (A0 A0 A0 A1 A1 A1 A2 A2 A2....
std::vector< double > AIN_double
Readings from analog input (ADCs) channels (vector length=channel count) in Volts.
std::vector< uint8_t > DIN
Present output values for 16-bit analog output (DACs) channels (vector length=channel count) in volts...
std::shared_ptr< CObservationRawDAQ > Ptr
Versatile class for consistent logging and management of output messages.
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
#define ASSERT_EQUAL_(__A, __B)
Assert comparing two values, reporting their actual values upon failure.
#define ASSERT_ABOVE_(__A, __B)
#define ASSERT_(f)
Defines an assertion mechanism.
#define THROW_EXCEPTION(msg)
#define ASSERTMSG_(f, __ERROR_MSG)
Defines an assertion mechanism.
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
GLsizei const GLchar ** string
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
std::string trim(const std::string &str)
Removes leading and trailing spaces.
bool strCmpI(const std::string &s1, const std::string &s2)
Return true if the two strings are equal (case insensitive)
void tokenize(const std::string &inString, const std::string &inDelimiters, OUT_CONTAINER &outTokens, bool skipBlankTokens=true) noexcept
Tokenizes a string according to a set of delimiting characters.
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Contains classes for various device interfaces.
This namespace contains representation of robot actions and observations.
CArchiveStreamBase< STREAM > archiveFrom(STREAM &s)
Helper function to create a templatized wrapper CArchive object for a: MRPT's CStream,...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
unsigned __int32 uint32_t
unsigned __int64 uint64_t
std::atomic< int > new_obs_available
std::unique_ptr< mrpt::io::CPipeWriteEndPoint > write_pipe
TaskDescription task
A copy of the original task description that generated this thread.
std::unique_ptr< mrpt::io::CPipeReadEndPoint > read_pipe
std::string physicalChannel
std::string terminalConfig
unsigned int physicalChannelCount
IMPORTANT This must be the total number of channels listed in "physicalChannel" (e....
unsigned int physicalChannelCount
IMPORTANT This must be the total number of channels listed in "physicalChannel" (e....
std::string physicalChannel
std::string countDirection
std::string line
The digital line (for example "Dev1/port0/line1")
std::string line
The digital line (for example "Dev1/port0/line1")
Each of the tasks to create in CNationalInstrumentsDAQ::initialize().
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_count_edges_t ci_count_edges
Counter: period of a digital signal.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_co_pulses_t co_pulses
Output counter: digital pulses output.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_pulse_width_t ci_pulse_width
Counter: measure the width of a digital pulse.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ai_t ai
Analog inputs.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_lin_encoder_t ci_lin_encoder
Counter: uses a linear encoder to measure linear position.
double samplesPerSecond
Sample clock config: samples per second.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ao_t ao
Analog outputs.
uint32_t samplesPerChannelToRead
(Default=1000) The number of samples to grab at once from each channel.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_ang_encoder_t ci_ang_encoder
Counter: uses an angular encoder to measure angular position.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_di_t di
Digital inputs (di)
uint32_t bufferSamplesPerChannel
(Default=0) From NI's docs: The number of samples the buffer can hold for each channel in the task.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_period_t ci_period
Counter: period of a digital signal.
std::string sampleClkSource
Sample clock source: may be empty (default value) for some channels.
std::string taskLabel
(Default="task###")
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_do_t douts
Digital outs (do)