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;
935 #endif // MRPT_HAS_SOME_NIDAQMX 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)
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().
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_ang_encoder_t ci_ang_encoder
Counter: uses an angular encoder to measure angular position.
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
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")
#define THROW_EXCEPTION(msg)
#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 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###")
#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
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.
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
struct mrpt::hwdrivers::CNationalInstrumentsDAQ::TaskDescription::desc_ci_count_edges_t ci_count_edges
Counter: period of a digital signal.
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
#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.
#define MRPT_DAQmxCfgInputBuffer
Versatile class for consistent logging and management of output messages.
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
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.
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
#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...
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 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)
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
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.
#define ASSERT_ABOVE_(__A, __B)
std::unique_ptr< mrpt::io::CPipeWriteEndPoint > write_pipe
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.
#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
#define MRPT_DAQmxCreateCICountEdgesChan
#define MRPT_DAQmxCreateTask
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.