giovedì 3 gennaio 2013

Aggiunge PPA ad Ubuntu dietro ad un proxy



Installare repository PPA ad Ubuntu da una rete protetta da un proxy web non e' banale
per prima cosa si devono configurare le due variabili di ambiente

export http_proxy=http://mioproxy:8080
export https_proxy=http://mioproxy:8080

questo perche' parte delle connessioni avviene sulla porta 80 e parte sul SSL
puo' accadere che quando si tentano di scaricare le chiavi GPG dal server di Ubuntu si incorra in questo messaggio
------------------------------------------
keyserver.ubuntu.com: Connection timed out
gpgkeys: HTTP fetch error 7: couldn't connect: Connection timed out
gpg: no valid OpenPGP data found.
gpg: Total number processed: 0
------------------------------------------



per scaricare il ppa desiderato ci si deve annotare la key che contraddistingue il PPA e poi si importa a parte la chiave GPG mediante il comando

 apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 EFF8D5ED

che utilizza espressamente la porta 80 per la connessione risolvendo i problemi del proxy


Hello World in QML

E' di oggi la notizia dell'uscita di Ubuntu for Phones e devo ammettere che la cosa mi incuriosisce soprattutto per l'SDK che inizia a venire distribuito

Il linguaggio di programmazione previsto per Ubuntu for Phones e' QML (Qt Modelling Language) che e' incluso nell'SDK di Qt

Con l'occasione mi sono scaricato anche l'ambiente di sviluppo delle Qt 5.0 Beta 2

Ho deciso quindi di fare qualche prova iniziando dal classico Hello World

Per prima cosa si deve creare un nuovo progetto dentro QtCreator selezionando QtQuick 2 UI (per usare le Qt 5.0) e si accede quindi alla finestra di programmazione che e' divisa come al solito in un editor ed in una interfaccia visuale

Editor del codice

Editor della parte visuale
e si inizia subito con un bug; infatti aprendo l'editor visual e dichiarando l'uso di QtQuick 2.0 (la versione legata a Qt 5.0) viene presentato un errore non risolvibile


Scriviamo un po' di codice..il programma mostra semplicemente la scritta Hello World quando si clicca sul pulsante rosso
------------------------------------------------------------

import QtQuick 1.0

Rectangle {
    width: 160; height: 160

    Rectangle {
            id: redSquare
            width: 80; height: 80
            anchors.top: parent.top; anchors.margins: 10; anchors.horizontalCenter: parent.horizontalCenter
            color: "red"

            Text { text: "Click Me"; font.pixelSize: 16; anchors.centerIn: parent }

            MouseArea {
                anchors.fill: parent
                acceptedButtons: Qt.AllButtons
                onPressed: {
                    hello.text = 'Hello World'
               }
                onReleased: {
                    hello.text = ''
               }
            }
        }


    Text {
        id: hello
        anchors.bottom: parent.bottom; anchors.horizontalCenter: parent.horizontalCenter; anchors.margins: 20
        text: ""
    }

}




------------------------------------------------------------


Ok tutto funziona ma.......c'e' un problemino. Per sviluppare sotto Ubuntu for Phones e' necessario importare la seguente libreria


import Ubuntu.Components 0.1

in conclusione si puo' sviluppare praticamente solo usando il sistema operativo Ubuntu (o meglio Ubuntu ToolKit)  e non impiegando il generico SDK di Qt (e di solito io non uso Ubuntu)


mercoledì 2 gennaio 2013

Uso di JFreeChart in Java/NetBeans

L'utilizzo di JFreeChart in NetBeans/Java e' sostanzialmente identico a quello di Android

Per prima cosa si deve creare un progetto come New Java Application e poi si devono linkare le librerie jcommon e jfreechart (le altre librerie comprese nel file zip si possono omettere)


In seguito si deve editare la funzione main come segue
Barre
----------------------------------------

package barre;

import java.awt.Color;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;

/**
 *
 * @author l.innocenti
 */
