UDPManager.java
Go to the documentation of this file.
1 package grl;
2 
3 import java.nio.ByteBuffer;
4 
5 import com.kuka.task.ITaskLogger;
6 import java.io.*;
7 import java.net.*;
8 
9 public class UDPManager {
10 
11  DatagramSocket socket = null;
12 
13  ITaskLogger logger;
14  String _Remote_IP;
15  int _Remote_Port;
16 
17  InetAddress _address_send = null;
18 
19  int statesLength = 0;
20  long message_counter = 0;
21  long noMessageCounter = 0;
22  long noMessageCounterLimit = 9999999;
23  private grl.flatbuffer.KUKAiiwaStates _currentKUKAiiwaStates = null;
24  private grl.flatbuffer.KUKAiiwaState _currentKUKAiiwaState = null;
25  private grl.flatbuffer.KUKAiiwaState _previousKUKAiiwaState = null;
26 
27  byte[] recBuf = new byte[1400];
28  ByteBuffer bb = null;
29  boolean stop;
30 
31  long startTime;
32  long elapsedTime;
33  long lastMessageStartTime;
34  long lastMessageElapsedTime;
35  long lastMessageTimeoutMilliseconds = 1000;
36 
37  int retriesAllowed = 3;
38  int retriesAttempted = 0;
39 
40  public UDPManager(String laptopIP, String laptopPort, ITaskLogger errorlogger) {
41  super();
42  this.logger = errorlogger;
43  _Remote_IP = laptopIP;
44  _Remote_Port = Integer.parseInt(laptopPort);
45 
46  try {
47  _address_send = InetAddress.getByName(_Remote_IP);
48  } catch (UnknownHostException e) {
49  logger.error("Could not create InetAddress for sending");
50  }
51 
52  }
53 
54  /**
55  * Blocks until a connection is established or stop() is called.
56  *
57  * @return error code: false on success, otherwise failure (or told to stop)
58  * @throws UnknownHostException
59  */
60  public boolean connect() {
61 
62  logger.info("Waiting for connection initialization...");
63 
64  try {
65  socket = new DatagramSocket();
66  } catch (SocketException e1) {
67  logger.info("failed to create socket.");
68  }
69 
70 
71 
72  try {
73  socket.setSoTimeout(100);
74  } catch (SocketException e1) {
75  logger.error("UDPManager failed to set socket timeout");
76  }
77 
78  startTime = System.currentTimeMillis();
79  elapsedTime = 0L;
80  grl.flatbuffer.KUKAiiwaStates newKUKAiiwaStates = null;
81  int newStatesLength = 0;
82 
83  boolean connectionEstablished = false;
84 
85  while(newStatesLength<1 && newKUKAiiwaStates == null){
86 
87  DatagramPacket packet = new DatagramPacket(recBuf, recBuf.length);
88 
89  // continues sending dummy messages until the server receives the address of this machine and sends a message back
90  while (!connectionEstablished){
91  connectionEstablished = preConnect();
92  if (stop) {
93  logger.info("Stopping program.");
94  return true; // asked to exit
95  }
96  }
97 
98  if(packet.getLength() > 0){
99 
100  bb = ByteBuffer.wrap(recBuf);
101 
102  newKUKAiiwaStates = grl.flatbuffer.KUKAiiwaStates.getRootAsKUKAiiwaStates(bb);
103  newStatesLength = newKUKAiiwaStates.statesLength();
104 
105  }
106 
107  if (stop) {
108  logger.info("Stopping program.");
109  return true; // asked to exit
110  }
111  }
112 
113  _currentKUKAiiwaStates = newKUKAiiwaStates;
114  statesLength = newStatesLength;
115 
116  logger.info("States initialized...");
117 
118  startTime = System.currentTimeMillis();
119  lastMessageStartTime = startTime;
120  lastMessageElapsedTime = System.currentTimeMillis() - lastMessageStartTime;
121  elapsedTime = 0L;
122 
123  return false; // no error
124  }
125 
126  /// @return true successfully sent and received a message, false otherwise
127  private boolean preConnect()
128  {
129  // Dummy message to send to Remote pc (server), in order for the server to know the address of the client (this machine)
130  /// @todo Should probably just make this a real flatbuffers init message too
131  String dummyMessage = "Hi";
132 
133  DatagramPacket packetSend= new DatagramPacket(dummyMessage.getBytes(), dummyMessage.getBytes().length, _address_send, _Remote_Port);
134 
135  try {
136  socket.send(packetSend);
137  } catch (IOException e1) {
138  // Could not send
139  }
140  try {
141  DatagramPacket packet = new DatagramPacket(recBuf, recBuf.length);
142  socket.receive(packet);
143  return true;
144  } catch (SocketTimeoutException e) {
145  // TimeOut reached, continue sending until we receive something
146  return false;
147  } catch (IOException e) {
148  // Could not receive packet
149  return false;
150  }
151  }
152 
153  /**
154  * Blocks until a connection is re-established or stop() is called.
155  *
156  * @return error code: false on success, otherwise failure (or told to stop)
157  * @throws IOException
158  */
159 
160 
161  public boolean sendMessage(byte[] msg, int size) throws IOException
162  {
163  DatagramPacket packet= new DatagramPacket(msg, size, _address_send , _Remote_Port );
164  socket.send(packet);
165  return true;
166  }
167 
169  {
170  boolean haveNextMessage = false;
171  while(!stop && !haveNextMessage) {
172 
173  DatagramPacket packet = new DatagramPacket(recBuf, recBuf.length);
174  try {
175  socket.receive(packet);
176 
177  if(packet.getLength() > 0){
178 
179  message_counter+=1;
180  bb = ByteBuffer.wrap(recBuf);
181 
182  _currentKUKAiiwaStates = grl.flatbuffer.KUKAiiwaStates.getRootAsKUKAiiwaStates(bb, _currentKUKAiiwaStates);
183 
184  if(_currentKUKAiiwaStates.statesLength()>0) {
185  // initialize the fist state
186  grl.flatbuffer.KUKAiiwaState tmp = _currentKUKAiiwaStates.states(0);
187  if (tmp == null || tmp.armControlState() == null) {
188  noMessageCounter +=1;
189  if (message_counter % 100 == 0) {
190  logger.warn("NULL ArmControlState message, main UDP FlatBuffer message is arriving but doesn't contain any data/commands!");
191  }
192  continue;
193  } else {
194  _previousKUKAiiwaState = _currentKUKAiiwaState;
195  _currentKUKAiiwaState = tmp;
196  }
197 
198  if (_currentKUKAiiwaState == null) {
199  noMessageCounter+=1;
200  logger.error("Missing current state message!");
201  continue;
202  }
203 
204  haveNextMessage=true;
205  noMessageCounter = 0;
206  lastMessageStartTime = System.currentTimeMillis();
207  } else {
208  logger.error("got a UDP packet but it isn't a valid FlatBuffer message, this is an unexpected state that shouldn't occur. please debug me.");
209  }
210  // }
211  }
212  } catch (IOException e) {
213  noMessageCounter +=1;
214  if (message_counter % 100 == 0) {
215  logger.warn("Failed to receive UDP packet from control computer... Trying to re-establish connection");
216  preConnect();
217  }
218  }
219 
220  }
221 
222  return _currentKUKAiiwaState;
223  }
224 
226  return _currentKUKAiiwaState;
227  }
228 
230  return _previousKUKAiiwaState;
231  }
232 
233 
234 
235  public boolean isStop() {
236  return stop;
237  }
238 
239  public void setStop(boolean stop) {
240  if(stop)
241  {
242  // done
243  socket.close();
244  logger.error("socket closed");
245  this.stop = stop;
246 
247  }
248  }
249 
250  public void stop(){
251  setStop(true);
252  }
253 
254  protected void finalize() {
255  try {
256  logger.error("Trying to close socket");
257  socket.close();
258  logger.error("Socket Closed");
259  }
260  catch (Exception e)
261  {
262  logger.error("Could not close socket");
263  }
264  }
265 
266 
267 
268 
269 
270 
271 }
grl.flatbuffer.KUKAiiwaState getPrevMessage()
grl.flatbuffer.KUKAiiwaState getCurrentMessage()
UDPManager(String laptopIP, String laptopPort, ITaskLogger errorlogger)
Definition: UDPManager.java:40
boolean sendMessage(byte[] msg, int size)
grl.flatbuffer.KUKAiiwaState waitForNextMessage()
void setStop(boolean stop)
boolean isStop()
boolean connect()
Definition: UDPManager.java:60