This repository has been archived by the owner on Mar 21, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathClienteKhepera.java
402 lines (333 loc) · 13.2 KB
/
ClienteKhepera.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.lang.Thread.sleep;
public class ClienteKhepera
{
//Factor de aprendizaje
public static final double BETA = 0.9;
//Tasa de descuento
public static final double GAMMA = 0.5;
//Numero de episodios
public static final int NUMERO_EPISODIOS = 50000;
static final int CANT_ESTADOS = 256;
static final int CANT_ACCIONES = 16;
static final int ACCION_IZQ_M15_DER_M15 = 0;
static final int ACCION_IZQ_M15_DER_10 = 1;
static final int ACCION_IZQ_M15_DER_15 = 2;
static final int ACCION_IZQ_M15_DER_20 = 3;
static final int ACCION_IZQ_10_DER_M15 = 4;
static final int ACCION_IZQ_10_DER_10 = 5;
static final int ACCION_IZQ_10_DER_15 = 6;
static final int ACCION_IZQ_10_DER_20 = 7;
static final int ACCION_IZQ_15_DER_M15 = 8;
static final int ACCION_IZQ_15_DER_10 = 9;
static final int ACCION_IZQ_15_DER_15 = 10;
static final int ACCION_IZQ_15_DER_20 = 11;
static final int ACCION_IZQ_20_DER_M15 = 12;
static final int ACCION_IZQ_20_DER_10 = 13;
static final int ACCION_IZQ_20_DER_15 = 14;
static final int ACCION_IZQ_20_DER_20 = 15;
// No es una de las acciones que realiza khepera
static final int ACCION_LEER_SENSORES = 24;
//Valor de sensor considerado como posible choque
static final int VALOR_CHOQUE = 700;
double[][] tabla_q = new double [CANT_ESTADOS][CANT_ACCIONES];
int iteracion = 1;
double epsilon = 0.9;
int sum_sensor_Front = 0, sum_sensor_Back = 0;
int auxiliar = 0, auxiliar2 = 0;
// call our constructor to start the program
public static void main(String[] args)
{
new ClienteKhepera();
}
public void ejecutar( ) {
String testServerName = "localhost";
int port = 6800;
Socket socket = null;
double cotasuperior = Math.exp(NUMERO_EPISODIOS);
try
{
// open a socket
double q_actual;
double q_max;
double q_nuevo;
//Posicion de estado en la tabla Q
int pos_estado;
int nuevo_pos_estado;
int accion;
double recompensa;
inicializarValoresQ(0.0);
socket = openSocket(testServerName, port);
pos_estado = this.getEstado(socket); /// cambiado
while( iteracion != NUMERO_EPISODIOS ) {
//socket = openSocket(testServerName, port);
//Recuperar estado desde robot
//pos_estado = this.getEstado(socket); ///
accion = seleccionarAccion( pos_estado );
socket = openSocket(testServerName, port);
//Ejecuta accion
ejecutarAccion( accion, socket);
socket = openSocket(testServerName, port);
//Nuevo estado luego de ejecutar la accion
nuevo_pos_estado = this.getEstado(socket);
//Calcula la recompensa para el nuevo par estado-accion
recompensa = getRecompensa();
q_actual = tabla_q[pos_estado][accion];
q_max = getMaxQ(nuevo_pos_estado);
// Calculate new Value for Q
q_nuevo = q_actual + BETA * ( recompensa + GAMMA * q_max - q_actual );
tabla_q[pos_estado][accion] = q_nuevo;
// Set state to the new state.
pos_estado = nuevo_pos_estado;/// cambiado
iteracion++;
if (iteracion % 2000 == 0){
if(epsilon > 0.2){
epsilon -= 0.1;
}
}
//epsilon = epsilon - (epsilon*(1/(Math.exp(NUMERO_EPISODIOS) - Math.exp(iteracion))));
System.out.println("iteracion:: "+ iteracion+" --------- Epsion :: "+epsilon);
}
// close the socket, and we're done
socket.close();
}
catch (Exception e)
{
e.printStackTrace();
}
} // end ejecutar
//Inicializar la matriz de valores Q
public void inicializarValoresQ(double valorInicial){
for (int i = 0 ; i <CANT_ESTADOS; i++) {
for (int j=0; j < CANT_ACCIONES ; j++) {
tabla_q[i][j]=valorInicial;
}
}
}
//Ejecutar accion en el servidor
//OJO Esto puede cambiarse dejando dos parametros indicando las velocidades de las ruedas y sacando el switch
public String ejecutarAccion(int accion, Socket socket){
String respuesta = "NO MIRAR!!";
try{
switch (accion){
case ACCION_IZQ_M15_DER_M15:{
writeToAndReadFromSocket(socket, "2,-15,-15"+"\0");
break;
}
case ACCION_IZQ_M15_DER_10:{
writeToAndReadFromSocket(socket, "2,-15,10"+"\0");
break;
}
case ACCION_IZQ_M15_DER_15:{
writeToAndReadFromSocket(socket, "2,-15,20"+"\0");
break;
}
case ACCION_IZQ_M15_DER_20:{
writeToAndReadFromSocket(socket, "2,-15,30"+"\0");
break;
}
case ACCION_IZQ_10_DER_M15:{
writeToAndReadFromSocket(socket, "2,10,-15"+"\0");
break;
}
case ACCION_IZQ_10_DER_10:{
writeToAndReadFromSocket(socket, "2,10,10"+"\0");
break;
}
case ACCION_IZQ_10_DER_15:{
writeToAndReadFromSocket(socket, "2,10,20"+"\0");
break;
}
case ACCION_IZQ_10_DER_20:{
writeToAndReadFromSocket(socket, "2,10,30"+"\0");
break;
}
case ACCION_IZQ_15_DER_M15:{
writeToAndReadFromSocket(socket, "2,20,-15"+"\0");
break;
}
case ACCION_IZQ_15_DER_10:{
writeToAndReadFromSocket(socket, "2,20,10"+"\0");
break;
}
case ACCION_IZQ_15_DER_15:{
writeToAndReadFromSocket(socket, "2,20,20"+"\0");
break;
}
case ACCION_IZQ_15_DER_20:{
writeToAndReadFromSocket(socket, "2,20,30"+"\0");
break;
}
case ACCION_IZQ_20_DER_M15:{
writeToAndReadFromSocket(socket, "2,30,-15"+"\0");
break;
}
case ACCION_IZQ_20_DER_10:{
writeToAndReadFromSocket(socket, "2,30,10"+"\0");
break;
}
case ACCION_IZQ_20_DER_15:{
writeToAndReadFromSocket(socket, "2,30,20"+"\0");
break;
}
case ACCION_IZQ_20_DER_20:{
writeToAndReadFromSocket(socket, "2,30,30"+"\0");
break;
}
case ACCION_LEER_SENSORES:{
respuesta = writeToAndReadFromSocket(socket, "24"+"\0");
break;
}
default:{
System.out.println("ACCION INVALIDA");
}
}
} catch (Exception ex) {
Logger.getLogger(ClienteKhepera.class.getName()).log(Level.SEVERE, null, ex);
}
return respuesta;
}
//Recupera la posicion de estado actual
public int getEstado(Socket socket){
String valorSensores;
String[] arr;
int[] arr_int = new int[8];
int pos_estado =0;
auxiliar2 = 0;
//Consultar valor de sensores y control de falta de respuesta
valorSensores = this.ejecutarAccion(ACCION_LEER_SENSORES, socket);
//System.out.println("Valores Sensores es:: "+valorSensores);
arr = valorSensores.split(";");
for(int j=0; j<8; j++){
//System.out.println("Arr en "+j+" ES:: "+ arr[j]);
arr_int[j]= Integer.parseInt(arr[j]);
auxiliar2 += arr_int[j];
if(arr_int[j] > VALOR_CHOQUE){
arr_int[j]=1;
}
else{
arr_int[j]=0;
}
}
sum_sensor_Front = arr_int[0] +arr_int[1] +arr_int[2] +arr_int[3] +arr_int[4] +arr_int[5];
sum_sensor_Back = arr_int[6] +arr_int[7];
//Calcula la posicion de estado en base al valor de los sensores discretizados
for(int i=0; i<8;i++){
pos_estado += arr_int[i]*(Math.pow(2.0, i));
}
return pos_estado;
}
private int seleccionarAccion( int estado ) {
int pos_accion = 0;
double max_val=tabla_q[estado][0];
for (int i=1; i< CANT_ACCIONES; i++) {
if(tabla_q[estado][i] > max_val) {
max_val=tabla_q[estado][i];
pos_accion = i;
}
}
int cant_exploracion;
//Explore
if ( Math.random() < epsilon ) {
cant_exploracion = ((CANT_ACCIONES -1 )/ 2) - (int)((0.9 - epsilon) * ((CANT_ACCIONES -1 )/ 2));
System.out.println("Cantidad de exploracion"+cant_exploracion);
pos_accion = (pos_accion + cant_exploracion) % CANT_ACCIONES;//(int)(Math.random() * CANT_ACCIONES)) % CANT_ACCIONES;
}
return pos_accion;
}
public double getRecompensa(){
System.out.println("auxiliar 1 : "+ auxiliar + "-----auxiliar2 "+ auxiliar2);
if(auxiliar - auxiliar2 > 200){
System.out.println("Recompensa positiva");
auxiliar = auxiliar2;
return 1;
}
else{
auxiliar = auxiliar2;
if(sum_sensor_Front > 1000||sum_sensor_Back > 850){
System.out.println("Recompensa negativa");
return -1;
}
System.out.println("Recompensa neutra");
return 0;
}
}
private double getMaxQ(int estado){
double max_val=tabla_q[estado][0];
for (int i=1; i< CANT_ACCIONES; i++) {
if(tabla_q[estado][i] > max_val) {
max_val=tabla_q[estado][i];
}
}
return max_val;
}
public ClienteKhepera()
{
ejecutar();
}
private String writeToAndReadFromSocket(Socket socket, String writeTo) throws Exception
{
try
{
// write text to the socket
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bufferedWriter.write(writeTo);
bufferedWriter.flush();
// read text from the socket
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuilder sb = new StringBuilder();
String str;
while ((str = bufferedReader.readLine()) != null)
{
System.out.println("STR::"+ str);
sb.append(str);
}
// close the reader, and return the results as a String
bufferedReader.close();
return sb.toString();
}
catch (IOException e)
{
e.printStackTrace();
throw e;
}
}
/**
* Open a socket connection to the given server on the given port.
* This method currently sets the socket timeout value to 10 seconds.
* (A second version of this method could allow the user to specify this timeout.)
*/
private Socket openSocket(String server, int port) throws Exception
{
Socket socket;
// create a socket with a timeout
try
{
InetAddress inteAddress = InetAddress.getByName(server);
SocketAddress socketAddress = new InetSocketAddress(inteAddress, port);
// create a socket
socket = new Socket();
// this method will block no more than timeout ms.
int timeoutInMs = 10*1000; // 10 seconds
socket.connect(socketAddress, timeoutInMs);
return socket;
}
catch (SocketTimeoutException ste)
{
System.err.println("Timed out waiting for the socket.");
ste.printStackTrace();
throw ste;
}
}
}