public class Barre {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
       DefaultCategoryDataset dataset = new DefaultCategoryDataset();
  dataset.setValue(2, "classe1", "1");
  dataset.setValue(7, "classe1", "2");
  dataset.setValue(4, "classe1", "3");
  dataset.setValue(9, "classe1", "4");
  dataset.setValue(6, "classe1", "5");
  JFreeChart chart;
 chart = ChartFactory.createBarChart
("Grafico a barre","Classe", "Valore", dataset,
PlotOrientation.VERTICAL, false,true, false);
  //chart.setBackgroundPaint(Color.yellow);
  //chart.getTitle().setPaint(Color.blue); 
  CategoryPlot p = chart.getCategoryPlot(); 
  p.setRangeGridlinePaint(Color.red); 
  ChartFrame frame1=new ChartFrame("Bar Chart",chart);
  frame1.pack();
  frame1.setVisible(true);
  
//  frame1.setSize(400,350);
    }
}

----------------------------------------


Linee
----------------------------------------

package javaapplication7;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 *
 * @author l.innocenti
 */
public class JavaApplication7 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
   XYSeries series = new XYSeries("XYGraph");
   series.add(1, 1);
   series.add(1, 2);
   series.add(2, 1);
   series.add(3, 9);
   series.add(4, 10);

// Add the series to your data set
   XYSeriesCollection dataset = new XYSeriesCollection();
   dataset.addSeries(series);

// Generate the graph
   JFreeChart chart;   
        chart = ChartFactory.createXYLineChart(
"Grafico XY", // Title
"asse X", // x-axis Label
"asse Y", // y-axis Label
dataset, // Dataset
PlotOrientation.VERTICAL, // Plot Orientation
false, // Show Legend
false, // Use tooltips
false // Configure chart to generate URLs?
);
        
ChartFrame frame = new ChartFrame("Esempio", chart);
frame.pack();
frame.setVisible(true);
    }
}


----------------------------------------





FFT in Android e Java/NetBeans

Per elaborare i dati derivanti dai sensori posti sul telefono puo' essere utile una elaborazione della trasformata in Fourier; per il caso in esame sara' impiegata la libreria JTransform

La libreria si inserisce normalmente all'interno del progetto di NetBeans od Android

Per l'esempio non sono stati usati dati reali ma quelli calcolati dalla funzione

