ATINetFTUnit.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * 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 * @package VisionX::ArmarXObjects::ATINetFTUnit
19 * @author Jonas Rauber ( kit at jonasrauber dot de )
20 * @date 2014
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25#include "ATINetFTUnit.h"
26
27#include <inttypes.h>
28#include <stdio.h>
29#include <stdlib.h>
30
31#include <iostream>
32#include <string>
33#include <vector>
34
35#include <arpa/inet.h>
36#include <netdb.h>
37#include <sys/socket.h>
38
39namespace armarx
40{
41 void
45
46 void
48 {
49 /*
50 * Read ATINetFT hostname and port from properties
51 * std::string receiverHostName("192.168.1.1:49152");
52 */
53
54 std::string ATINetFTReceiverHostName =
55 getProperty<std::string>("ATINetFTReceiveHostName").getValue();
56 std::string captureName = getProperty<std::string>("CaptureName").getValue();
57 ARMARX_INFO << "Capture Name " << captureName;
58 size_t pos = captureName.find("0");
59 captureNamePrefix = captureName.substr(0, pos);
60 ARMARX_INFO << "Capture Name Prefix " << captureNamePrefix;
61 std::string captureNameSuffix = captureName.substr(pos, captureName.size());
62 ARMARX_INFO << "Capture Name Suffix " << captureNameSuffix;
63 nPaddingZeros = captureNameSuffix.size();
64 captureNumber = std::stoi(captureNameSuffix);
65 establishATINetFTReceiveHostConnection(ATINetFTReceiverHostName);
66 ftDataSize = 6;
67 sendPacketSize = 8;
68 receivePacketSize = 36;
69 recordingStopped = true;
70 recordingCompleted = true;
71 recordingStarted = false;
72
73 /*
74 * Connect to ATINetFT
75 */
76 /*if (ATINetFT.Connect(hostName).Result != Result::Success)
77 {
78 ARMARX_ERROR << "Could not connect to ATINetFT at " << hostName << flush;
79 return;
80 }
81 else
82 {
83 ARMARX_IMPORTANT << "Connected to ATINetFT at " << hostName << flush;
84 }*/
85
86 /*
87 * Enable Marker Data
88 */
89 /*Result::Enum result = ATINetFT.EnableMarkerData().Result;
90
91 if (result != Result::Success)
92 {
93 ARMARX_ERROR << "ATINetFT EnableMarkerData() returned error code " << result << flush;
94 return;
95 }*/
96 }
97
98 void
100 {
101 ARMARX_IMPORTANT << "Disconnecting from ATINetFT" << flush;
102 }
103
104 void
108
109 void
110 ATINetFTUnit::periodicExec()
111 {
112 if (recordingStarted)
113
114
115 {
116 //ISO C++ forbids variable length array [-Werror=vla] => use a vector (the array will be on the heap anyways)
117 std::vector<float> ftdata(ftDataSize);
118 std::vector<char> receivePacketContent(receivePacketSize);
119
120 if (!receivePacket(receivePacketContent.data()))
121 {
122 ARMARX_INFO << "recvfrom() failed :";
123 }
124 else
125 {
126 convertToFTValues(receivePacketContent.data(), ftdata.data(), ftdata.size());
127 writeFTValuesToFile(ftdata.data(), ftdata.size());
128 sampleIndex++;
129 }
130 }
131 }
132
138
139 void
140 ATINetFTUnit::startRecording(const std::string& customName, const Ice::Current& c)
141 {
142 if (remoteTriggerEnabled)
143 {
144 if (recordingCompleted)
145 {
146 int bpSize = sendPacketSize;
147 //ISO C++ forbids variable length array [-Werror=vla] => use a vector (the array will be on the heap anyways)
148 std::vector<char> bytePacket(bpSize);
149 *(uint16_t*)&bytePacket[0] = htons(0x1234); /* standard header. */
150 *(uint16_t*)&bytePacket[2] = htons(2); /* per table 9.1 in Net F/T user manual. */
151 *(uint32_t*)&bytePacket[4] = htonl(0); /* see section 9.1 in Net F/T user manual. */
152 recordingStarted = sendPacket(bytePacket.data(), bytePacket.size());
153
154 if (recordingStarted)
155 {
156 recordingStopped = false;
157 recordingCompleted = false;
158 //TODO build filename captureNamePrefic+customName
159 recordingFile.open(captureNamePrefix);
160 sampleIndex = 0;
161 }
162 }
163 }
164 }
165
166 void
167 ATINetFTUnit::stopRecording(const Ice::Current& c)
168 {
169 if (remoteTriggerEnabled)
170 {
171 int bpSize = 8;
172 //ISO C++ forbids variable length array [-Werror=vla] => use a vector (the array will be on the heap anyways)
173 std::vector<char> bytePacket(bpSize);
174 *(uint16_t*)&bytePacket[0] = htons(0x1234); /* standard header. */
175 *(uint16_t*)&bytePacket[2] = htons(0); /* per table 9.1 in Net F/T user manual. */
176 *(uint32_t*)&bytePacket[4] = htonl(0); /* see section 9.1 in Net F/T user manual. */
177
178 recordingStopped = sendPacket(bytePacket.data(), bytePacket.size());
179 if (recordingStopped)
180 {
181 recordingFile.close();
182 recordingStarted = false;
183 }
184 }
185 }
186
187 bool
188 ATINetFTUnit::sendPacket(char* bytePacket, int bpSize)
189 {
190 if (remoteTriggerEnabled)
191 {
192 if (sendto(senderSocket,
193 bytePacket,
194 bpSize,
195 0,
196 (struct sockaddr*)&receiveHostAddr,
197 sizeof(receiveHostAddr)) != bpSize)
198 {
199
200 return false;
201 }
202 return true;
203 }
204 return false;
205 }
206
207 bool
208 ATINetFTUnit::receivePacket(char* receiveBuf)
209 {
210
211 int test = sizeof(receiveHostAddr);
212
213 int receiveint = recvfrom(senderSocket,
214 receiveBuf,
215 receivePacketSize,
216 0,
217 (struct sockaddr*)&receiveHostAddr,
218 ((socklen_t*)&test));
219
220 if (receiveint < 0)
221 {
222
223 return false;
224 }
225
226
227 return true;
228 }
229
230 void
231 ATINetFTUnit::convertToFTValues(char* receiveBuf, float* ftdata, int ftdataSize)
232 {
233 //uint32_t rdt_sequence = ntohl(*(uint32_t*)&receiveBuf[0]); //was an unused variable
234 //uint32_t ft_sequence = ntohl(*(uint32_t*)&receiveBuf[4]); //was an unused variable
235 //uint32_t status = ntohl(*(uint32_t*)&receiveBuf[8]); //was an unused variable
236
237 for (int i = 0; i < ftdataSize; i++)
238 {
239 ftdata[i] = float(int32_t(ntohl(*(uint32_t*)&receiveBuf[12 + i * 4]))) / 1000000.0f;
240 }
241 }
242
243 void
244 ATINetFTUnit::writeFTValuesToFile(float* ftdata, int ftdataSize)
245 {
246 recordingFile << sampleIndex << " ";
247 for (int i = 0; i < ftdataSize; i++)
248 {
249 recordingFile << ftdata[i] << " ";
250 }
251 recordingFile << "\n";
252 }
253
254 void
255 ATINetFTUnit::establishATINetFTReceiveHostConnection(std::string receiverHostName)
256 {
257 remoteTriggerEnabled = false;
258
259 //Construct the server sockaddr_ structure
260 memset(&senderHostAddr, 0, sizeof(senderHostAddr));
261 senderHostAddr.sin_family = AF_INET;
262 senderHostAddr.sin_addr.s_addr = htonl(INADDR_ANY);
263 senderHostAddr.sin_port = htons(0);
264
265 //Create the socket
266 if ((senderSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
267 {
268 return;
269 }
270
271 if (bind(senderSocket, (struct sockaddr*)&senderHostAddr, sizeof(senderHostAddr)) < 0)
272 {
273 return;
274 }
275
276 //Construct the server sockaddr_ structure
277 memset(&receiveHostAddr, 0, sizeof(receiveHostAddr));
278 size_t pos = receiverHostName.find(":");
279 std::string hostname = receiverHostName.substr(0, pos);
280
281 std::string hostport = receiverHostName.substr(pos + 1, receiverHostName.size());
282
283 struct hostent* he;
284 struct in_addr** addr_list;
285 int i;
286
287 if ((he = gethostbyname(hostname.c_str())) == NULL)
288 {
289 // get the host info
290 herror("gethostbyname");
291 return;
292 }
293
294 addr_list = (struct in_addr**)he->h_addr_list;
295
296 for (i = 0; addr_list[i] != NULL; i++)
297 {
298
299 char ip[100];
300 //Return the first one;
301 strcpy(ip, inet_ntoa(*addr_list[i]));
302
303 inet_pton(AF_INET, ip, &receiveHostAddr.sin_addr.s_addr);
304
305 receiveHostAddr.sin_port = htons(atoi(hostport.c_str()));
306 remoteTriggerEnabled = true;
307 ARMARX_INFO << "Connection established to " << hostname << ":" << hostport;
308 //if((receiverSocket=socket(AF_INET, SOCK_DGRAM, 0))<0) {
309 // return;
310 //}
311 //if(bind(receiverSocket,( struct sockaddr *) &receiveHostAddr, sizeof(receiveHostAddr))<0) {
312 // return;
313 //}
314
315 return;
316 }
317 return;
318 }
319} // namespace armarx
#define float
Definition 16_Level.h:22
constexpr T c
void onInitComponent() override
void onDisconnectComponent() override
void stopRecording(const Ice::Current &c) override
void onConnectComponent() override
PropertyDefinitionsPtr createPropertyDefinitions() override
void startRecording(const std::string &customName, const Ice::Current &c) override
void onExitComponent() override
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
Property< PropertyType > getProperty(const std::string &name)
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
const LogSender::manipulator flush
Definition LogSender.h:251