16 #define MRPT_HAS_SOME_NIDAQMX (MRPT_HAS_NIDAQMXBASE || MRPT_HAS_NIDAQMX)
18 #define MRPT_USE_NIDAQMXBASE (MRPT_HAS_NIDAQMXBASE && !MRPT_HAS_NIDAQMX)
19 #define MRPT_USE_NIDAQMX (MRPT_HAS_NIDAQMX)
21 #if MRPT_USE_NIDAQMXBASE
22 #include "NIDAQmxBase.h"
30 #if MRPT_USE_NIDAQMXBASE
31 #define MRPT_DAQmxGetExtendedErrorInfo DAQmxBaseGetExtendedErrorInfo
32 #define MRPT_DAQmxCreateTask DAQmxBaseCreateTask
33 #define MRPT_DAQmxCreateAIVoltageChan DAQmxBaseCreateAIVoltageChan
34 #define MRPT_DAQmxCreateAOVoltageChan DAQmxBaseCreateAOVoltageChan
35 #define MRPT_DAQmxCreateDIChan DAQmxBaseCreateDIChan
36 #define MRPT_DAQmxCreateDOChan DAQmxBaseCreateDOChan
37 #define MRPT_DAQmxCreateCIPeriodChan DAQmxBaseCreateCIPeriodChan
38 #define MRPT_DAQmxCreateCICountEdgesChan DAQmxBaseCreateCICountEdgesChan
39 #define MRPT_DAQmxCreateCIPulseWidthChan DAQmxBaseCreateCIPulseWidthChan
40 #define MRPT_DAQmxCreateCILinEncoderChan DAQmxBaseCreateCILinEncoderChan
41 #define MRPT_DAQmxCreateCIAngEncoderChan DAQmxBaseCreateCIAngEncoderChan
42 #define MRPT_DAQmxCreateCOPulseChanFreq DAQmxBaseCreateCOPulseChanFreq
43 #define MRPT_DAQmxCfgSampClkTiming DAQmxBaseCfgSampClkTiming
44 #define MRPT_DAQmxCfgInputBuffer DAQmxBaseCfgInputBuffer
45 #define MRPT_DAQmxCfgOutputBuffer DAQmxBaseCfgOutputBuffer
46 #define MRPT_DAQmxStartTask DAQmxBaseStartTask
47 #define MRPT_DAQmxStopTask DAQmxBaseStopTask
48 #define MRPT_DAQmxClearTask DAQmxBaseClearTask
49 #define MRPT_DAQmxReadAnalogF64 DAQmxBaseReadAnalogF64
50 #define MRPT_DAQmxReadCounterF64 DAQmxBaseReadCounterF64
51 #define MRPT_DAQmxReadDigitalU8 DAQmxBaseReadDigitalU8
52 #define MRPT_DAQmxWriteAnalogF64 DAQmxBaseWriteAnalogF64
53 #define MRPT_DAQmxWriteDigitalU32 DAQmxBaseWriteDigitalU32
54 #define MRPT_DAQmxWriteDigitalLines DAQmxBaseWriteDigitalLines
56 #define MRPT_DAQmxGetExtendedErrorInfo DAQmxGetExtendedErrorInfo
57 #define MRPT_DAQmxCreateTask DAQmxCreateTask
58 #define MRPT_DAQmxCreateAIVoltageChan DAQmxCreateAIVoltageChan
59 #define MRPT_DAQmxCreateAOVoltageChan DAQmxCreateAOVoltageChan
60 #define MRPT_DAQmxCreateDIChan DAQmxCreateDIChan
61 #define MRPT_DAQmxCreateDOChan DAQmxCreateDOChan
62 #define MRPT_DAQmxCreateCIPeriodChan DAQmxCreateCIPeriodChan
63 #define MRPT_DAQmxCreateCICountEdgesChan DAQmxCreateCICountEdgesChan
64 #define MRPT_DAQmxCreateCIPulseWidthChan DAQmxCreateCIPulseWidthChan
65 #define MRPT_DAQmxCreateCILinEncoderChan DAQmxCreateCILinEncoderChan
66 #define MRPT_DAQmxCreateCIAngEncoderChan DAQmxCreateCIAngEncoderChan
67 #define MRPT_DAQmxCreateCOPulseChanFreq DAQmxCreateCOPulseChanFreq
68 #define MRPT_DAQmxCfgSampClkTiming DAQmxCfgSampClkTiming
69 #define MRPT_DAQmxCfgInputBuffer DAQmxCfgInputBuffer
70 #define MRPT_DAQmxCfgOutputBuffer DAQmxCfgOutputBuffer
71 #define MRPT_DAQmxStartTask DAQmxStartTask
72 #define MRPT_DAQmxStopTask DAQmxStopTask
73 #define MRPT_DAQmxClearTask DAQmxClearTask
74 #define MRPT_DAQmxReadAnalogF64 DAQmxReadAnalogF64
75 #define MRPT_DAQmxReadCounterF64 DAQmxReadCounterF64
76 #define MRPT_DAQmxReadDigitalU8 DAQmxReadDigitalU8
77 #define MRPT_DAQmxWriteAnalogF64 DAQmxWriteAnalogF64
78 #define MRPT_DAQmxWriteDigitalU32 DAQmxWriteDigitalU32
79 #define MRPT_DAQmxWriteDigitalLines DAQmxWriteDigitalLines
84 #define MRPT_DAQmx_ErrChk(functionCall) \
85 if ((functionCall) < 0) \
88 MRPT_DAQmxGetExtendedErrorInfo(errBuff, 2048); \
89 std::string sErr = mrpt::format( \
90 "DAQ error: '%s'\nCalling: '%s'", errBuff, #functionCall); \
91 THROW_EXCEPTION(sErr) \
107 new_obs_available(0),
116 :
mrpt::utils::COutputLogger(
"CNationalInstrumentsDAQ")
122 #define MY_LOAD_HERE_CONFIG_VAR( \
123 variableName, variableType, targetVariable, configFileObject, \
125 targetVariable = configFileObject.read_##variableType( \
126 sectionNameStr, variableName, targetVariable, false);
128 #define MY_LOAD_HERE_CONFIG_VAR_NO_DEFAULT( \
129 variableName, variableType, targetVariable, configFileObject, \
134 targetVariable = configFileObject.read_##variableType( \
135 sectionNameStr, variableName, targetVariable, true); \
137 catch (std::exception&) \
141 "Value for '%s' not found in config file", \
142 std::string(variableName).c_str())); \
155 const unsigned int nTasks = cfg.
read_uint64_t(sect,
"num_tasks", 0,
true);
158 std::cerr <<
"[CNationalInstrumentsDAQ] Warning: Number of tasks is "
159 "zero. No datalogging will be done.\n";
163 for (
unsigned int i = 0; i < nTasks; i++)
170 const string sChanns =
171 cfg.
read_string(sect, sTask +
string(
".channels"),
"",
true);
172 vector<string> lstStrChanns;
174 if (lstStrChanns.empty())
178 sTask +
string(
".samplesPerSecond"),
double,
t.samplesPerSecond,
181 sTask +
string(
".samplesPerChannelToRead"),
double,
182 t.samplesPerChannelToRead, cfg, sect)
184 sTask +
string(
".sampleClkSource"),
string,
t.sampleClkSource, cfg,
187 sTask +
string(
".bufferSamplesPerChannel"),
double,
188 t.bufferSamplesPerChannel, cfg, sect)
190 cfg.
read_string(sect, sTask +
string(
".taskLabel"), sTask,
false);
192 for (
size_t j = 0; j < lstStrChanns.size(); j++)
194 if (
strCmpI(lstStrChanns[j],
"ai"))
198 sTask +
string(
".ai.physicalChannel"),
string,
199 t.ai.physicalChannel, cfg, sect)
201 sTask +
string(
".ai.physicalChannelCount"),
uint64_t,
202 t.ai.physicalChannelCount, cfg, sect)
204 sTask +
string(
".ai.terminalConfig"),
string,
205 t.ai.terminalConfig, cfg, sect)
207 sTask +
string(
".ai.minVal"),
double,
t.ai.minVal, cfg,
210 sTask +
string(
".ai.maxVal"),
double,
t.ai.maxVal, cfg,
213 else if (
strCmpI(lstStrChanns[j],
"ao"))
217 sTask +
string(
".ao.physicalChannel"),
string,
218 t.ao.physicalChannel, cfg, sect)
220 sTask +
string(
".ao.physicalChannelCount"),
uint64_t,
221 t.ao.physicalChannelCount, cfg, sect)
223 sTask +
string(
".ao.minVal"),
double,
t.ao.minVal, cfg,
226 sTask +
string(
".ao.maxVal"),
double,
t.ao.maxVal, cfg,
229 else if (
strCmpI(lstStrChanns[j],
"di"))
233 sTask +
string(
".di.line"),
string,
t.di.line, cfg, sect)
235 else if (
strCmpI(lstStrChanns[j],
"do"))
239 sTask +
string(
".do.line"),
string,
t.douts.line, cfg, sect)
241 else if (
strCmpI(lstStrChanns[j],
"ci_period"))
243 t.has_ci_period =
true;
245 sTask +
string(
".ci_period.counter"),
string,
246 t.ci_period.counter, cfg, sect)
248 sTask +
string(
".ci_period.minVal"),
double,
249 t.ci_period.minVal, cfg, sect)
251 sTask +
string(
".ci_period.maxVal"),
double,
252 t.ci_period.maxVal, cfg, sect)
254 sTask +
string(
".ci_period.units"),
string,
255 t.ci_period.units, cfg, sect)
257 sTask +
string(
".ci_period.edge"),
string,
t.ci_period.edge,
260 sTask +
string(
".ci_period.measTime"),
double,
261 t.ci_period.measTime, cfg, sect)
263 sTask +
string(
".ci_period.divisor"),
int,
264 t.ci_period.divisor, cfg, sect)
266 else if (
strCmpI(lstStrChanns[j],
"ci_count_edges"))
268 t.has_ci_count_edges =
true;
270 sTask +
string(
".ci_count_edges.counter"),
string,
271 t.ci_count_edges.counter, cfg, sect)
273 sTask +
string(
".ci_count_edges.edge"),
string,
274 t.ci_count_edges.edge, cfg, sect)
276 sTask +
string(
".ci_count_edges.initialCount"),
int,
277 t.ci_count_edges.initialCount, cfg, sect)
279 sTask +
string(
".ci_count_edges.countDirection"),
string,
280 t.ci_count_edges.countDirection, cfg, sect)
282 else if (
strCmpI(lstStrChanns[j],
"ci_pulse_width"))
284 t.has_ci_pulse_width =
true;
286 sTask +
string(
".ci_pulse_width.counter"),
string,
287 t.ci_pulse_width.counter, cfg, sect)
289 sTask +
string(
".ci_pulse_width.minVal"),
double,
290 t.ci_pulse_width.minVal, cfg, sect)
292 sTask +
string(
".ci_pulse_width.maxVal"),
double,
293 t.ci_pulse_width.maxVal, cfg, sect)
295 sTask +
string(
".ci_pulse_width.units"),
string,
296 t.ci_pulse_width.units, cfg, sect)
298 sTask +
string(
".ci_pulse_width.startingEdge"),
string,
299 t.ci_pulse_width.startingEdge, cfg, sect)
301 else if (
strCmpI(lstStrChanns[j],
"ci_lin_encoder"))
303 t.has_ci_lin_encoder =
true;
305 sTask +
string(
".ci_lin_encoder.counter"),
string,
306 t.ci_lin_encoder.counter, cfg, sect)
308 sTask +
string(
".ci_lin_encoder.decodingType"),
string,
309 t.ci_lin_encoder.decodingType, cfg, sect)
311 sTask +
string(
".ci_lin_encoder.ZidxEnable"),
bool,
312 t.ci_lin_encoder.ZidxEnable, cfg, sect)
314 sTask +
string(
".ci_lin_encoder.ZidxVal"),
double,
315 t.ci_lin_encoder.ZidxVal, cfg, sect)
317 sTask +
string(
".ci_lin_encoder.ZidxPhase"),
string,
318 t.ci_lin_encoder.ZidxPhase, cfg, sect)
320 sTask +
string(
".ci_lin_encoder.units"),
string,
321 t.ci_lin_encoder.units, cfg, sect)
323 sTask +
string(
".ci_lin_encoder.distPerPulse"),
double,
324 t.ci_lin_encoder.distPerPulse, cfg, sect)
326 sTask +
string(
".ci_lin_encoder.initialPos"),
double,
327 t.ci_lin_encoder.initialPos, cfg, sect)
329 else if (
strCmpI(lstStrChanns[j],
"ci_ang_encoder"))
331 t.has_ci_ang_encoder =
true;
333 sTask +
string(
".ci_ang_encoder.counter"),
string,
334 t.ci_ang_encoder.counter, cfg, sect)
336 sTask +
string(
".ci_ang_encoder.decodingType"),
string,
337 t.ci_ang_encoder.decodingType, cfg, sect)
339 sTask +
string(
".ci_ang_encoder.ZidxEnable"),
bool,
340 t.ci_ang_encoder.ZidxEnable, cfg, sect)
342 sTask +
string(
".ci_ang_encoder.ZidxVal"),
double,
343 t.ci_ang_encoder.ZidxVal, cfg, sect)
345 sTask +
string(
".ci_ang_encoder.ZidxPhase"),
string,
346 t.ci_ang_encoder.ZidxPhase, cfg, sect)
348 sTask +
string(
".ci_ang_encoder.units"),
string,
349 t.ci_ang_encoder.units, cfg, sect)
351 sTask +
string(
".ci_ang_encoder.pulsesPerRev"),
int,
352 t.ci_ang_encoder.pulsesPerRev, cfg, sect)
354 sTask +
string(
".ci_ang_encoder.initialAngle"),
double,
355 t.ci_ang_encoder.initialAngle, cfg, sect)
357 sTask +
string(
".ci_ang_encoder.decimate"),
int,
358 t.ci_ang_encoder.decimate, cfg, sect)
360 else if (
strCmpI(lstStrChanns[j],
"co_pulses"))
362 t.has_co_pulses =
true;
364 sTask +
string(
".co_pulses.counter"),
string,
365 t.co_pulses.counter, cfg, sect)
367 sTask +
string(
".co_pulses.idleState"),
string,
368 t.co_pulses.idleState, cfg, sect)
370 sTask +
string(
".co_pulses.initialDelay"),
double,
371 t.co_pulses.initialDelay, cfg, sect)
373 sTask +
string(
".co_pulses.freq"),
double,
t.co_pulses.freq,
376 sTask +
string(
".co_pulses.dutyCycle"),
double,
377 t.co_pulses.dutyCycle, cfg, sect)
382 "Unknown channel type '%s'! See the docs of "
383 "CNationalInstrumentsDAQ",
384 lstStrChanns[j].c_str())
394 #if MRPT_HAS_SOME_NIDAQMX
402 const daqmx_str_val daqmx_vals[] = {
403 {
"DAQmx_Val_Cfg_Default", DAQmx_Val_Cfg_Default},
404 {
"DAQmx_Val_RSE", DAQmx_Val_RSE},
405 {
"DAQmx_Val_NRSE", DAQmx_Val_NRSE},
406 {
"DAQmx_Val_Diff", DAQmx_Val_Diff},
407 {
"DAQmx_Val_Seconds", DAQmx_Val_Seconds},
408 {
"DAQmx_Val_Rising", DAQmx_Val_Rising},
409 {
"DAQmx_Val_Falling", DAQmx_Val_Falling},
410 {
"DAQmx_Val_CountUp", DAQmx_Val_CountUp},
411 {
"DAQmx_Val_CountDown", DAQmx_Val_CountDown},
412 {
"DAQmx_Val_ExtControlled", DAQmx_Val_ExtControlled},
413 {
"DAQmx_Val_AHighBHigh", DAQmx_Val_AHighBHigh},
414 {
"DAQmx_Val_AHighBLow", DAQmx_Val_AHighBLow},
415 {
"DAQmx_Val_ALowBHigh", DAQmx_Val_ALowBHigh},
416 {
"DAQmx_Val_ALowBLow", DAQmx_Val_ALowBLow},
417 {
"DAQmx_Val_X1", DAQmx_Val_X1},
418 {
"DAQmx_Val_X2", DAQmx_Val_X2},
419 {
"DAQmx_Val_X4", DAQmx_Val_X4},
420 {
"DAQmx_Val_Meters", DAQmx_Val_Meters},
421 {
"DAQmx_Val_Inches", DAQmx_Val_Inches},
422 {
"DAQmx_Val_Ticks", DAQmx_Val_Ticks},
423 {
"DAQmx_Val_Degrees", DAQmx_Val_Degrees},
424 {
"DAQmx_Val_Radians", DAQmx_Val_Radians},
425 {
"DAQmx_Val_High", DAQmx_Val_High},
426 {
"DAQmx_Val_Low", DAQmx_Val_Low}};
432 for (
unsigned int i = 0; i <
sizeof(daqmx_vals) /
sizeof(daqmx_vals[0]);
435 if (
strCmpI(daqmx_vals[i].str,
s.c_str()))
return daqmx_vals[i].
val;
446 #if MRPT_HAS_SOME_NIDAQMX
461 TaskHandle& taskHandle =
462 *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
470 "ai.physicalChannelCount is zero! Please, define it "
477 tf.
ai.
maxVal, DAQmx_Val_Volts,
nullptr));
483 "ai.physicalChannelCount is zero! Please, define it "
495 taskHandle, tf.
di.
line.c_str(),
nullptr,
496 DAQmx_Val_ChanPerLine));
502 taskHandle, tf.
douts.
line.c_str(),
nullptr,
503 DAQmx_Val_ChanPerLine));
608 ipt.
read_pipe->timeout_read_start_us = 100000;
609 ipt.
read_pipe->timeout_read_between_us = 100000;
616 catch (std::exception
const& e)
618 std::cerr <<
"[CNationalInstrumentsDAQ] Error:" << std::endl
619 << e.what() << std::endl;
622 TaskHandle& taskHandle =
623 *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
632 cerr <<
"[CNationalInstrumentsDAQ::initialize] Waiting for the "
633 "grabbing thread to end due to exception...\n";
635 cerr <<
"[CNationalInstrumentsDAQ::initialize] Grabbing thread "
642 std::cerr <<
"[CNationalInstrumentsDAQ] Error while creating "
643 "tasks. Closing other tasks before returning...\n";
645 std::cerr <<
"[CNationalInstrumentsDAQ] Closing tasks done.\n";
664 it->must_close =
true;
667 cout <<
"[CNationalInstrumentsDAQ::stop] Waiting for grabbing threads "
673 if (it->hThread.joinable()) it->hThread.join();
680 cout <<
"[CNationalInstrumentsDAQ::stop] All threads ended.\n";
683 #if MRPT_HAS_SOME_NIDAQMX
687 TaskHandle& taskHandle =
688 *
reinterpret_cast<TaskHandle*
>(&it->taskHandle);
692 taskHandle =
nullptr;
707 std::vector<mrpt::obs::CObservationRawDAQ::Ptr>& outObservations,
710 hardwareError =
false;
711 outObservations.clear();
715 hardwareError =
true;
728 if (it->new_obs_available != 0)
730 it->read_pipe->ReadObject(&tmp_obs);
731 --(it->new_obs_available);
734 outObservations.push_back(
763 std::vector<mrpt::utils::CSerializable::Ptr> new_obs;
778 #if MRPT_HAS_SOME_NIDAQMX
781 TaskHandle& taskHandle =
782 *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
784 cout <<
"[CNationalInstrumentsDAQ::grabbing_thread] Starting "
791 const float timeout =
796 vector<uint8_t> u8Buf;
810 bool there_are_data =
false;
822 dBuf.resize(totalSamplesToRead);
823 int32 pointsReadPerChan = -1;
827 : DAQmx_Val_GroupByChannel,
828 &dBuf[0], dBuf.size(), &pointsReadPerChan,
nullptr)) <
830 err != DAQmxErrorSamplesNotYetAvailable)
834 else if (pointsReadPerChan > 0)
840 there_are_data =
true;
842 cout <<
"[CNationalInstrumentsDAQ::grabbing_thread] "
843 << pointsReadPerChan <<
" analog samples read.\n";
850 u8Buf.resize(totalSamplesToRead);
852 int32 pointsReadPerChan = -1;
855 DAQmx_Val_GroupByChannel, &u8Buf[0], u8Buf.size(),
856 &pointsReadPerChan,
nullptr)) < 0 &&
857 err != DAQmxErrorSamplesNotYetAvailable)
861 else if (pointsReadPerChan > 0)
867 there_are_data =
true;
869 cout <<
"[CNationalInstrumentsDAQ::grabbing_thread] "
870 << pointsReadPerChan <<
" digital samples read.\n";
875 const int32 totalSamplesToRead =
877 dBuf.resize(totalSamplesToRead);
878 int32 pointsReadPerChan = -1;
880 taskHandle, totalSamplesToRead, timeout, &dBuf[0],
881 dBuf.size(), &pointsReadPerChan,
nullptr)) < 0 &&
882 err != DAQmxErrorSamplesNotYetAvailable)
886 else if (pointsReadPerChan > 0)
897 there_are_data =
true;
900 static int decim = 0;
902 cout <<
"[CNationalInstrumentsDAQ::grabbing_"
905 <<
" counter samples read ([0]="
907 if (++decim > 100) decim = 0;
923 std::this_thread::sleep_for(1ms);
928 catch (std::exception& e)
930 std::cerr <<
"[CNationalInstrumentsDAQ::grabbing_thread] Exception:\n"
931 << e.what() << std::endl;
939 size_t task_index,
size_t nSamplesPerChannel,
const double* volt_values,
940 double timeout,
bool groupedByChannel)
942 #if MRPT_HAS_SOME_NIDAQMX
946 std::advance(it, task_index);
948 TaskHandle& taskHandle = *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
950 int32 samplesWritten = 0;
953 taskHandle, nSamplesPerChannel,
FALSE, timeout,
954 groupedByChannel ? DAQmx_Val_GroupByChannel
955 : DAQmx_Val_GroupByScanNumber,
956 const_cast<float64*
>(volt_values), &samplesWritten,
nullptr))
970 size_t task_index,
bool line_value,
double timeout)
972 #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
void appendObservations(const std::vector< mrpt::utils::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
void loadConfig_sensorSpecific(const mrpt::utils::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
std::vector< mrpt::obs::CObservationRawDAQ::Ptr > m_nextObservations
A buffer for doProcess.
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
static void createPipe(ReadPtr &outReadPipe, WritePtr &outWritePipe)
Creates a new pipe and returns the read & write end-points as newly allocated objects.
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
GLsizei const GLchar ** string
void tokenize(const std::string &inString, const std::string &inDelimiters, std::deque< std::string > &outTokens, bool skipBlankTokens=true) noexcept
Tokenizes a string according to a set of delimiting characters.
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)
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
#define ASSERT_EQUAL_(__A, __B)
#define ASSERT_ABOVE_(__A, __B)
#define THROW_EXCEPTION(msg)
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
#define ASSERTMSG_(f, __ERROR_MSG)
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
Contains classes for various device interfaces.
This namespace contains representation of robot actions and observations.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation,...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
unsigned __int32 uint32_t
unsigned __int64 uint64_t
std::unique_ptr< mrpt::synch::CPipeReadEndPoint > read_pipe
std::atomic< int > new_obs_available
TaskDescription task
A copy of the original task description that generated this thread.
std::unique_ptr< mrpt::synch::CPipeWriteEndPoint > write_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)