10sin(x)+5sin(x/2(

Grafici da WolframAlpha

il codice Java (quello Android e' identico) e'
------------------------------

package javaapplication1;

import edu.emory.mathcs.jtransforms.fft.DoubleFFT_1D;


/**
 *
 * @author l.innocenti
 */
public class JavaApplication1 {
   

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       int k;
        // numero dei dati 
        int N = 1002;

       DoubleFFT_1D dfft = new DoubleFFT_1D(N);

       double[] data = new double[N];
       double[] outputData = new double[N];

//crea il segnale
       for (k=0;k<N-1;k++) {
            data[k] = 10*Math.sin(Math.toRadians(k))+5*Math.sin(Math.toRadians(k/2));
            //System.out.println(k+";"+data[k]);
        }
     
       
        // si usa Real FFT perche' dati sono reali
        dfft.realForward(data);  
        
        // il risultato viene messo nella matrice dei risultati secondo il formato
        // data[0] = somma di tutti gli input
        // se il numero di dati e' pari a partire dall'indice data[2] si ha la parte reale nell'indice pari e 
        // la parte immaginaria nell'indice dispari
        // data[2*k] = Re[k], 0 <= k < n / 2
        // data[2*k+1] = Im[k], 0 < k < n / 2
        // altrimenti se i dati sono dispari
        // data[2*k] = Re[k], 0 <= k < (n+1)/2
        // data[2*k+1] = Im[k], 0 < k< (n-1)/2
        // per calcolare il valore di frequenza di ogni array 
        // Fs = valore di campionamento in Hz
        // N = numero di punti
        // k = indice della matrice
        // Frequenza = (k*Fs) / n
        //
        //La potenza dello spettro e' data da 
        //sqrt(parte_reale*parte_reale+parte_immaginaria*parte_immaginaria)
        
        if(data.length%2==0){
            for(int i = 0; i < data.length/2; i++){
                outputData[i]= (float) Math.sqrt((Math.pow(data[2*i],2))+(Math.pow(data[2*(i)+1], 2)));
            }
        }else{
            for(int i = 0; i < data.length/2-1; i++){
                outputData[i]= (float) Math.sqrt((Math.pow(data[2*i],2))+(Math.pow(data[2*i+1], 2)));
            }
        }
    }
}
-------------------------------------
Il risultato e' il seguente



domenica 30 dicembre 2012

Giove nel cielo di dicembre

Con il cielo invernale diventa tutto piu' facile


Il punto piu' luminoso e' Giove mentre in basso leggermente verso destra Aldebaran


Ripresa fatta con una fotocamera compatta digitale con tempo di esposizione di circa 10 secondi (e senza treppiede)

venerdì 28 dicembre 2012

Recuperare foto da SD

Scattando foto puo' capitare di cancellare una schedina SD con foto ancora non salvate sul altri supporti

A questo punto risulta utili PhotoRec, un programma multipiattaforma ed a linea di comando, che e' tanto brutto da vedersi quanto efficace nel risultato



una sola avvertenza: le foto salvate vengono messe in una sottodirectory del tipo recup_dir.1

Correzione Nord Magnetico/Geografico su Android

All'interno delle Api del sistema operativo di Android ci sono anche delle funzioni abbastanza inusuali (per un linguaggio di programmazione standard), in particolare c'e' la possibilita' di effettuare il calcolo della declinazione magnetica ovvero della differenza tra la direzione del Nord magnetico e del Nord geografico

In Italia tale differenza e' abbastanza modesta e si puo' trascurare per praticamente tutte le attivita' amatoriali ma in alcuni paesi e' molto influente sulle misure

Per il calcolo della declinazione magnetica Android si basa sul modello matematico rintracciabile a questo link http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml dove viene fornita anche cartografia a scala mondiale e software per ambiente desktop per il calcolo




Come si osserva per il calcolo e' necessario conoscere la posizione del luogo (in latitudine, longitudine ed altezza) e la data di osservazione; dati questi parametri il modello matematico fornisce la declinazione

Per implementare la funzione anche in Android si deve quindi attivare sia il SensorManager (per la bussola) che il LocationManager (per la posizione)...la data viene assunta quella del telefono

Di seguito si riporta un esempio completo di applicazione Android con correzione di Nord Magnetico/Geografico (la parte di codice che gestisce il Gps e' stata ripresa da qui)




ads
activity_compass.xml
----------------------------------------

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Compass" >

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="35dp"
        android:gravity="right"
        android:text="n/a"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/TextView01"
        android:layout_marginTop="29dp"
        android:layout_toRightOf="@+id/textView3"
        android:gravity="right"
        android:text="n/a"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/TextView02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/TextView01"
        android:layout_alignBottom="@+id/TextView01"
        android:layout_alignParentLeft="true"
        android:text="Azimuth Magn.North:"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/TextView03"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/textView1"
        android:layout_alignBottom="@+id/textView1"
        android:layout_alignParentLeft="true"
        android:text="Magnetic Declination:"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/TextView04"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/textView2"
        android:layout_alignBottom="@+id/textView2"
        android:layout_alignParentLeft="true"
        android:text="Azimuth True North:"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/TextView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="34dp"
        android:gravity="right"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView2"
        android:layout_centerHorizontal="true"
        android:text="--------"
        android:textAppearance="?android:attr/textAppearanceSmall" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView3"
        android:layout_centerHorizontal="true"
        android:text="Waiting Gps Signal"
        android:textAppearance="?android:attr/textAppearanceSmall" />

</RelativeLayout>

----------------------------------------
Compass Manifest
----------------------------------------

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.compass"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.compass.Compass"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

----------------------------------------
Compass.java
----------------------------------------

package com.example.compass;

import java.text.DecimalFormat;
import java.util.List;


import android.hardware.GeomagneticField;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.TextView;

public class Compass extends Activity implements LocationListener{

private boolean sersorrunning;
private SensorManager mySensorManager;
private TextView azimuth;
private double lat;
private double lon;
private double alt;
private TextView az_corr;
private TextView gps;
private LocationManager lm;
private StringBuilder sb;
static final String tag = "Main"; // for Log
int noOfFixes = 0;
private TextView true_north;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_compass);
azimuth = (TextView) findViewById(R.id.TextView01);
az_corr = (TextView)  findViewById(R.id.textView1);
true_north = (TextView)  findViewById(R.id.textView2);
gps = (TextView)  findViewById(R.id.textView4);

mySensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);

lm = (LocationManager) getSystemService(LOCATION_SERVICE);

@SuppressWarnings("deprecation")
List<Sensor> mySensors = mySensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
if(mySensors.size() > 0){
     mySensorManager.registerListener(mySensorEventListener, mySensors.get(0), SensorManager.SENSOR_DELAY_NORMAL);
     sersorrunning = true;
     //Toast.makeText(this, "Start ORIENTATION Sensor", Toast.LENGTH_LONG).show();
   
    }
    else{
     //Toast.makeText(this, "No ORIENTATION Sensor", Toast.LENGTH_LONG).show();
     sersorrunning = false;
     finish();
    }
}

protected void onResume() {
/*
* onResume is is always called after onStart, even if the app hasn't been
* paused

* add location listener and request updates every 1000ms or 10m
*/
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 10f, this);
super.onResume();
}

