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;
933 #endif // MRPT_HAS_SOME_NIDAQMX 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 ASSERT_EQUAL_(__A, __B)
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.
std::shared_ptr< CObservationRawDAQ > Ptr
Each of the tasks to create in CNationalInstrumentsDAQ::initialize().
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_ang_encoder_t ci_ang_encoder
Counter: uses an angular encoder to measure angular position.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
#define ASSERT_ABOVE_(__A, __B)
virtual void initialize()
Setup and launch the DAQ tasks, in parallel threads.
#define MRPT_DAQmxCreateDOChan
std::string line
The digital line (for example "Dev1/port0/line1")
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
#define MRPT_DAQmxCreateCIPulseWidthChan
std::string m_sensorLabel
See CGenericSensor.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_co_pulses_t co_pulses
Output counter: digital pulses output.
#define MRPT_DAQmxStartTask
std::atomic< int > new_obs_available
#define THROW_EXCEPTION(msg)
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
#define MRPT_DAQmxCreateAOVoltageChan
#define MRPT_DAQmxCreateDIChan
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_do_t douts
Digital outs (do)
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Contains classes for various device interfaces.
std::string taskLabel
(Default="task###")
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
#define MRPT_DAQmxCreateCIPeriodChan
bool checkDAQIsWorking() const
Returns true if initialize() was called and at least one task is running.
TaskDescription task
A copy of the original task description that generated this thread.
#define MRPT_DAQmxWriteDigitalLines
#define MRPT_DAQmxReadAnalogF64
CNationalInstrumentsDAQ()
Constructor.
This class allows loading and storing values and vectors of different types from a configuration text...
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_count_edges_t ci_count_edges
Counter: period of a digital signal.
void loadConfig_sensorSpecific(const mrpt::utils::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
std::list< TInfoPerTask > m_running_tasks
#define MRPT_DAQmxWriteAnalogF64
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
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.
#define MRPT_DAQmxCfgInputBuffer
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_di_t di
Digital inputs (di)
#define MRPT_DAQmxReadCounterF64
This namespace contains representation of robot actions and observations.
std::string countDirection
void stop()
Stop the grabbing threads for DAQ tasks.
void grabbing_thread(TInfoPerTask &ipt)
Method to be executed in each parallel thread.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_pulse_width_t ci_pulse_width
Counter: measure the width of a digital pulse.
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
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...
virtual ~CNationalInstrumentsDAQ()
Destructor.
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...
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_lin_encoder_t ci_lin_encoder
Counter: uses a linear encoder to measure linear position.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ai_t ai
Analog inputs.
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.
void readFromDAQ(std::vector< mrpt::obs::CObservationRawDAQ::Ptr > &outObservations, bool &hardwareError)
Receives data from the DAQ thread(s).
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.
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...
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)
std::unique_ptr< mrpt::synch::CPipeWriteEndPoint > write_pipe
unsigned int physicalChannelCount
IMPORTANT This must be the total number of channels listed in "physicalChannel" (e.g.
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ao_t ao
Analog outputs.
#define MRPT_DAQmxCreateCOPulseChanFreq
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_period_t ci_period
Counter: period of a digital signal.
uint64_t read_uint64_t(const std::string §ion, const std::string &name, uint64_t defaultValue, bool failIfNotFound=false) const
#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
std::unique_ptr< mrpt::synch::CPipeReadEndPoint > read_pipe
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...
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 ASSERTMSG_(f, __ERROR_MSG)
#define MY_LOAD_HERE_CONFIG_VAR_NO_DEFAULT( variableName, variableType, targetVariable, configFileObject, sectionNameStr)
std::string physicalChannel
#define MRPT_DAQmxReadDigitalU8
#define MRPT_DAQmxCfgSampClkTiming
#define MRPT_DAQmxCreateCICountEdgesChan
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...
#define MRPT_DAQmxCreateTask
static void createPipe(ReadPtr &outReadPipe, WritePtr &outWritePipe)
Creates a new pipe and returns the read & write end-points as newly allocated objects.