RTXI  3.0.0
The Real-Time eXperiment Interface Reference Manual
system_control.cpp
Go to the documentation of this file.
1 /*
2  The Real-Time eXperiment Interface (RTXI)
3  Copyright (C) 2011 Georgia Institute of Technology, University of Utah,
4  Weill Cornell Medical College
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 
20 // #include <math.h>
21 
22 #include <cmath>
23 #include <memory>
24 
25 #include "system_control.hpp"
26 
27 #include "daq.hpp"
28 #include "debug.hpp"
29 #include "main_window.hpp"
30 #include "rt.hpp"
31 
32 SystemControl::Panel::Panel(QMainWindow* mw, Event::Manager* ev_manager)
33  : Widgets::Panel(std::string(SystemControl::MODULE_NAME), mw, ev_manager)
34  , buttonGroup(new QGroupBox)
35  , deviceList(new QComboBox)
36  , analogChannelList(new QComboBox)
37  , analogRangeList(new QComboBox)
38  , analogDownsampleList(new QComboBox)
39  , analogReferenceList(new QComboBox)
40  , analogSubdeviceList(new QComboBox)
41  , analogUnitPrefixList(new QComboBox)
42  , analogUnitList(new QComboBox)
43  , analogUnitPrefixList2(new QComboBox)
44  , analogGainEdit(new QLineEdit)
45  , analogZeroOffsetEdit(new QLineEdit)
46  , digitalChannelList(new QComboBox)
47  , digitalDirectionList(new QComboBox)
48  , digitalSubdeviceList(new QComboBox)
49  , rateUpdate(false)
50  , freqUnitList(new QComboBox)
51  , periodUnitList(new QComboBox)
52  , freqEdit(new QLineEdit)
53  , periodEdit(new QLineEdit)
54 {
55  setWhatsThis(
56  "<p><b>System Control Panel:</b><br>This control panel allows you to "
57  "configure "
58  "the channels on your DAQ card. RTXI automatically detects the number "
59  "and types "
60  "of channels that are available. You should set the \"Scale\" of the "
61  "channel "
62  "to be the inverse of the gain that is applied to the signal through the "
63  "combination of hardware and software that you are using. To acquire "
64  "data from "
65  "a channel, you must set it to be Active using the toggle button. Any "
66  "parameter "
67  "settings such as the \"Range\" or \"Scale\" must be set by clicking the "
68  "\"Apply\" "
69  "button.<br><br> The \"Thread\" tab allows you to set the period for "
70  "real-time "
71  "execution. You must click \"Apply\" to change this setting and "
72  "propagate it "
73  "to other user modules such as the Data Recorder. Custom user modules "
74  "can "
75  "execute special code when the real-time period is changed using the "
76  "update(PERIOD) "
77  "flag.</p>");
78  // Create main layout
79  auto* layout = new QGridLayout;
80 
81  // Create child widget and layout for device block
82  deviceGroup = new QGroupBox(tr("DAQ Setup"));
83  auto* deviceLayout = new QGridLayout;
84 
85  // Create elements for device block
86  deviceLayout->addWidget(new QLabel(tr("Device:")), 0, 0);
87 
88  deviceLayout->addWidget(deviceList, 0, 1, 1, 5);
89  buildDAQDeviceList();
90  QObject::connect(
91  deviceList, SIGNAL(activated(int)), this, SLOT(updateDevice()));
92 
93  // Frequency box
94  deviceLayout->addWidget(new QLabel(tr("Frequency:")), 1, 0);
95  deviceLayout->addWidget(freqEdit, 1, 1);
96 
98  this->getRTXIEventManager()->postEvent(&get_period_event);
99  auto period = std::any_cast<int64_t>(get_period_event.getParam("period"));
100  freqEdit->setText(
101  std::to_string(RT::OS::SECONDS_TO_NANOSECONDS / period).c_str());
102 
103  QObject::connect(
104  freqEdit, SIGNAL(textEdited(const QString&)), this, SLOT(updatePeriod()));
105  freqUnitList->setFixedWidth(50);
106  freqUnitList->addItem(" Hz", 1);
107  freqUnitList->addItem("kHz", 1000);
108  deviceLayout->addWidget(freqUnitList, 1, 2);
109  QObject::connect(
110  freqUnitList, SIGNAL(activated(int)), this, SLOT(updatePeriod()));
111 
112  // Period box
113  deviceLayout->addWidget(new QLabel(tr("Period:")), 1, 3);
114  deviceLayout->addWidget(periodEdit, 1, 4);
115  QObject::connect(
116  periodEdit, SIGNAL(textEdited(const QString&)), this, SLOT(updateFreq()));
117  deviceLayout->addWidget(periodUnitList, 1, 5);
118  periodUnitList->setFixedWidth(50);
119  periodUnitList->addItem(" s", 1.0);
120  periodUnitList->addItem("ms", 1e-3);
121  periodUnitList->addItem("us", 1e-6);
122  periodUnitList->addItem("ns", 1e-9);
123  QObject::connect(
124  periodUnitList, SIGNAL(activated(int)), this, SLOT(updateFreq()));
125  updatePeriod();
126 
127  // Assign layout to child widget
128  deviceGroup->setLayout(deviceLayout);
129 
130  // Create child widget and layout for Analog block
131  analogGroup = new QGroupBox(tr("Analog Channels"));
132  auto* analogLayout = new QGridLayout;
133 
134  // Create elements for analog block
135  analogLayout->addWidget(new QLabel(tr("Channel:")), 1, 0);
136 
137  analogSubdeviceList->addItem("Input",
138  QVariant::fromValue(DAQ::ChannelType::AI));
139  analogSubdeviceList->addItem("Output",
140  QVariant::fromValue(DAQ::ChannelType::AO));
141  QObject::connect(
142  analogSubdeviceList, SIGNAL(activated(int)), this, SLOT(updateDevice()));
143  analogLayout->addWidget(analogSubdeviceList, 1, 1);
144 
145  QObject::connect(
146  analogChannelList, SIGNAL(activated(int)), this, SLOT(display()));
147  analogLayout->addWidget(analogChannelList, 1, 2);
148 
149  analogActiveButton = new QPushButton("Active");
150  analogActiveButton->setCheckable(true);
151  analogLayout->addWidget(analogActiveButton, 1, 3);
152 
153  analogLayout->addWidget(new QLabel(tr("Range:")), 2, 0, 1, 1);
154  analogLayout->addWidget(analogRangeList, 2, 1, 1, 2);
155  analogRangeList->clear();
156  const std::string formatting = "{:.1f}";
157  std::string range_list_text;
158  DAQ::index_t indx = 0;
159  for (auto range : DAQ::get_default_ranges()) {
160  auto [min, max] = range;
161  range_list_text = fmt::format(formatting, min) + std::string(" to ")
162  + fmt::format(formatting, max);
163  analogRangeList->addItem(QString(range_list_text.c_str()),
164  QVariant::fromValue(indx));
165  indx++;
166  }
167 
168  analogLayout->addWidget(analogReferenceList, 2, 3, 1, 2);
169  analogLayout->addWidget(new QLabel(tr("Scale:")), 3, 0);
170  analogReferenceList->clear();
171  analogReferenceList->addItem(
172  "Ground",
173  QVariant::fromValue(static_cast<DAQ::index_t>(DAQ::Reference::GROUND)));
174  analogReferenceList->addItem(
175  "Common",
176  QVariant::fromValue(static_cast<DAQ::index_t>(DAQ::Reference::COMMON)));
177  analogReferenceList->addItem("Differential",
178  QVariant::fromValue(static_cast<DAQ::index_t>(
180  analogReferenceList->addItem(
181  "Other",
182  QVariant::fromValue(static_cast<DAQ::index_t>(DAQ::Reference::OTHER)));
183 
184  analogGainEdit->setAlignment(Qt::AlignRight);
185  analogLayout->addWidget(analogGainEdit, 3, 1);
186 
187  analogUnitPrefixList->addItem("yotta-", 1e24);
188  analogUnitPrefixList->addItem("zetta-", 1e21);
189  analogUnitPrefixList->addItem("exa-", 1e18);
190  analogUnitPrefixList->addItem("peta-", 1e15);
191  analogUnitPrefixList->addItem("tera-", 1e12);
192  analogUnitPrefixList->addItem("giga-", 1e9);
193  analogUnitPrefixList->addItem("mega-", 1e6);
194  analogUnitPrefixList->addItem("kilo-", 1e3);
195  analogUnitPrefixList->addItem("", 1);
196  analogUnitPrefixList->addItem("milli-", 1e-3);
197  analogUnitPrefixList->addItem("micro-", 1e-6);
198  analogUnitPrefixList->addItem("nano-", 1e-9);
199  analogUnitPrefixList->addItem("pico-", 1e-12);
200  analogUnitPrefixList->addItem("femto-", 1e-15);
201  analogUnitPrefixList->addItem("atto-", 1e-18);
202  analogUnitPrefixList->addItem("zepto-", 1e-21);
203  analogUnitPrefixList->addItem("yocto-", 1e-24);
204  analogLayout->addWidget(analogUnitPrefixList, 3, 2);
205 
206  analogLayout->addWidget(analogUnitList, 3, 3);
207  analogUnitList->clear();
208  DAQ::index_t units_index = 0;
209  for (const auto& units : DAQ::get_default_units()) {
210  analogUnitList->addItem(QString(units.c_str()),
211  QVariant::fromValue(units_index));
212  units_index++;
213  }
214  analogLayout->addWidget(new QLabel(tr(" / Volt")), 3, 4);
215  analogLayout->addWidget(new QLabel(tr("Offset:")), 4, 0);
216  analogZeroOffsetEdit->setText("0");
217  analogZeroOffsetEdit->setAlignment(Qt::AlignRight);
218  analogLayout->addWidget(analogZeroOffsetEdit, 4, 1);
219 
220  // Prefixes for offset
221  analogUnitPrefixList2->addItem("yotta-", 1e24);
222  analogUnitPrefixList2->addItem("zetta-", 1e21);
223  analogUnitPrefixList2->addItem("exa-", 1e18);
224  analogUnitPrefixList2->addItem("peta-", 1e15);
225  analogUnitPrefixList2->addItem("tera-", 1e12);
226  analogUnitPrefixList2->addItem("giga-", 1e9);
227  analogUnitPrefixList2->addItem("mega-", 1e6);
228  analogUnitPrefixList2->addItem("kilo-", 1e3);
229  analogUnitPrefixList2->addItem("", 1);
230  analogUnitPrefixList2->addItem("milli-", 1e-3);
231  analogUnitPrefixList2->addItem("micro-", 1e-6);
232  analogUnitPrefixList2->addItem("nano-", 1e-9);
233  analogUnitPrefixList2->addItem("pico-", 1e-12);
234  analogUnitPrefixList2->addItem("femto-", 1e-15);
235  analogUnitPrefixList2->addItem("atto-", 1e-18);
236  analogUnitPrefixList2->addItem("zepto-", 1e-21);
237  analogUnitPrefixList2->addItem("yocto-", 1e-24);
238 
239  analogLayout->addWidget(analogUnitPrefixList2, 4, 2, 1, 1);
240  analogLayout->addWidget(new QLabel(tr(" Volt/Amps")), 4, 3);
241  analogLayout->addWidget(new QLabel(tr("Downsample:")), 5, 0);
242  analogDownsampleList->addItem("1", 1);
243  analogDownsampleList->addItem("2", 2);
244  analogDownsampleList->addItem("4", 4);
245  analogDownsampleList->addItem("6", 6);
246  analogDownsampleList->addItem("8", 8);
247  analogDownsampleList->addItem("10", 10);
248  analogLayout->addWidget(analogDownsampleList, 5, 1);
249 
250  // Assign layout to child widget
251  analogGroup->setLayout(analogLayout);
252 
253  // Create child widget and layout for digital block
254  digitalGroup = new QGroupBox(tr("Digital I/O"));
255  auto* digitalLayout = new QGridLayout;
256 
257  // Create elements for digital block
258  digitalLayout->addWidget(new QLabel(tr("Channel:")), 1, 0, 1, 1);
259 
260  digitalSubdeviceList->addItem("I/O");
261  QObject::connect(
262  digitalSubdeviceList, SIGNAL(activated(int)), this, SLOT(updateDevice()));
263  digitalLayout->addWidget(digitalSubdeviceList, 1, 1, 1, 1);
264 
265  QObject::connect(
266  digitalChannelList, SIGNAL(activated(int)), this, SLOT(display()));
267  digitalLayout->addWidget(digitalChannelList, 1, 2, 1, 1);
268 
269  digitalDirectionList->addItem("Input",
270  QVariant::fromValue(DAQ::ChannelType::DI));
271  digitalDirectionList->addItem("Output",
272  QVariant::fromValue(DAQ::ChannelType::DO));
273  digitalLayout->addWidget(digitalDirectionList, 1, 3, 1, 1);
274 
275  digitalActiveButton = new QPushButton("Active");
276  digitalActiveButton->setCheckable(true);
277  digitalLayout->addWidget(digitalActiveButton, 1, 4, 1, 1);
278 
279  // Assign layout to child widget
280  digitalGroup->setLayout(digitalLayout);
281 
282  // Create child widget
283  auto* buttonLayout = new QHBoxLayout;
284 
285  // Create elements for buttons
286  auto* applyButton = new QPushButton("Apply");
287  QObject::connect(applyButton, SIGNAL(released()), this, SLOT(apply()));
288  buttonLayout->addWidget(applyButton);
289  auto* cancelButton = new QPushButton("Close");
290  QObject::connect(
291  cancelButton, SIGNAL(released()), parentWidget(), SLOT(close()));
292  buttonLayout->addWidget(cancelButton);
293 
294  // Assign layout to child widget
295  buttonGroup->setLayout(buttonLayout);
296 
297  // Attach child widget to parent widget
298  layout->addWidget(deviceGroup, 1, 0);
299  layout->addWidget(analogGroup, 2, 0);
300  layout->addWidget(digitalGroup, 3, 0);
301  layout->addWidget(buttonGroup, 4, 0);
302 
303  // Attach layout to widget
304  setLayout(layout);
305  setWindowTitle("System Control Panel");
306 
307  // Set layout to Mdi
308  this->getMdiWindow()->setFixedSize(this->minimumSizeHint());
309 
310  // Updates settings for device and builds lists of channels
311  updateDevice();
312  display();
313 }
314 
315 void SystemControl::Panel::submitAnalogChannelUpdate()
316 {
317  auto* dev = deviceList->currentData().value<DAQ::Device*>();
318  auto a_chan = analogChannelList->currentData().value<DAQ::index_t>();
319  auto a_type =
320  analogSubdeviceList->currentData().value<DAQ::ChannelType::type_t>();
321  const double a_gain = analogGainEdit->text().toDouble()
322  * analogUnitPrefixList->currentData().toDouble();
323  const double a_zerooffset = analogZeroOffsetEdit->text().toDouble()
324  * analogUnitPrefixList2->currentData().toDouble();
325 
326  dev->setChannelActive(a_type, a_chan, analogActiveButton->isChecked());
327  if (!analogActiveButton->isChecked()) {
328  return;
329  }
330  dev->setAnalogGain(a_type, a_chan, a_gain);
331  dev->setAnalogZeroOffset(a_type, a_chan, a_zerooffset);
332  dev->setAnalogRange(
333  a_type, a_chan, analogRangeList->currentData().value<DAQ::index_t>());
334  dev->setAnalogReference(
335  a_type, a_chan, analogReferenceList->currentData().value<DAQ::index_t>());
336  dev->setAnalogUnits(
337  a_type, a_chan, analogUnitList->currentData().value<DAQ::index_t>());
338  const int value =
339  analogDownsampleList
340  ->itemData(analogDownsampleList->currentIndex(), Qt::DisplayRole)
341  .toInt();
342  dev->setAnalogDownsample(a_type, a_chan, static_cast<size_t>(value));
343  dev->setAnalogCounter(a_type, a_chan);
344 }
345 
346 void SystemControl::Panel::submitDigitalChannelUpdate()
347 {
348  auto* dev = deviceList->currentData().value<DAQ::Device*>();
349  auto d_chan = digitalChannelList->currentData().value<DAQ::index_t>();
350  auto d_dir = digitalDirectionList->currentData().value<DAQ::direction_t>();
351  auto d_type =
353 
354  dev->setChannelActive(d_type, d_chan, digitalActiveButton->isChecked());
355  if (!digitalActiveButton->isChecked()) {
356  return;
357  }
358  if (d_type == DAQ::ChannelType::DI || d_type == DAQ::ChannelType::DO) {
359  dev->setDigitalDirection(d_chan, d_dir);
360  }
361 }
362 
364 {
365  int64_t freq = freqEdit->text().toInt();
366  freq *= freqUnitList->currentData().toInt();
367  const int64_t period = RT::OS::SECONDS_TO_NANOSECONDS / freq;
369  event.setParam("period", std::any(period));
370  this->getRTXIEventManager()->postEvent(&event);
371 
372  // We don't bother continuing if no valid device info is present/selected
373  if (deviceList->count() == 0 || deviceList->currentIndex() < 0) {
374  return;
375  }
376 
377  auto* device = this->deviceList->currentData().value<DAQ::Device*>();
379  disable_device.setParam("device", std::any(static_cast<RT::Device*>(device)));
381  enable_device.setParam("device", std::any(static_cast<RT::Device*>(device)));
382 
383  this->getRTXIEventManager()->postEvent(&disable_device);
384  if (analogActiveButton->isEnabled()) {
385  this->submitAnalogChannelUpdate();
386  }
387  if (digitalActiveButton->isEnabled()) {
388  this->submitDigitalChannelUpdate();
389  }
390  this->getRTXIEventManager()->postEvent(&enable_device);
391  // Display changes
392  display();
393 }
394 
396 {
397  if (this->deviceList->currentIndex() < 0) {
398  return;
399  }
400 
401  auto* dev = deviceList->currentData().value<DAQ::Device*>();
402  analogChannelList->clear();
403  digitalChannelList->clear();
404 
405  auto type =
406  analogSubdeviceList->currentData().value<DAQ::ChannelType::type_t>();
407  for (size_t i = 0; i < dev->getChannelCount(type); ++i) {
408  analogChannelList->addItem(
409  QString::number(i), QVariant::fromValue(static_cast<DAQ::index_t>(i)));
410  }
411 
412  type = digitalSubdeviceList->currentData().value<DAQ::ChannelType::type_t>();
413  for (size_t i = 0; i < dev->getChannelCount(type); ++i) {
414  digitalChannelList->addItem(
415  QString::number(i), QVariant::fromValue(static_cast<DAQ::index_t>(i)));
416  }
417 
418  display();
419 }
420 
422 {
423  /* Determine the Period */
424  auto period = periodEdit->text().toDouble();
425  period *= periodUnitList->currentData().toDouble();
426  auto freq = 1 / period;
427  int index = 0;
428  if (freq > 1000) {
429  freq /= 1000;
430  index = 1;
431  }
432 
433  freqEdit->setText(QString::number(freq));
434  freqUnitList->setCurrentIndex(index);
435 }
436 
438 {
439  int index = 0;
440 
441  // Determine the Frequency
442  auto freq = freqEdit->text().toDouble();
443  freq *= freqUnitList->currentData().toDouble();
444 
445  auto period = 1 / freq;
446 
447  while (period < .001 && (index < 4)) {
448  period *= 1000;
449  index++;
450  }
451 
452  periodEdit->setText(QString::number(period));
453  periodUnitList->setCurrentIndex(index);
454 }
455 
456 void SystemControl::Panel::buildDAQDeviceList()
457 {
459  this->getRTXIEventManager()->postEvent(&device_list_request);
460  auto devices = std::any_cast<std::vector<DAQ::Device*>>(
461  device_list_request.getParam("devices"));
462  for (auto* device : devices) {
463  this->deviceList->addItem(QString(device->getName().c_str()),
464  QVariant::fromValue(device));
465  }
466 }
467 
468 // TODO: improve simplicity of display function
470 {
471  if (deviceList->count() == 0) {
472  deviceList->setEnabled(false);
473  analogSubdeviceList->setEnabled(false);
474  digitalSubdeviceList->setEnabled(false);
475  }
476  displayAnalogGroup();
477  displayDigitalGroup();
478  // Display thread info
479  int index = 3;
481  this->getRTXIEventManager()->postEvent(&get_period_event);
482  auto tmp = std::any_cast<int64_t>(get_period_event.getParam("period"));
483  while ((tmp >= 1000) && ((index) != 0)) {
484  tmp /= 1000;
485  index--;
486  }
487  periodEdit->setText(QString::number(static_cast<int64_t>(tmp)));
488  periodUnitList->setCurrentIndex(index);
489  updateFreq();
490 }
491 
493 {
494  if (deviceList->count() == 0 || deviceList->currentIndex() < 0) {
495  return;
496  }
497  if (analogChannelList->count() == 0 || analogChannelList->currentIndex() < 0)
498  {
499  analogActiveButton->setChecked(false);
500  analogActiveButton->setEnabled(false);
501  analogRangeList->setEnabled(false);
502  analogDownsampleList->setEnabled(false);
503  analogReferenceList->setEnabled(false);
504  analogGainEdit->setEnabled(false);
505  analogZeroOffsetEdit->setEnabled(false);
506  analogUnitPrefixList->setEnabled(false);
507  analogUnitPrefixList2->setEnabled(false);
508  analogUnitList->setEnabled(false);
509  return;
510  }
511  auto* dev = deviceList->currentData().value<DAQ::Device*>();
512  auto type =
513  analogSubdeviceList->currentData().value<DAQ::ChannelType::type_t>();
514  auto chan = analogChannelList->currentData().value<DAQ::index_t>();
515 
516  // Downsample is only enabled for AI
517  analogDownsampleList->setEnabled(type == DAQ::ChannelType::AI);
518  analogActiveButton->setEnabled(true);
519  analogChannelList->setEnabled(true);
520  analogRangeList->setEnabled(true);
521  analogReferenceList->setEnabled(true);
522  analogGainEdit->setEnabled(true);
523  analogZeroOffsetEdit->setEnabled(true);
524  analogUnitPrefixList->setEnabled(true);
525  analogUnitPrefixList2->setEnabled(true);
526  analogUnitList->setEnabled(true);
527 
528  analogActiveButton->setChecked(dev->getChannelActive(type, chan));
529  analogRangeList->setCurrentIndex(
530  static_cast<int>(dev->getAnalogRange(type, chan)));
531  analogDownsampleList->setCurrentIndex(analogDownsampleList->findData(
532  QVariant::fromValue(dev->getAnalogDownsample(type, chan)),
533  Qt::DisplayRole));
534  analogReferenceList->setCurrentIndex(analogReferenceList->findData(
535  QVariant::fromValue(dev->getAnalogReference(type, chan))));
536  analogUnitList->setCurrentIndex(analogUnitList->findData(
537  QVariant::fromValue(dev->getAnalogUnits(type, chan))));
538 
539  // Determine the correct prefix for analog gain
540  int indx = 8;
541  double tmp = NAN;
542  const double gain = dev->getAnalogGain(type, chan);
543  tmp = fabs(gain);
544  while (((tmp >= 1000) && (indx > 0)) || ((tmp < 1) && (indx < 16))) {
545  if (tmp >= 1000) {
546  tmp /= 1000;
547  indx--;
548  } else {
549  tmp *= 1000;
550  indx++;
551  }
552  }
553  analogGainEdit->setText(QString::number(gain));
554 
555  // Set gain prefix to computed index
556  analogUnitPrefixList->setCurrentIndex(indx);
557 
558  // Determine the correct prefix for analog offset
559  indx = 8;
560  const double offset = dev->getAnalogZeroOffset(type, chan);
561  tmp = fabs(offset);
562  while (((tmp >= 1000) && (indx > 0)) || ((tmp < 1) && (indx < 16))) {
563  if (tmp >= 1000) {
564  tmp /= 1000;
565  indx--;
566  } else {
567  tmp *= 1000;
568  indx++;
569  }
570  }
571  analogZeroOffsetEdit->setText(QString::number(offset));
572  // Set offset prefix to computed index
573  analogUnitPrefixList2->setCurrentIndex(indx);
574 }
575 
577 {
578  if (deviceList->count() == 0 || deviceList->currentIndex() < 0) {
579  return;
580  }
581  if (digitalChannelList->count() == 0) {
582  digitalActiveButton->setChecked(false);
583  digitalActiveButton->setEnabled(false);
584  digitalChannelList->setEnabled(false);
585  digitalDirectionList->setEnabled(false);
586  return;
587  }
588  auto* dev = deviceList->currentData().value<DAQ::Device*>();
589  auto chan = digitalChannelList->currentData().value<DAQ::index_t>();
590  auto direction =
591  digitalDirectionList->currentData().value<DAQ::direction_t>();
592 
593  digitalActiveButton->setEnabled(true);
594  digitalChannelList->setEnabled(true);
595  digitalDirectionList->setCurrentIndex(
596  digitalDirectionList->findData(QVariant::fromValue(direction)));
597  auto type =
599  digitalActiveButton->setChecked(dev->getChannelActive(type, chan));
600 }
601 
602 std::unique_ptr<Widgets::Plugin> SystemControl::createRTXIPlugin(
603  Event::Manager* ev_manager)
604 {
605  return std::make_unique<SystemControl::Plugin>(ev_manager);
606 }
607 
609  Event::Manager* ev_manager)
610 {
611  return static_cast<Widgets::Panel*>(
612  new SystemControl::Panel(main_window, ev_manager));
613 }
614 
615 std::unique_ptr<Widgets::Component> SystemControl::createRTXIComponent(
616  Widgets::Plugin* /*unused*/)
617 {
618  return {nullptr};
619 }
620 
622 {
627  return fact;
628 }
virtual double getAnalogGain(ChannelType::type_t type, index_t index) const =0
virtual int setChannelActive(ChannelType::type_t type, index_t index, bool state)=0
void postEvent(Object *event)
Definition: event.cpp:299
void setParam(const std::string &param_name, const std::any &param_value)
Definition: event.cpp:191
std::any getParam(const std::string &param_name) const
Definition: event.cpp:170
Panel(QMainWindow *mw, Event::Manager *ev_manager)
Event::Manager * getRTXIEventManager()
Definition: widgets.hpp:443
QMdiSubWindow * getMdiWindow()
Definition: widgets.hpp:286
constexpr std::string_view MODULE_NAME
Definition: connector.hpp:35
@ DIFFERENTIAL
Definition: daq.hpp:104
uint64_t index_t
Definition: daq.hpp:82
std::array< std::string, 2 > get_default_units()
Definition: daq.hpp:122
std::array< analog_range_t, 7 > get_default_ranges()
Definition: daq.hpp:110
direction_t
Definition: daq.hpp:93
@ INPUT
Definition: daq.hpp:94
@ RT_GET_PERIOD_EVENT
Definition: event.hpp:59
@ RT_PERIOD_EVENT
Definition: event.hpp:56
@ RT_DEVICE_UNPAUSE_EVENT
Definition: event.hpp:67
@ DAQ_DEVICE_QUERY_EVENT
Definition: event.hpp:79
@ RT_DEVICE_PAUSE_EVENT
Definition: event.hpp:66
const int64_t SECONDS_TO_NANOSECONDS
Definition: rtos.hpp:17
std::unique_ptr< Widgets::Plugin > createRTXIPlugin(Event::Manager *ev_manager)
Widgets::FactoryMethods getFactories()
std::unique_ptr< Widgets::Component > createRTXIComponent(Widgets::Plugin *host_plugin)
Widgets::Panel * createRTXIPanel(QMainWindow *main_window, Event::Manager *ev_manager)
Definition: rt.hpp:35
std::unique_ptr< Widgets::Plugin >(* createPlugin)(Event::Manager *)
Function that returns a smart pointer to plugin object.
Definition: widgets.hpp:145
Widgets::Panel *(* createPanel)(QMainWindow *, Event::Manager *)
Definition: widgets.hpp:170
std::unique_ptr< Widgets::Component >(* createComponent)(Widgets::Plugin *)
Definition: widgets.hpp:156