@Override
protected void onPause() {
/* GPS, as it turns out, consumes battery like crazy */
lm.removeUpdates(this);
super.onPause();
}

@Override
public void onLocationChanged(Location location) {
Log.v(tag, "Location Changed");

sb = new StringBuilder(512);

noOfFixes++;

/* display some of the data in the TextView */

sb.append("No. of Fixes: ");
sb.append(noOfFixes);
sb.append('\n');
sb.append('\n');

sb.append("Londitude: ");
sb.append(location.getLongitude());
sb.append('\n');

sb.append("Latitude: ");
sb.append(location.getLatitude());
sb.append('\n');

sb.append("Altitiude: ");
sb.append(location.getAltitude());
sb.append('\n');

sb.append("Accuracy: ");
sb.append(location.getAccuracy());
sb.append('\n');

sb.append("Timestamp: ");
sb.append(location.getTime());
sb.append('\n');

lat = location.getLatitude();
lon = location.getLongitude();
alt = location.getAltitude();

gps.setText(sb.toString());
}

@Override
public void onProviderDisabled(String provider) {
/* this is called if/when the GPS is disabled in settings */
Log.v(tag, "Disabled");

/* bring up the GPS settings */
Intent intent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}

@Override
public void onProviderEnabled(String provider) {
Log.v(tag, "Enabled");
//Toast.makeText(this, "GPS Enabled", Toast.LENGTH_SHORT).show();

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
/* This is called when the GPS status alters */
switch (status) {
case LocationProvider.OUT_OF_SERVICE:
Log.v(tag, "Status Changed: Out of Service");
//Toast.makeText(this, "Status Changed: Out of Service",
//Toast.LENGTH_SHORT).show();
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
Log.v(tag, "Status Changed: Temporarily Unavailable");
//Toast.makeText(this, "Status Changed: Temporarily Unavailable",
//Toast.LENGTH_SHORT).show();
break;
case LocationProvider.AVAILABLE:
Log.v(tag, "Status Changed: Available");
//Toast.makeText(this, "Status Changed: Available",
//Toast.LENGTH_SHORT).show();
break;
}
}

@Override
protected void onStop() {
/* may as well just finish since saving the state is not important for this toy app */
finish();
super.onStop();
}
   


private SensorEventListener mySensorEventListener = new SensorEventListener(){

private float declinazione;

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

@Override
public void onSensorChanged(SensorEvent event) {

DecimalFormat df = new DecimalFormat("##.##");

azimuth.setText(df.format(event.values[0]));
 
GeomagneticField geoField = new GeomagneticField( 
  Double.valueOf(lat).floatValue(), 
  Double.valueOf(lon).floatValue(),
           Double.valueOf(alt).floatValue(),
           System.currentTimeMillis() );


if (noOfFixes > 0)
{
declinazione = geoField.getDeclination();
az_corr.setText(df.format(declinazione));
true_north.setText(df.format(event.values[0]+declinazione));
}
}

};

@Override
protected void onDestroy() {
super.onDestroy();

if(sersorrunning){
mySensorManager.unregisterListener(mySensorEventListener);
}
}

}


FigSpec FS-60CL

A lavoro mi hanno rifilato questo sensore iperspettrale cinese (pushbroom 400-1000 nm con larghezza di banda di 0.5 nm compatibile con DJI M...