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); \ 106 : new_obs_available(0), task()
120 #define MY_LOAD_HERE_CONFIG_VAR( \ 121 variableName, variableType, targetVariable, configFileObject, \ 123 targetVariable = configFileObject.read_##variableType( \ 124 sectionNameStr, variableName, targetVariable, false); 126 #define MY_LOAD_HERE_CONFIG_VAR_NO_DEFAULT( \ 127 variableName, variableType, targetVariable, configFileObject, \ 132 targetVariable = configFileObject.read_##variableType( \ 133 sectionNameStr, variableName, targetVariable, true); \ 135 catch (std::exception&) \ 137 THROW_EXCEPTION(format( \ 138 "Value for '%s' not found in config file", \ 139 std::string(variableName).c_str())); \ 152 const unsigned int nTasks = cfg.
read_uint64_t(sect,
"num_tasks", 0,
true);
155 std::cerr <<
"[CNationalInstrumentsDAQ] Warning: Number of tasks is " 156 "zero. No datalogging will be done.\n";
160 for (
unsigned int i = 0; i < nTasks; i++)
167 const string sChanns =
168 cfg.
read_string(sect, sTask +
string(
".channels"),
"",
true);
169 vector<string> lstStrChanns;
171 if (lstStrChanns.empty())
175 sTask +
string(
".samplesPerSecond"),
double,
t.samplesPerSecond,
178 sTask +
string(
".samplesPerChannelToRead"),
double,
179 t.samplesPerChannelToRead, cfg, sect)
181 sTask +
string(
".sampleClkSource"),
string,
t.sampleClkSource, cfg,
184 sTask +
string(
".bufferSamplesPerChannel"),
double,
185 t.bufferSamplesPerChannel, cfg, sect)
187 cfg.
read_string(sect, sTask +
string(
".taskLabel"), sTask,
false);
189 for (
auto& lstStrChann : lstStrChanns)
191 if (
strCmpI(lstStrChann,
"ai"))
195 sTask +
string(
".ai.physicalChannel"),
string,
196 t.ai.physicalChannel, cfg, sect)
198 sTask +
string(
".ai.physicalChannelCount"),
uint64_t,
199 t.ai.physicalChannelCount, cfg, sect)
201 sTask +
string(
".ai.terminalConfig"),
string,
202 t.ai.terminalConfig, cfg, sect)
204 sTask +
string(
".ai.minVal"),
double,
t.ai.minVal, cfg,
207 sTask +
string(
".ai.maxVal"),
double,
t.ai.maxVal, cfg,
210 else if (
strCmpI(lstStrChann,
"ao"))
214 sTask +
string(
".ao.physicalChannel"),
string,
215 t.ao.physicalChannel, cfg, sect)
217 sTask +
string(
".ao.physicalChannelCount"),
uint64_t,
218 t.ao.physicalChannelCount, cfg, sect)
220 sTask +
string(
".ao.minVal"),
double,
t.ao.minVal, cfg,
223 sTask +
string(
".ao.maxVal"),
double,
t.ao.maxVal, cfg,
226 else if (
strCmpI(lstStrChann,
"di"))
230 sTask +
string(
".di.line"),
string,
t.di.line, cfg, sect)
232 else if (
strCmpI(lstStrChann,
"do"))
236 sTask +
string(
".do.line"),
string,
t.douts.line, cfg, sect)
238 else if (
strCmpI(lstStrChann,
"ci_period"))
240 t.has_ci_period =
true;
242 sTask +
string(
".ci_period.counter"),
string,
243 t.ci_period.counter, cfg, sect)
245 sTask +
string(
".ci_period.minVal"),
double,
246 t.ci_period.minVal, cfg, sect)
248 sTask +
string(
".ci_period.maxVal"),
double,
249 t.ci_period.maxVal, cfg, sect)
251 sTask +
string(
".ci_period.units"),
string,
252 t.ci_period.units, cfg, sect)
254 sTask +
string(
".ci_period.edge"),
string,
t.ci_period.edge,
257 sTask +
string(
".ci_period.measTime"),
double,
258 t.ci_period.measTime, cfg, sect)
260 sTask +
string(
".ci_period.divisor"),
int,
261 t.ci_period.divisor, cfg, sect)
263 else if (
strCmpI(lstStrChann,
"ci_count_edges"))
265 t.has_ci_count_edges =
true;
267 sTask +
string(
".ci_count_edges.counter"),
string,
268 t.ci_count_edges.counter, cfg, sect)
270 sTask +
string(
".ci_count_edges.edge"),
string,
271 t.ci_count_edges.edge, cfg, sect)
273 sTask +
string(
".ci_count_edges.initialCount"),
int,
274 t.ci_count_edges.initialCount, cfg, sect)
276 sTask +
string(
".ci_count_edges.countDirection"),
string,
277 t.ci_count_edges.countDirection, cfg, sect)
279 else if (
strCmpI(lstStrChann,
"ci_pulse_width"))
281 t.has_ci_pulse_width =
true;
283 sTask +
string(
".ci_pulse_width.counter"),
string,
284 t.ci_pulse_width.counter, cfg, sect)
286 sTask +
string(
".ci_pulse_width.minVal"),
double,
287 t.ci_pulse_width.minVal, cfg, sect)
289 sTask +
string(
".ci_pulse_width.maxVal"),
double,
290 t.ci_pulse_width.maxVal, cfg, sect)
292 sTask +
string(
".ci_pulse_width.units"),
string,
293 t.ci_pulse_width.units, cfg, sect)
295 sTask +
string(
".ci_pulse_width.startingEdge"),
string,
296 t.ci_pulse_width.startingEdge, cfg, sect)
298 else if (
strCmpI(lstStrChann,
"ci_lin_encoder"))
300 t.has_ci_lin_encoder =
true;
302 sTask +
string(
".ci_lin_encoder.counter"),
string,
303 t.ci_lin_encoder.counter, cfg, sect)
305 sTask +
string(
".ci_lin_encoder.decodingType"),
string,
306 t.ci_lin_encoder.decodingType, cfg, sect)
308 sTask +
string(
".ci_lin_encoder.ZidxEnable"),
bool,
309 t.ci_lin_encoder.ZidxEnable, cfg, sect)
311 sTask +
string(
".ci_lin_encoder.ZidxVal"),
double,
312 t.ci_lin_encoder.ZidxVal, cfg, sect)
314 sTask +
string(
".ci_lin_encoder.ZidxPhase"),
string,
315 t.ci_lin_encoder.ZidxPhase, cfg, sect)
317 sTask +
string(
".ci_lin_encoder.units"),
string,
318 t.ci_lin_encoder.units, cfg, sect)
320 sTask +
string(
".ci_lin_encoder.distPerPulse"),
double,
321 t.ci_lin_encoder.distPerPulse, cfg, sect)
323 sTask +
string(
".ci_lin_encoder.initialPos"),
double,
324 t.ci_lin_encoder.initialPos, cfg, sect)
326 else if (
strCmpI(lstStrChann,
"ci_ang_encoder"))
328 t.has_ci_ang_encoder =
true;
330 sTask +
string(
".ci_ang_encoder.counter"),
string,
331 t.ci_ang_encoder.counter, cfg, sect)
333 sTask +
string(
".ci_ang_encoder.decodingType"),
string,
334 t.ci_ang_encoder.decodingType, cfg, sect)
336 sTask +
string(
".ci_ang_encoder.ZidxEnable"),
bool,
337 t.ci_ang_encoder.ZidxEnable, cfg, sect)
339 sTask +
string(
".ci_ang_encoder.ZidxVal"),
double,
340 t.ci_ang_encoder.ZidxVal, cfg, sect)
342 sTask +
string(
".ci_ang_encoder.ZidxPhase"),
string,
343 t.ci_ang_encoder.ZidxPhase, cfg, sect)
345 sTask +
string(
".ci_ang_encoder.units"),
string,
346 t.ci_ang_encoder.units, cfg, sect)
348 sTask +
string(
".ci_ang_encoder.pulsesPerRev"),
int,
349 t.ci_ang_encoder.pulsesPerRev, cfg, sect)
351 sTask +
string(
".ci_ang_encoder.initialAngle"),
double,
352 t.ci_ang_encoder.initialAngle, cfg, sect)
354 sTask +
string(
".ci_ang_encoder.decimate"),
int,
355 t.ci_ang_encoder.decimate, cfg, sect)
357 else if (
strCmpI(lstStrChann,
"co_pulses"))
359 t.has_co_pulses =
true;
361 sTask +
string(
".co_pulses.counter"),
string,
362 t.co_pulses.counter, cfg, sect)
364 sTask +
string(
".co_pulses.idleState"),
string,
365 t.co_pulses.idleState, cfg, sect)
367 sTask +
string(
".co_pulses.initialDelay"),
double,
368 t.co_pulses.initialDelay, cfg, sect)
370 sTask +
string(
".co_pulses.freq"),
double,
t.co_pulses.freq,
373 sTask +
string(
".co_pulses.dutyCycle"),
double,
374 t.co_pulses.dutyCycle, cfg, sect)
379 "Unknown channel type '%s'! See the docs of " 380 "CNationalInstrumentsDAQ",
381 lstStrChann.c_str());
391 #if MRPT_HAS_SOME_NIDAQMX 399 const daqmx_str_val daqmx_vals[] = {
400 {
"DAQmx_Val_Cfg_Default", DAQmx_Val_Cfg_Default},
401 {
"DAQmx_Val_RSE", DAQmx_Val_RSE},
402 {
"DAQmx_Val_NRSE", DAQmx_Val_NRSE},
403 {
"DAQmx_Val_Diff", DAQmx_Val_Diff},
404 {
"DAQmx_Val_Seconds", DAQmx_Val_Seconds},
405 {
"DAQmx_Val_Rising", DAQmx_Val_Rising},
406 {
"DAQmx_Val_Falling", DAQmx_Val_Falling},
407 {
"DAQmx_Val_CountUp", DAQmx_Val_CountUp},
408 {
"DAQmx_Val_CountDown", DAQmx_Val_CountDown},
409 {
"DAQmx_Val_ExtControlled", DAQmx_Val_ExtControlled},
410 {
"DAQmx_Val_AHighBHigh", DAQmx_Val_AHighBHigh},
411 {
"DAQmx_Val_AHighBLow", DAQmx_Val_AHighBLow},
412 {
"DAQmx_Val_ALowBHigh", DAQmx_Val_ALowBHigh},
413 {
"DAQmx_Val_ALowBLow", DAQmx_Val_ALowBLow},
414 {
"DAQmx_Val_X1", DAQmx_Val_X1},
415 {
"DAQmx_Val_X2", DAQmx_Val_X2},
416 {
"DAQmx_Val_X4", DAQmx_Val_X4},
417 {
"DAQmx_Val_Meters", DAQmx_Val_Meters},
418 {
"DAQmx_Val_Inches", DAQmx_Val_Inches},
419 {
"DAQmx_Val_Ticks", DAQmx_Val_Ticks},
420 {
"DAQmx_Val_Degrees", DAQmx_Val_Degrees},
421 {
"DAQmx_Val_Radians", DAQmx_Val_Radians},
422 {
"DAQmx_Val_High", DAQmx_Val_High},
423 {
"DAQmx_Val_Low", DAQmx_Val_Low}};
429 for (
unsigned int i = 0; i <
sizeof(daqmx_vals) /
sizeof(daqmx_vals[0]);
432 if (
strCmpI(daqmx_vals[i].str,
s.c_str()))
return daqmx_vals[i].val;
443 #if MRPT_HAS_SOME_NIDAQMX 458 TaskHandle& taskHandle =
459 *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
467 "ai.physicalChannelCount is zero! Please, define it " 473 tf.
ai.
maxVal, DAQmx_Val_Volts,
nullptr));
479 "ai.physicalChannelCount is zero! Please, define it " 489 taskHandle, tf.
di.
line.c_str(),
nullptr,
490 DAQmx_Val_ChanPerLine));
495 taskHandle, tf.
douts.
line.c_str(),
nullptr,
496 DAQmx_Val_ChanPerLine));
566 DAQmx_Val_Rising, DAQmx_Val_ContSamps,
591 ipt.
read_pipe->timeout_read_start_us = 100000;
592 ipt.
read_pipe->timeout_read_between_us = 100000;
599 catch (std::exception
const& e)
601 std::cerr <<
"[CNationalInstrumentsDAQ] Error:" << std::endl
602 << e.what() << std::endl;
605 TaskHandle& taskHandle =
606 *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
615 cerr <<
"[CNationalInstrumentsDAQ::initialize] Waiting for the " 616 "grabbing thread to end due to exception...\n";
618 cerr <<
"[CNationalInstrumentsDAQ::initialize] Grabbing thread " 625 std::cerr <<
"[CNationalInstrumentsDAQ] Error while creating " 626 "tasks. Closing other tasks before returning...\n";
628 std::cerr <<
"[CNationalInstrumentsDAQ] Closing tasks done.\n";
646 m_running_task.must_close =
true;
649 cout <<
"[CNationalInstrumentsDAQ::stop] Waiting for grabbing threads " 654 if (m_running_task.hThread.joinable()) m_running_task.hThread.join();
661 cout <<
"[CNationalInstrumentsDAQ::stop] All threads ended.\n";
664 #if MRPT_HAS_SOME_NIDAQMX 668 TaskHandle& taskHandle =
669 *
reinterpret_cast<TaskHandle*
>(&it->taskHandle);
673 taskHandle =
nullptr;
688 std::vector<mrpt::obs::CObservationRawDAQ::Ptr>& outObservations,
691 hardwareError =
false;
692 outObservations.clear();
696 hardwareError =
true;
708 if (m_running_task.new_obs_available != 0)
712 arch.ReadObject(&tmp_obs);
713 --(m_running_task.new_obs_available);
716 outObservations.push_back(CObservationRawDAQ::Create(tmp_obs));
744 std::vector<mrpt::serialization::CSerializable::Ptr> new_obs;
759 #if MRPT_HAS_SOME_NIDAQMX 762 TaskHandle& taskHandle =
763 *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
765 cout <<
"[CNationalInstrumentsDAQ::grabbing_thread] Starting " 772 const float timeout =
777 vector<uint8_t> u8Buf;
791 bool there_are_data =
false;
803 dBuf.resize(totalSamplesToRead);
804 int32 pointsReadPerChan = -1;
808 : DAQmx_Val_GroupByChannel,
809 &dBuf[0], dBuf.size(), &pointsReadPerChan,
nullptr)) <
811 err != DAQmxErrorSamplesNotYetAvailable)
815 else if (pointsReadPerChan > 0)
821 there_are_data =
true;
823 cout <<
"[CNationalInstrumentsDAQ::grabbing_thread] " 824 << pointsReadPerChan <<
" analog samples read.\n";
831 u8Buf.resize(totalSamplesToRead);
833 int32 pointsReadPerChan = -1;
836 DAQmx_Val_GroupByChannel, &u8Buf[0], u8Buf.size(),
837 &pointsReadPerChan,
nullptr)) < 0 &&
838 err != DAQmxErrorSamplesNotYetAvailable)
842 else if (pointsReadPerChan > 0)
848 there_are_data =
true;
850 cout <<
"[CNationalInstrumentsDAQ::grabbing_thread] " 851 << pointsReadPerChan <<
" digital samples read.\n";
856 const int32 totalSamplesToRead =
858 dBuf.resize(totalSamplesToRead);
859 int32 pointsReadPerChan = -1;
861 taskHandle, totalSamplesToRead, timeout, &dBuf[0],
862 dBuf.size(), &pointsReadPerChan,
nullptr)) < 0 &&
863 err != DAQmxErrorSamplesNotYetAvailable)
867 else if (pointsReadPerChan > 0)
877 there_are_data =
true;
880 static int decim = 0;
882 cout <<
"[CNationalInstrumentsDAQ::grabbing_" 885 <<
" counter samples read ([0]=" 887 if (++decim > 100) decim = 0;
903 std::this_thread::sleep_for(1ms);
908 catch (
const std::exception& e)
910 std::cerr <<
"[CNationalInstrumentsDAQ::grabbing_thread] Exception:\n" 911 << e.what() << std::endl;
913 #endif // MRPT_HAS_SOME_NIDAQMX 919 size_t task_index,
size_t nSamplesPerChannel,
const double* volt_values,
920 double timeout,
bool groupedByChannel)
922 #if MRPT_HAS_SOME_NIDAQMX 925 std::advance(it, task_index);
927 TaskHandle& taskHandle = *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
929 int32 samplesWritten = 0;
932 taskHandle, nSamplesPerChannel,
FALSE, timeout,
933 groupedByChannel ? DAQmx_Val_GroupByChannel
934 : DAQmx_Val_GroupByScanNumber,
935 const_cast<float64*>(volt_values), &samplesWritten,
nullptr))
949 size_t task_index,
bool line_value,
double timeout)
951 #if MRPT_HAS_SOME_NIDAQMX 954 std::advance(it, task_index);
956 TaskHandle& taskHandle = *
reinterpret_cast<TaskHandle*
>(&ipt.
taskHandle);
958 uInt8 dat = line_value ? 1 : 0;
960 int32 samplesWritten = 0;
961 int32 nSamplesPerChannel = 1;
964 taskHandle, nSamplesPerChannel,
FALSE, timeout,
965 DAQmx_Val_GroupByScanNumber, &dat, &samplesWritten,
nullptr))
uint16_t AIN_channel_count
Readings from analog input (ADCs) channels (vector length=channel count) in Volts.
#define MRPT_DAQmxCreateCILinEncoderChan
double sample_rate
Readings from ticks counters, such as quadrature encoders.
Each of the tasks to create in CNationalInstrumentsDAQ::initialize().
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &iniSection) override
See the class documentation at the top for expected parameters.
#define MRPT_DAQmxCreateDOChan
std::string line
The digital line (for example "Dev1/port0/line1")
#define THROW_EXCEPTION(msg)
#define MRPT_DAQmxCreateCIPulseWidthChan
std::string m_sensorLabel
See CGenericSensor.
#define MRPT_DAQmxStartTask
std::atomic< int > new_obs_available
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_co_pulses_t co_pulses
#define MRPT_DAQmxCreateAOVoltageChan
#define MRPT_DAQmxCreateDIChan
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Contains classes for various device interfaces.
std::string taskLabel
(Default="task###")
void doProcess() override
This method will be invoked at a minimum rate of "process_rate" (Hz)
#define MRPT_DAQmxCreateCIPeriodChan
bool checkDAQIsWorking() const
Returns true if initialize() was called and at least one task is running.
void initialize() override
Setup and launch the DAQ tasks, in parallel threads.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_ang_encoder_t ci_ang_encoder
TaskDescription task
A copy of the original task description that generated this thread.
#define MRPT_DAQmxWriteDigitalLines
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.
#define MRPT_DAQmxReadAnalogF64
CNationalInstrumentsDAQ()
Constructor.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_pulse_width_t ci_pulse_width
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...
CArchiveStreamBase< STREAM > archiveFrom(STREAM &s)
Helper function to create a templatized wrapper CArchive object for a: MRPT's CStream, std::istream, std::ostream, std::stringstream.
std::list< TInfoPerTask > m_running_tasks
#define ASSERT_(f)
Defines an assertion mechanism.
This class allows loading and storing values and vectors of different types from a configuration text...
#define MRPT_DAQmxWriteAnalogF64
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_do_t douts
#define ASSERT_EQUAL_(__A, __B)
Assert comparing two values, reporting their actual values upon failure.
std::string sampleClkSource
Sample clock source: may be empty (default value) for some channels.
#define MRPT_DAQmxCreateCIAngEncoderChan
void writeDigitalOutputTask(size_t task_index, bool line_value, double timeout)
Changes the boolean state of one digital output line.
~CNationalInstrumentsDAQ() override
Destructor.
#define MRPT_DAQmxCfgInputBuffer
Versatile class for consistent logging and management of output messages.
#define MRPT_DAQmxReadCounterF64
This namespace contains representation of robot actions and observations.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_di_t di
std::string countDirection
uint64_t read_uint64_t(const std::string §ion, const std::string &name, uint64_t defaultValue, bool failIfNotFound=false) const
void stop()
Stop the grabbing threads for DAQ tasks.
void grabbing_thread(TInfoPerTask &ipt)
Method to be executed in each parallel thread.
An interface to read from data acquisition boards compatible with National Instruments "DAQmx Base" o...
#define MY_LOAD_HERE_CONFIG_VAR( variableName, variableType, targetVariable, configFileObject, sectionNameStr)
std::string terminalConfig
#define ASSERTMSG_(f, __ERROR_MSG)
Defines an assertion mechanism.
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...
GLsizei const GLchar ** string
#define MRPT_DAQmxStopTask
std::vector< mrpt::obs::CObservationRawDAQ::Ptr > m_nextObservations
A buffer for doProcess.
Store raw data from a Data Acquisition (DAQ) device, such that input or output analog and digital cha...
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
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, refere to NI DAQmx docs for DAQmxBaseWriteAnalogF64()
std::vector< double > CNTRIN_double
Readings from ticks counters, such as quadrature encoders.
uint32_t bufferSamplesPerChannel
(Default=0) From NI's docs: The number of samples the buffer can hold for each channel in the task...
void readFromDAQ(std::vector< mrpt::obs::CObservationRawDAQ::Ptr > &outObservations, bool &hardwareError)
Receives data from the DAQ thread(s).
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_count_edges_t ci_count_edges
std::string line
The digital line (for example "Dev1/port0/line1")
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
unsigned __int64 uint64_t
#define MRPT_DAQmxCreateAIVoltageChan
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::vector< double > AIN_double
Readings from analog input (ADCs) channels (vector length=channel count) in Volts.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_lin_encoder_t ci_lin_encoder
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp.
uint32_t samplesPerChannelToRead
(Default=1000) The number of samples to grab at once from each channel.
std::vector< TaskDescription > task_definitions
Publicly accessible vector with the list of tasks to be launched upon call to CNationalInstrumentsDAQ...
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
unsigned int physicalChannelCount
IMPORTANT This must be the total number of channels listed in "physicalChannel" (e.g.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ai_t ai
#define ASSERT_ABOVE_(__A, __B)
std::unique_ptr< mrpt::io::CPipeWriteEndPoint > write_pipe
#define MRPT_DAQmxCreateCOPulseChanFreq
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_period_t ci_period
Counter: period of a digital signal.
#define MRPT_DAQmx_ErrChk(functionCall)
unsigned int physicalChannelCount
IMPORTANT This must be the total number of channels listed in "physicalChannel" (e.g.
std::string trim(const std::string &str)
Removes leading and trailing spaces.
#define MRPT_DAQmxClearTask
double samplesPerSecond
Sample clock config: samples per second.
std::vector< uint8_t > DIN
Present output values for 16-bit analog output (DACs) channels (vector length=channel count) in volts...
std::unique_ptr< mrpt::io::CPipeReadEndPoint > read_pipe
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
bool strCmpI(const std::string &s1, const std::string &s2)
Return true if the two strings are equal (case insensitive)
unsigned __int32 uint32_t
std::string physicalChannel
#define MY_LOAD_HERE_CONFIG_VAR_NO_DEFAULT( variableName, variableType, targetVariable, configFileObject, sectionNameStr)
std::string physicalChannel
#define MRPT_DAQmxReadDigitalU8
#define MRPT_DAQmxCfgSampClkTiming
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ao_t ao
#define MRPT_DAQmxCreateCICountEdgesChan
#define MRPT_DAQmxCreateTask
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.