giovedì 22 maggio 2014

Da Debian Stable a Testing

A causa di un programma che mi richiede una versione di GLibC moderna (almeno 2.18) ho dovuto abbandonare Debian Stable (dove e' presente la versione 2.13) per passare nel ramo Unstable


Dato che non avevo voglia di ripartire da una installazione da zero ho provato a fare il dist-upgrade.

La procedura, anche se un po' lunga, e' piuttosto semplice
in /etc/apt/sources si sostituisce la stringa stable con testing

apt-get update
apt-get --download-only dist-upgrade
apt-get dist-upgrade

il sistema e' ripartito correttamente senza particolari problemi

mercoledì 21 maggio 2014

IBeacon e direzione

Ho fatto qualche prova per vedere di poter replicare la navigazione con i radiofari (beacon) che veniva utilizzata in aeronautica prima dell'avvento delle nuove tecnologie

In pratica si puo' fare navigazione mettendo un trasmettitore con una antenna omnidirezionale (beacon) ed un ricevitore con una antenna direzionale. In questo modo l'aereo punta direttamente sul radiofaro massimizzando il segnale nella propria antenna direzionale

Si puo' fare qualcosa di simile con IBeacon ed i telefoni cellulari??
Per la prova ho preso un Motorola G ed un AprilBeacon ed ho scritto una piccola applicazione che legge i valori di RSSI di BT4
Dopo ogni serie di misure ho ruotato il telefono di 90° (mantenendolo alla stessa distanza) e ripreso le misure (l'angolo 0° coincide con il telefono puntato in direzione del beacon e 180° con il telefono orientato in direzione opposta al beacon

Serie 1
Come era lecito attendersi i valori di RSSI sono molto variabili e danno luogo a grandi valori della standard deviation. In ogni caso l'orientazione a 90° sembra sensibilmente quella con valori minori



Serie 2
nella serie 2 i dati dell'angolo 0° sono decisamente anomali. In ogni caso si ha che ancora l'angolo 90° mostra i valori minori

In sostanza sembra che ci sia una certa direzionalita' nelle antenna BT dei telefoni cellulari ma i valori di RSSI sono cosi' poco affidabili da rendere sostanzialmente impossibile utilizzare nel mondo reale tale metodo


lunedì 12 maggio 2014

Da SMB Share name a IP

Per trovare l'indirizzo IP di una connessione SMB  sotto Windows e'  sufficiente richiamare il comando NBTSTAT seguito dal nome del computer

Per esempio

nbtstat -a hw2229



giovedì 8 maggio 2014

Illegal Operation su OpenNi e IBM X40

Ho compilato da sorgenti le librerie OpenNI e PyOpenNI sul mio IBM X40 per poter usare il programmino per gestire il Kinect gia' visto in questi post



Con sopresa pero' lo script genera un errore di "Illegal Operation"
Dopo un po' di ricerche ho scoperto che OpenNi e' ottimizzato per utilizzare le estensioni delle istruzioni del processore SSE3 mentre il Centrino montato sull'X40 ammette solo le estensioni SSE2

In conclusione non si puo' usare Kinect accoppiato all'IBM X40

mercoledì 7 maggio 2014

Kinect per Belle Arti

Continuando gli esperimenti con Kinect ho provato ad acquisire la mappa di profondita' di un basso rilievo. Nello specifico si tratta dei fregi che si trovano sulla base dei leoni delle leonesse nel Piazzale delle Cascine a Firenze
Come si puo' osservare i risultati sono buoni (anche se un po' rumorosi) e le scansioni permettono si osservare dettagli anche molto fini

Fregio 1
Immagine di profondita'


Immagine RGB (da fotocamera)



Fregio 2 
Immagine di profondita'
Immagine RGB da Kinect



Bluetooth ed Android

Questa piccola applicazione interfaccia i sensori di Android  con un PC mediante Bluetooth.
In pratica viene avviata una connessione BT tra PC ed telefono e vengono passati i valori di azimuth, pitch e roll del telefono; dopo aver inviato la prima terna di valore il socket viene interrotto

Importanti: i due dispositivi devono essere gia' stati accoppiati in precedenza ed il BT deve essere gia' abilitato sul telefono


Lato Android
-------------------------------------------------
package com.luca.innocenti.btsensors;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

import android.support.v7.app.ActionBarActivity;
import android.support.v4.app.Fragment;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.hardware.Sensor;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.SensorEvent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.TextView;

@SuppressLint("NewApi")
public class MainActivity extends ActionBarActivity {

private static final String TAG = "BT";

//Bluetooth
public BluetoothAdapter mBluetoothAdapter;
public  BluetoothDevice mmDevice;
public BluetoothSocket mmSocket;
public OutputStream mmOutputStream;

//Sensori
public SensorManager mSensorManager;
    public Sensor mSensor;
    public double azimuth;
    public double pitch;
    public double roll;
    



@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);


setContentView(R.layout.activity_main);

if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}

