Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpComedi.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software 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 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * ATI Force torque interface.
32 */
33
34#include <visp3/core/vpConfig.h>
35
36#ifdef VISP_HAVE_COMEDI
37
38#include <unistd.h>
39
40#include <visp3/core/vpException.h>
41#include <visp3/sensor/vpComedi.h>
42
48 : m_device("/dev/comedi0"), m_handler(nullptr), m_subdevice(0), m_range(0), m_aref(AREF_DIFF), m_nchannel(6),
50{ }
51
57
62{
63 if (!m_handler) {
64 m_handler = comedi_open(m_device.c_str());
65
66 if (!m_handler) {
67 throw vpException(vpException::fatalError, "Could not open device %s", m_device.c_str());
68 }
69
70 // Print NaN for clipped inputs
71 comedi_set_global_oor_behavior(COMEDI_OOR_NAN);
72
73 // Setup data range and max value
75 m_maxdata.resize(m_nchannel);
76 m_chanlist.resize(m_nchannel);
77 for (unsigned int channel = 0; channel < m_nchannel; channel++) {
78 m_chanlist[channel] = CR_PACK(channel, m_range, m_aref);
79 m_range_info[channel] = comedi_get_range(m_handler, m_subdevice, channel, m_range);
80 m_maxdata[channel] = comedi_get_maxdata(m_handler, m_subdevice, channel);
81 }
82 }
83}
84
89{
90 if (m_handler) {
91 comedi_close(m_handler);
92 m_handler = nullptr;
93 }
94}
95
103std::vector<lsampl_t> vpComedi::getRawData() const
104{
105 if (m_handler == nullptr) {
106 throw vpException(vpException::fatalError, "Comedi device not open");
107 }
108 // Get raw data
109 std::vector<lsampl_t> raw_data(m_nchannel);
110
111 for (unsigned int channel = 0; channel < m_nchannel; channel++) {
112 // When switching the multiplexor from one channel to the next, the A/D
113 // input needs time to settle to the new input voltage. The greater the
114 // voltage difference, the more time it takes. Here we wait for 1us
115 int ret = comedi_data_read_delayed(m_handler, m_subdevice, channel, m_range, m_aref, &raw_data[channel], 1000);
116 if (ret < 0) {
118 "Cannot get %d data from device=%s subdevice=%d "
119 "channel=%d range=%d analog reference=%d",
120 m_nchannel, m_device.c_str(), m_subdevice, channel, m_aref);
121 }
122 }
123
124 return raw_data;
125}
126
132{
133 if (m_handler == nullptr) {
134 throw vpException(vpException::fatalError, "Comedi device not open");
135 }
136 // Get raw data
137 std::vector<lsampl_t> raw_data = this->getRawData();
138 vpColVector phy_data(m_nchannel);
139
140 // Convert data to physical data
141 for (unsigned int channel = 0; channel < m_nchannel; channel++) {
142 phy_data[channel] = comedi_to_phys(raw_data[channel], m_range_info[channel], m_maxdata[channel]);
143 if (vpMath::isNaN(phy_data[channel])) {
144 throw vpException(vpException::fatalError, "Comedi DAQ get NaN value. Check the connection with your device");
145 }
146 }
147
148 return phy_data;
149}
150
153std::string vpComedi::getPhyDataUnits() const
154{
155 if (m_handler == nullptr) {
156 throw vpException(vpException::fatalError, "Comedi device not open");
157 }
158 std::string units;
159 unsigned int channel = 0;
160 switch (m_range_info[channel]->unit) {
161 case UNIT_volt:
162 units = "V";
163 break;
164 case UNIT_mA:
165 units = "mA";
166 break;
167 case UNIT_none:
168 break;
169 }
170 return units;
171}
172END_VISP_NAMESPACE
173#elif !defined(VISP_BUILD_SHARED_LIBS)
174// Work around to avoid warning: libvisp_sensor.a(vpComedi.cpp.o) has symbols
175void dummy_vpComedi() { }
176#endif
Implementation of column vector and the associated operations.
virtual ~vpComedi()
Definition vpComedi.cpp:56
unsigned int m_aref
Definition vpComedi.h:173
std::vector< lsampl_t > m_maxdata
Definition vpComedi.h:176
std::string m_device
Definition vpComedi.h:169
std::vector< lsampl_t > getRawData() const
Definition vpComedi.cpp:103
unsigned int m_range
Definition vpComedi.h:172
vpColVector getPhyData() const
Definition vpComedi.cpp:131
void open()
Definition vpComedi.cpp:61
std::vector< comedi_range * > m_range_info
Definition vpComedi.h:175
unsigned int m_subdevice
Definition vpComedi.h:171
comedi_t * m_handler
Definition vpComedi.h:170
unsigned int m_nchannel
Definition vpComedi.h:174
std::vector< unsigned int > m_chanlist
Definition vpComedi.h:177
std::string getPhyDataUnits() const
Definition vpComedi.cpp:153
void close()
Definition vpComedi.cpp:88
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ fatalError
Fatal error.
Definition vpException.h:72
static bool isNaN(double value)
Definition vpMath.cpp:101