One big step

Sorry if I don’t write, since a long time, but now I’m here with a great step.

How to control your toy-drone through internet.

Well the idea is quite simple, use the gyroscope from the smart phone to control the movements of our drone.
This is made as proof of concept
So to do this project (small exercise) I divided it in three parts

A.- Controller (smart phone) (Java for Android)
B.- Server(cubieboard) (python)
C.- Controller (arduino) (Quite C šŸ™‚ )

Controller

The controller in this case will be a smart phone, which could connect to a server and send the gyroscope’s values.
I justĀ  put the small part of the code, there are lot of examples on internet
I took some ideas from here to took the gyroscope’s value : http://android-er.blogspot.com.es/2010/08/detect-rotation-around-x-y-z-axis-using.html
and there are a lot of examples to create a socket client in java for android.

Just for the proof of concept I took a shortcut and I use the StrictMode.ThreadPolicy to send the data from the main activity. (it’s not a good way I know)

StrictMode.ThreadPolicy politica = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(politica);

And hereĀ  part of the code to send the gyroscope’s values.

private SensorEventListener fSensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event)
{
azimuth = (int)event.values[0];
pitch = (int)event.values[1];
roll = (int)event.values[2];
if (azimuth0==0)
{
azimuth0=azimuth;
}
lblValor.setText(azimuth0 – azimuth + “\n” + pitch +”\n” + roll);
if (enviar)
{
String vectorDireccion = “”;
vectorDireccion = pitch +”:” + rollĀ  ;
try {
os.write(vectorDireccion);
os.flush();
String recibido;
recibido = br.readLine(); // this stop the client till it receives anything (“ok\n” in this case) to avoid the socket overflow
System.out.println(recibido);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
vectorDireccion=””;
}
}

The code could be implemented in a lot of ways.
The main point is to send the values in text mode to the server.

Server

The server has to receive the values from a socket and send it to the serial port. I thought to do it in Java also, but I can’t find a good information about Javax.comm, so I decided to make a merge of knowledge, and use python
It’s quite simple, just receive theĀ  values in text format from the socket and ad “;”Ā  and send the values to the serial port
The server send an “ok” response for every data received, as way to avoid the socket overflow
And control the serial port is really simple and useful.

#!/usr/bin/env python
import socket
import serial
import sys

host = ”
port = 5000
size = 10
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ‘Socket creado’
try:
s.bind((host,port))
except socket.error , msg:
print ‘Error en el bind, codigo: ‘ + str(msg[0]) + ‘\n’ + ‘Error: ‘ + msg[1]
sys.exit()
print ‘Socket bind created’
s.listen(1)
print ‘Socket listening’

(conn, addr) = s.accept()
print ‘Conexion desde ‘ + addr[0] + ‘:’ + str(addr[1])

#Open serial port
ser = serial.Serial(‘/dev/ttyS0’,9600, timeout=1)

while 1:
data = conn.recv(size)
print data.decode(‘utf-8’)
conn.send(‘ok\n’) #Send “ok\n” to avoid the socket overflow
ser.write(data)Ā 
ser.write(‘;’)
conn.close()
s.close()
ser.close()

Controller

The controller is an Arduino with a motorshield from adafruit which can manage 4 electric motors.
This is the most interesting part, the arduino fetch the values from the software serial.
The values are pitch and roll , and must be converted to values to give different power to the right and left wells

Receive values through serial.

I made a library to control the software serial
I fetch the every value whic is terminated in “;”

String puerto::evento()
{//utilizamos el puerto serie para recibir los comandos.
String comando =””;
bool completo=false;
while (mySerial.available() || !completo)
{
if (mySerial.available())
{
char inChar = (char) mySerial.read();
comando +=inChar;
if (inChar == ‘;’)
{
completo=true;
break;
}
}
}
return comando;
}

Converting values into force.

The command received has this formĀ  pitch:roll;

comando= port.evento(); //Command received
pitch = comando.substring(0,comando.indexOf(‘:’)).toInt();
roll=(comando.substring(comando.indexOf(‘:’)+1)).toInt();

Drawing the forces

Drawing the forces

/*
this part could be a little bit complicated to describe.
But the idea is quite simple, is to convert the pitch and roll values into a vector
The forces inside the vehicle come from the wheels and are decomposed in their components.
Also the values of pitch and roll are decomposed and we can do a vectorial sum.

*/

void avanzar ( int pitch, int roll)
{
uint8_t potencia =sqrt(sq(pitch)+sq(roll));
uint8_t velIzquierda;
uint8_t velDerecha;
float factor = abs((float)roll/ (float)potencia);
Serial.print(“Potencia:”);
Serial.println(potencia);
Serial.print(“Factor:”);
Serial.println(factor);

if (roll < -10 ) //girar derecha
{//es la izquierda la que dirige
Serial.println(“DERECHA”);
avanzaIzquierda(potencia);
avanzaDerecha (potencia * (1 – factor));
}
if (roll > 10 ) // girar izquierda
{//Es la derecha la que dirige
Serial.println(“IZQUIERDA”);
avanzaDerecha(potencia);
avanzaIzquierda(potencia * (1-factor));
}

if ((roll > -10 )&& (roll < 10) && (pitch >10))
{
avanzaIzquierda(potencia);
avanzaDerecha(potencia);
}

}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s