//Ricerca BT
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
   if(mBluetoothAdapter == null) {
     Log.d(TAG,"No bluetooth adapter available");
   }

   if(!mBluetoothAdapter.isEnabled()) {
     startActivityForResult( new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), 0);
   }

   Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
   if(pairedDevices.size() > 0) {
     for(BluetoothDevice device : pairedDevices) {
       if(device.getName().equals("debian-x40-0")) { //qui si deve mettere il nome BT del PC
        Log.d(TAG,device.getName()+" "+device.getAddress() );
       
         mmDevice = device;
         break;
       }
     }
   }
//apre connessione
   UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard //SerialPortService ID
   try {
mmSocket = mmDevice.createInsecureRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}    
   try {
mmSocket.connect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
   try {
mmOutputStream = mmSocket.getOutputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
   
   //sensori
    mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
    mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);  
   
    
}


private void send_string(final String dati)
{
for (int t=0;t<dati.length();t++)
{
try {
mmOutputStream.write(dati.charAt(t));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

private final SensorEventListener mListener = new SensorEventListener() {
//manda una terna di valori pitch,roll ed azimuth e poi termina l'applicazione
public void onSensorChanged(SensorEvent event) {
   azimuth = event.values[0];
           pitch = event.values[1];
           roll = event.values[2];
              
           send_string(Double.toString(azimuth));
           send_string("A");
           send_string(Double.toString(pitch));
           send_string("A");
           send_string(Double.toString(roll));
           send_string("A");
           
           try {
mmSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
           //termina l'applicazione dopo la prima lettura
           finish();
           moveTaskToBack(true);
           android.os.Process.killProcess(android.os.Process.myPid());

           
           }

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub

}
};
 
    @Override
   protected void onResume()
   {
       super.onResume();
       mSensorManager.registerListener(mListener, mSensor,SensorManager.SENSOR_DELAY_GAME);
   }

   @Override
   protected void onStop()
   {
       mSensorManager.unregisterListener(mListener);
       super.onStop();
   }

   @Override
   protected void onDestroy()
   {
       mSensorManager.unregisterListener(mListener);
       super.onDestroy();
   }

   @Override
public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}

/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {


public PlaceholderFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}


}
----------------------------------------------------

Lato PC (Python)
-----------------------------------------------------
from bluetooth import *

server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)

port = server_sock.getsockname()[1]

uuid = "00001101-0000-1000-8000-00805F9B34FB"

advertise_service( server_sock, "SampleServer",
    service_id = uuid,
    service_classes = [ uuid, SERIAL_PORT_CLASS ],
    profiles = [ SERIAL_PORT_PROFILE ]
)


client_sock, client_info = server_sock.accept()
misura = ""

try:
    while True:
        data = client_sock.recv(1024)
        if len(data) == 0: break
        if data == 'A':
print misura
misura = ""
else:
misura = misura + data

except IOError:
    pass

client_sock.close()
server_sock.close()


Riduzione di dimensione di file mp3 con lame

Per una piccola applicazione devo mettere negli asset del progetto Android dei file mp3.


Trattandosi di un testo letto senza musica si puo' anche abbassare al massimo il rate del file.
Per questo si puo' usare lame con la stringa

lame --mp3input -b 8 input.mp3 output.mp3

Per esempio questo file (MPEG ADTS, layer III, v1,  32 kbps, 44.1 kHz, Monaural) della dimensione di 64470 byte e' stato convertito in questo file (8.mp3: MPEG ADTS, layer III,  v2.5,   8 kbps, 8 kHz, Monaural) della dimensione di 16272 byte con una compressione di circa 4 volte

Lame ha una serie di ottimizzazioni implicite per cui e' sostanzialmente inutile effettuare tentativi manuali

(Per ottenere le informazioni sui file mp3 si puo' usare il comando file)

Opencv camera calibration in cpp

Oltre che con uno script Python come visto qui la calibrazione della camera si puo' fare anche con il programma in CPP Questo il proce...