44 throw LocalException(
"Could not find calibration file '") << calibrationFilePath <<
"'";
46 ARMARX_INFO <<
"reading config " << calibrationFilePath;
50 auto findDaqNode = [&](std::string serialNumber)
54 if (daqNode.attribute_value(
"serialNumber") == serialNumber)
64 OPort* portlist = ports.listPorts(
true);
65 ARMARX_INFO <<
"Found " << ports.getLastSize() <<
" Optoforce device(s).";
68 portlist = ports.listPorts(
true);
69 ARMARX_INFO <<
"Found " << ports.getLastSize() <<
" Optoforce device(s):";
71 for (
int i = 0; i < ports.getLastSize(); i++)
73 std::string deviceName(portlist[i].name);
74 std::string serialNumber(portlist[i].serialNumber);
75 ARMARX_INFO <<
"Found DAQ: deviceName='" << deviceName <<
"', serialNumber='"
76 << serialNumber <<
"'";
80 throw LocalException(
"Could not find config node for device deviceName='")
81 << deviceName <<
"', serialNumber='" << serialNumber <<
"'";
83 DaqWrapperPtr daqPtr(
new DaqWrapper(deviceName, serialNumber, daqNode));
84 daqList.push_back(daqPtr);
87 ARMARX_INFO <<
"number of ports: " << ports.getLastSize();
89 for (
int i = 0; i < ports.getLastSize(); ++i)
91 const DaqWrapperPtr& daq = daqList.at(i);
93 daq->daq.open(portlist[i]);
95 daq->checkSensorCount();
115 OptoForceUnitListenerPrx batchPrx = topicPrx->ice_batchOneway();
118 while (readTask->isRunning())
120 bool flushNeeded =
false;
122 for (
const DaqWrapperPtr& daqPtr : daqList)
125 int size = daqPtr->daq.readAll(pa,
false);
136 if (daqPtr->daq.getSize() > 0)
138 IceUtil::Time now = IceUtil::Time::now();
141 int sensorCount = daqPtr->daq.getSensorSize();
143 std::vector<std::array<float, 3>>
data;
144 data.resize(sensorCount);
146 for (
int i = 0; i < sensorCount; i++)
148 if (!daqPtr->enableFlags.at(i))
152 for (
int n = 0;
n < size;
n++)
154 float countsPerN = daqPtr->countsPerN.at(i);
155 float x = pa[i * size +
n].x / countsPerN - daqPtr->offsets.at(i).at(0);
156 float y = pa[i * size +
n].y / countsPerN - daqPtr->offsets.at(i).at(1);
157 float z = pa[i * size +
n].z / countsPerN - daqPtr->offsets.at(i).at(2);
159 batchPrx->reportSensorValues(daqPtr->deviceName +
":" +
to_string(i),
160 daqPtr->sensorNames.at(i),
166 data.at(i) = {x, y, z};
173 recordingFile <<
"{\"timestamp\":\"" << now.toDateTime() <<
"\",";
174 recordingFile <<
"\"daq\":\"" << daqPtr->serialNumber <<
"\",\"data\":[";
176 for (
int i = 0; i < sensorCount; i++)
178 if (!daqPtr->enableFlags.at(i))
184 recordingFile <<
",";
187 recordingFile <<
"[" <<
data.at(i).at(0) <<
"," <<
data.at(i).at(1) <<
","
188 <<
data.at(i).at(2) <<
"]";
190 recordingFile <<
"]}\n";
191 recordingFile.flush();
195 if (isRecording && stopRecordingFlag)
197 recordingFile.close();
200 stopRecordingFlag =
false;
203 batchPrx->ice_flushBatchRequests();
230OptoForceUnit::DaqWrapper::DaqWrapper(
const std::string& deviceName,
231 const std::string& serialNumber,
233 deviceName(deviceName), serialNumber(serialNumber)
238 float counts_at_nc = sensorNode.attribute_as_float(
"counts_at_nc");
239 float nominalCapacity = sensorNode.attribute_as_float(
"nominalCapacity");
240 std::string sensorName =
241 sensorNode.attribute_value_or_default(
"name", serialNumber +
"-" + to_string(i));
242 countsPerN.push_back(counts_at_nc / nominalCapacity);
243 sensorNames.push_back(sensorName);
244 enableFlags.push_back(
245 sensorNode.attribute_as_optional_bool(
"enabled",
"true",
"false", true));
246 offsets.push_back({sensorNode.attribute_as_float(
"offsetX"),
247 sensorNode.attribute_as_float(
"offsetY"),
248 sensorNode.attribute_as_float(
"offsetZ")});
254OptoForceUnit::DaqWrapper::printInfo()
256 SensorConfig config = daq.getConfig();
257 int state = config.getState();
258 int speed = config.getSpeed();
259 int filter = config.getFilter();
260 int mode = config.getMode();
274OptoForceUnit::DaqWrapper::checkSensorCount()
276 if ((
int)countsPerN.size() != daq.getSensorSize())
278 throw LocalException(
"Sensor count mismatch. Configured: ")
279 << ((int)countsPerN.size()) <<
" found: " << daq.getSensorSize();
281 ARMARX_INFO_S <<
"Configured: " << ((int)countsPerN.size()) <<
" found: " << daq.getSensorSize()
289 recordingFile.open(filepath);
296 stopRecordingFlag =
true;
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Property< PropertyType > getProperty(const std::string &name)
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
TopicProxyType getTopic(const std::string &name)
Returns a proxy of the specified topic.
Brief description of class OptoForceUnit.
void onInitComponent() override
void onDisconnectComponent() override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void onConnectComponent() override
void startRecording(const std::string &filepath, const Ice::Current &) override
void stopRecording(const Ice::Current &) override
void onExitComponent() override
std::vector< RapidXmlReaderNode > nodes(const char *name=nullptr) const
static RapidXmlReaderNode NullNode()
static RapidXmlReaderPtr FromFile(const std::string &path)
#define ARMARX_INFO
The normal logging level.
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_IMPORTANT_S
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< RapidXmlReader > RapidXmlReaderPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
const std::string & to_string(const std::string &s)
IceInternal::Handle< TimestampVariant > TimestampVariantPtr
constexpr auto n() noexcept