Navigatore virtuale 3D - Christian Paoliello Giacomo Poretti - in SUPSI Tesi

Pagina creata da Mattia Di Martino
 
CONTINUA A LEGGERE
Navigatore virtuale 3D - Christian Paoliello Giacomo Poretti - in SUPSI Tesi
Navigatore virtuale 3D

Studente/i               Relatore

Christian Paoliello      Giacomo Poretti

                         Correlatore

                         -

                         Committente

                         -

Corso di laurea          Modulo

Ingegneria informatica   M00002 - Progetto di diploma

Anno

2017/18

Data

9 settembre 2018
Navigatore virtuale 3D - Christian Paoliello Giacomo Poretti - in SUPSI Tesi
Navigatore virtuale 3D - Christian Paoliello Giacomo Poretti - in SUPSI Tesi
i

Indice

1 Abstract                                                                                       1

2 Progetto assegnato                                                                             3
   2.1 Descrizione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      3
   2.2 Compiti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    3
   2.3 Obbiettivi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   4
   2.4 Tecnologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     4

3 Introduzione                                                                                  5
   3.1 Scanner 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       6
   3.2 Fotogrammetria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       7
   3.3 Formati point cloud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      7

4 Point cloud renderer                                                                          11
   4.1 Octree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
   4.2 Potree converter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
   4.3 Funzionalità di Potree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
   4.4 Informazioni utili per interagire con Potree . . . . . . . . . . . . . . . . . . . . 17

5 Sviluppo                                                                                      21
   5.1 Conversione WGS84 a LV95 . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
   5.2 Movimento della camera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
   5.3 Calcolo altitudine per camera . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
   5.4 Rilevazione ostacoli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
   5.5 Lettura coordinate GPS - Firebase . . . . . . . . . . . . . . . . . . . . . . . . 29
   5.6 Pulizia point cloud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

6 Risultati e conclusione                                                                       35
   6.1 Risultati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
   6.2 Difficoltà incontrate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
   6.3 Considerazioni finali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

                                                                          Navigatore virtuale 3D
Navigatore virtuale 3D - Christian Paoliello Giacomo Poretti - in SUPSI Tesi
ii                       INDICE

Navigatore virtuale 3D
Navigatore virtuale 3D - Christian Paoliello Giacomo Poretti - in SUPSI Tesi
iii

Elenco delle figure

 3.1 Stanford bunny      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    5
 3.2 Leica lidar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      6
 3.3 Point cloud acquisito da un lidar Leica . . . . . . . . . . . . . . . . . . . . . .        6
 3.4 Drone Phantom 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .          7
 3.5 Zona di Cornaredo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .          8
 3.6 Zona di Cornaredo da vicino . . . . . . . . . . . . . . . . . . . . . . . . . . .          8

 4.1 LOD in un octree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
 4.2 Point cloud di esempio "Lion" su Potree . . . . . . . . . . . . . . . . . . . . . 13
 4.3 Octree di Potree nel filesystem . . . . . . . . . . . . . . . . . . . . . . . . . . 14
 4.4 Octree boxes      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
 4.5 Punto selezionato . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
 4.6 Distanza misurata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
 4.7 Volume clipping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
 4.8 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
 4.9 Struttura root in Chrome      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

 5.1 WGS84       . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
 5.2 Conversione WGS84->LV95 . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
 5.3 South S660P       . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
 5.4 Prova di segmentazione        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
 5.5 Rilevazione di ostacoli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
 5.6 Percorso effettuato dai dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
 5.7 Point cloud originale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
 5.8 Point cloud modificato . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

 6.1 GPS sopra la macchina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

                                                                        Navigatore virtuale 3D
Navigatore virtuale 3D - Christian Paoliello Giacomo Poretti - in SUPSI Tesi
iv                       ELENCO DELLE FIGURE

Navigatore virtuale 3D
Navigatore virtuale 3D - Christian Paoliello Giacomo Poretti - in SUPSI Tesi
1

Capitolo 1

Abstract

Il progetto prevede la realizzazione di un applicazione in grado di visualizzare in un point
cloud l’ambiente che circonda un veicolo attraverso l’uso di un apparecchio GPS specifico.
L’applicazione deve assistere la guida di veicoli in condizioni di visibilità minima.

Come visualizzatore di point cloud si è optato per Potree, un renderer scritto in javascript che
gira su browser grazie al motore grafico WebGL. In questo modo l’applicazione può essere
eseguita su diversi sistemi operativi e dispositivi finchè essi sono dotati di un browser.

È stato inoltre sviluppato come obbiettivo aggiuntivo un algoritmo che basandosi sull’e-
levazione stradale evidenzia gli ostacoli intorno al veicolo. L’approccio risulta comunque
più adatto come operazione di pre-processing piuttosto che in real-time a causa del tem-
po necessario ad analizzare i punti, che è di circa un secondo per una superficie 400m2
(altamente dipendente dalla densità di punti).

Il progetto dimostra la fattibilità dell’usare un point cloud dell’ambiente circostante come
supporto alla guida, sincronizzando la posizione e direzione nel point cloud con quelle reale
del veicolo.

                                                                          Navigatore virtuale 3D
Navigatore virtuale 3D - Christian Paoliello Giacomo Poretti - in SUPSI Tesi
2                                                                                   Abstract

The project involves the implementation of an application which can display in a point cloud
the surrounding environment of a vehicle thanks to a specific GPS device. The application
must assist driving in poor visibility conditions.

Potree was chosen to display point clouds, a renderer written in javascript which can run
in all the browsers supporting WebGL. In this way the application can run on a variety of
operating systems and devices as long as they have a browser.

As an additional goal an algorithm has been developed which highlights obstacles around
the vehicle based on the elevation of the road. This approach however is more suitable to
be a pre-processing step instead of being used in real-time because of the time needed to
analyse the points, which is about one second for a 400m2 surface (highly dependent on the
point density).

The project demonstrates the feasibility of using a point cloud of the surrounding environ-
ment to assist your driving, synchronising the position and direction in the point cloud with
the real ones of the vehicle.

Navigatore virtuale 3D
Navigatore virtuale 3D - Christian Paoliello Giacomo Poretti - in SUPSI Tesi
3

Capitolo 2

Progetto assegnato

2.1    Descrizione

Il progetto richiede lo sviluppo di un navigatore a supporto di veicoli in condizioni estreme di
poca visibilità (notte), strada coperta da neve o altri fattori.
L’applicazione richiede la ricostruzione dello scenario virtuale tramite nuvola di punti / mondo
3D. La nuvola di punti è gia definita/conosciuta e memorizzata all’interno del dispositivo (PC
o table : da valutare).
Il primo prototipo prevede la visualizzazione dei dati su schemo (tablet / PC), potrà essere
valutata anche la visualizzazione dei dati su appositi visori.
La soluzione prevede l’utilizzo di sensori "south surveying" già predisposti per l’invio di
informazioni GPS del veicolo a un apposito server poi predisposto per l’invio di queste
informazioni all’applicazione in tempo reale.
Requisito fondamentale è quindi la connettività internet sul veicolo (scheda 3G/4G).
Sulla base di queste informazioni l’applicazione dovrà visualizzare l’ambiente circostante,
nell’orientamento relativo al movimento del veicolo in modo da permettere all’autista di
muoversi correttamente e rimanere nel campo stradale pur non essendo questo visibile
e riconoscibile.
Posizione GPS : fornita dai server di Device SA
Orientamento : ricavato dalle posizioni nel tempo
Per le tecnologia di rendering si vuole fare affidamento su librerie open source : per es.
Potree (potree.org) basate su WebGL quindi utilizzabili all’interno del browser

2.2    Compiti

Sviluppo di un programma di visualizzazione e navigazione all’interno di un "Point Cloud"
guidato dalla posizione GPS del veicolo.

                                                                         Navigatore virtuale 3D
Navigatore virtuale 3D - Christian Paoliello Giacomo Poretti - in SUPSI Tesi
4                                                                          Progetto assegnato

2.3    Obbiettivi
Garantire un allineamento fra scena rappresentata sullo schermo e realtà effettiva di quello
che il conducente vedrebbe in condizioni reali.

2.4    Tecnologie
    • Utilizzo di soluzioni open source per esempio Potree all’interno di un browser o tramite
      programma ad-hoc (da definire)

    • WebGL, Javascript, eventualmente shader code (GLSL)

    • Utilizzo di sensori "south surveying" forniti dall’azienda e connessione ai server dell’a-
      zienda per il recupero delle informazioni GPS

Navigatore virtuale 3D
5

Capitolo 3

Introduzione

Una nuvola di punti, chiamata comunemente point cloud, è un insieme di punti definiti in un
determinato sistema di coordinate. Questi punti sono dei vertici identificati da coordinate X,
Y, e Z, a volte anche colorati, che nel loro insieme rappresentano superfici di oggetti. Ov-
viamente per suggerire l’oggetto che si vuole rappresentare il numero di punti deve essere
elevato. Le applicazioni dei point cloud sono principalmente legati agli ambiti della computer
grafica, ma si trovano anche applicazioni in campo medico e geografico (GIS).
Uno dei principali vantaggi di optare per un point cloud è poter digitalizzare in modo molto
dettagliato una scena reale, mantenendo intatte forme e dimensioni dei vari oggetti per poi
poterli analizzare in un secondo tempo.
Una pratica che è comune fare è trasformare delle superfici nel point cloud in mesh così da
avere più utilizzi come in progetti di animazione oppure progetti CAD.

                                       Source:
Source: http://graphics.stanford.      https://imatge.upc.edu/web/sites/
edu/data/3Dscanrep/                    default/files/pub/cPujol-Miro17.pdf

                                 Figura 3.1: Stanford bunny

I metodi più diffusi per creare un point cloud da una scena reale sono la scannerizzazione

                                                                         Navigatore virtuale 3D
6                                                                                Introduzione

                                  Source:
                                  https://en.wikipedia.org/
                                  wiki/3D_scanner

                                   Figura 3.2: Scanner Leica

                         Source: http://www.revittunes.com/

                   Figura 3.3: Point cloud acquisito da uno scanner Leica

laser e la fotogrammetria.

3.1    Scanner 3D

La tipologia più utilizzata di laser scanner è il cosiddetto laser a tempo di volo. Questo de-
termina la distanza di un oggetto misurando il tempo di andata e ritorno di un impulso di
luce. Il laser misura la distanza soltanto del primo punto che esso incrocia, per scanneriz-
zare l’intero campo visivo o si ruota il diodo emettitore o si ricorre ad un sistema di specchi
rotanti per deviare il raggio. Questi scanner possono arrivare ad una precisione millimetrica
e misurare anche fino a 100,000 punti al secondo.

Navigatore virtuale 3D
7

                  Source: www.techradar.com

                               Figura 3.4: Drone Phantom 4

3.2    Fotogrammetria
La fotogrammetria non è un termine limitato ai point cloud bensì si riferisce alla tecnica
con cui si ottengono delle misurazioni geometriche quali forma, dimensione e posizione
di un oggetto mediante l’uso di fotografie, senza quindi emettere impulsi elettromagnetici.
Consiste nell’acquisire diverse foto di uno stesso oggetto da angolazioni e posizioni diverse.
Dei software processano poi le immagini e trovano i punti in comune così da collegare le
varie immagini. In ogni fotografia si può tracciare un raggio tra la posizione della camera
ed un punto nella foto, l’intersezione di questi raggi permette di triangolare la posizione
dei punti. Un caso speciale di fotogrammetria che usa questo genere di triangolazione si
chiama stereofotogrammetria.
Il point cloud che ho usato nella mia tesi è stato acquisito con questo sistema, la camera
era montata su un drone DJI Phantom 4.
A causa della lunghezza del point cloud (maggiore di 2km) la figura 3.5 mostra solo tre parti
delle dieci totali, la zona soggetta è il quartiere Cornaredo del comune di Lugano.

3.3    Formati point cloud
Esistono diversi modi per immagazzinare i dati di un point cloud e quindi diversi formati di
file. Non esiste uno standard unico, però i formati che si usano comunemente sono meno
di una decina.

   • PLY
      Conosciuto come Polygon File Format, esiste una versione binaria compatta ed una
      ASCII più human readable, entrambe hanno un header dove viene specificato il nu-
      mero di vertici e poligoni nel file. A parte le coordinate x, y, e z altre informazioni
      possono essere colore e normale dei vertici. Il seguente è un esempio di point cloud
      in PLY:

                                                                       Navigatore virtuale 3D
8                                                                  Introduzione

                             Figura 3.5: Zona di Cornaredo

                         Figura 3.6: Zona di Cornaredo da vicino

Navigatore virtuale 3D
9

 ply
 format ascii 1.0
 element vertex 2
 property float x
 property float y
 property float z
 property float nx
 property float ny
 property float nz
 property float intensity
 property uchar diffuse_red
 property uchar diffuse_green
 property uchar diffuse_blue
 end_header
 13.32 12.84 3.06 -0.352745 -0.230493 0.906887 1 255 243 245
 13.44 12.84 3.06 0.135449 -0.0514792 0.989446 1 255 244 242

• PTS
 Formato che viene usato tra altri dal software Cyclone della Leica. La prima linee
 contiene il numero di punti, le altre valori x, y, z, intensità (frazione di luce riflessa), r,
 g, b. Questo è il formato del point cloud che ho usato.

• PTX
 Formato ASCII che utilizza scansioni separate, ognuna con un proprio sistema di
 coordinate. L’header contiene una matrice di trasformazione per ogni point cloud.
 Anche questa come PTS ha sette colonne ed è usata tra altri da Cyclone.
 Esempio di header:
 number of columns
 number of rows
 st1 st2 st3 ; scanner registered position
 sx1 sx2 sx3 ; scanner registered axis ’X’
 sy1 sy2 sy3 ; scanner registered axis ’Y’
 sz1 sz2 sz3 ; scanner registered axis ’Z’
 r11 r12 r13 0 ; transformation matrix
 r21 r22 r23 0 ; this is a simple rotation and translation 4x4 matrix
 r31 r32 r33 0 ; just apply to each point to get the transformed coordinate
 tr1 tr2 tr3 1 ; use double-precision variables

• XYZ

                                                                       Navigatore virtuale 3D
10                                                                                 Introduzione

      Questo è semplicemente come il PTS ma senza il numero di punti come linea iniziale.

     • LAS
      Uno standard industriale binario per dati provenienti da macchine che usano lidar.
      Essendo un formato binario non viene qui approfondito, è rilevante comunque il fatto
      che ha dei bytes dedicati alla classificazione dei punti (terreno, albero...).

     • LAZ
      Una versione compressa del LAS.

Questa non intende essere una lista completa dei formati di point cloud bensì solo quelli che
ho incontrato nel corso del progetto. Fortunatamente esistono dei convertitori tra i diversi
formati che funzionano più o meno bene. Menziono Faro Scene LT perchè è l’unico che ho
trovato in grado di convertire da ptx a diversi altri formati senza sovraccaricare inutilmente la
RAM. Un altro programma che fa il suo dovere è pointzip che converte da ptx/pts a las/laz.

Navigatore virtuale 3D
11

Capitolo 4

Point cloud renderer

Semplicemente avere un file con tanti punti non è molto utile, diventa utile se possiamo
visualizzarlo e questo viene dato erroneamente per scontato. Dato l’elevato numero di punti
da renderizzare una visualizzazione fluida è possibile solo con un codice performante che
magari usa anche algoritmi geometrici astuti.
Un requisito indispensabile per il renderer di cui ho bisogno è che sia open-source dato che
devo avere accesso a strutture dati e metodi interni per raggiungere i miei scopi. Un altro
requisito non obbligatorio ma che è sicuramente utile è la platform independence, cioè la
capacità di un programma di eseguire su sistemi operativi diversi senza cambiare il codice
sottostante.
La scelta si è quasi subito fermata su Potree, un visualizzatore standalone che gira su
browser tramite WebGL, sia perchè ci sono pochi renderer point cloud che funzionano nel
browser (di altri conosco solo plasio), sia perchè offriva una guida veloce su come iniziare a
visualizzare un point cloud. Purtroppo il codice sorgente consiste di 22000 e passa linee di
codice javascript non documentate il che ha reso la comprensione del programma una sfida
di reverse engineering.
Potree, come appena detto, è un renderer di point cloud che gira su browser, è scritto in
javascript e utilizza WebGL anche se la maggior parte dell’interazioni col motore grafico
sono mediate da Three.js, una libreria ad alto livello che permette di creare animazioni 3D
complesse sotto licenza MIT.

4.1    Octree

Potree può visualizzare point cloud in formato las, laz, xyz e pts, però non può visualizzarli
direttamente bensì bisogna prima convertire il file in questione in una struttura intermedia
utilizzata da Potree, un octree.
Un octree è una particolare struttura ad albero dove ogni nodo figlio ha al massimo 8 figli,
ognuno dei quali ha delle coordinate in uno spazio tridimensionale riferite al suo centro.

                                                                       Navigatore virtuale 3D
12                                                                       Point cloud renderer

Source: http://www.cradle-cfd.com

                                Figura 4.1: LOD in un octree

Partendo dal nodo root che include tutto il volume di una scena, ogni figlio comprende
un ottavo del volume del nodo padre. Questa partizione dello spazio permette di creare
algoritmi efficienti nel campo della computer grafica come per esempio algoritmi di collision
detection dove si riesce ad arrivare ad una time complexity di O(n log n).

Nel caso dei point cloud gli octree vengono usati per cercare in modo efficiente quali punti
sono vicini ad un dato punto, ma soprattutto per decidere il livello di dettaglio con il quale
renderizzare dei punti (level of detail, LOD).

Un approccio usato è il seguente: in base alla distanza di un nodo dalla camera, la gerarchia
del nodo verrà percorsa più in profondità o meno. Se la camera si avvicina al nodo allora
la gerarchia verrà percorsa più in profondità e verranno quindi renderizzati i punti associati
a un maggiore livello di dettaglio, che tenderanno a essere anche più numerosi. In questo
modo se la camera è lontana da un nodo i punti in esso contenuti verranno renderizzati con
un LOD minore ma la differenza di dettaglio è viene mascherata dal fatto che la camera è
lontana.

Navigatore virtuale 3D
13

                          Figura 4.2: Point cloud di esempio "Lion" su Potree

    4.2      Potree converter
    Nella pagina github di Potree1 è anche possibile trovare il programma Potree Converter che
    si occupa di convertire il point cloud (las, pts, ...) in un octree. La seguente linea mostra
    come eseguire il programma su windows convertendo un file las in una gerarchia octree e
    generando una pagina html che permette di visualizzare il point cloud.
1   # convert data . las and generate web page .
2   ./ PotreeConverter . exe C :/ data . las -o C :/ potree_converted -p pageName

    In particolare, il comando che io ho eseguito per convertire tre parti su dieci del point cloud
    di Cornaredo è il seguente:
1   ./ PotreeConverter . exe .\ cassarate \1. pts .\ cassarate \2. pts .\ cassarate \3.
         pts
2   -o \ cassaratePotree123 -p cassaratePage -f xyzirgb --projection " + proj =
         somerc + lat_0 =46.95240555555556 + lon_0 =7.439583333333333 + k_0 =1 + x_0
         =2600000 + y_0 =1200000 + ellps = bessel + towgs84 =674.
3   374 ,15.056 ,405.346 ,0 ,0 ,0 ,0 + units = m + no_defs "

    Il parametro -f indica il formato del file mentre --projection è una piccolezza che indica la
    proiezione da usare per le coordinate affinchè la mini-mappa di OpenStreetMap in alto a
      1
          https://github.com/potree/

                                                                            Navigatore virtuale 3D
14                                                                            Point cloud renderer

                           Figura 4.3: Octree di Potree nel filesystem

sinistra nella pagina html mostri il luogo esatto. La posizione dei punti non è influenzata da
questo parametro.

Nel filesystem l’octree generato ha una struttura come quella in figura 4.3. Ogni file rap-
presenta un nodo e il suo nome indica la posizione gerarchica, la radice è indicata con la
lettera "r". Quindi il file chiamato "r006.bin" indica che per raggiungere quel nodo bisogna
percorrere r, il figlio 0, il figlio 0 e il figlio 6. Per capire meglio si consideri la figura 4.4, i
cubi gialli sono la rappresentazione grafica dei nodi, il cubo più piccolo che si vede contiene
i punti presenti nel file "r44". Il motivo per cui non ci sono i nodi r1, r3, r5, r7 è che non ci
sono punti in quelle zone, sopra i nodi 0, 2, 4, 6 ci sarebbero rispettivamente 1, 3, 5 e 7.
Questo partizionamento del volume rende possible caricare solo un sottoinsieme dei punti
del point cloud in RAM in un determinato istante, caricare tutti i punti sarebbe tecnicamente
impossibile su un computer medio con un point cloud modesto che può anche superare i
100GB.

Navigatore virtuale 3D
15

                                  Figura 4.4: Octree boxes

4.3    Funzionalità di Potree

Potree non offre solo la possibilità di visualizzare un point cloud ma anche altre funzionalità
tra quali le seguenti.

   • Selezionare un punto

                                Figura 4.5: Punto selezionato

   • Misurare distanze

                                                                        Navigatore virtuale 3D
16                                                                Point cloud renderer

                                  Figura 4.6: Distanza misurata

     • Isolare regioni di punti

                                   Figura 4.7: Volume clipping

     • E altre ancora

Navigatore virtuale 3D
17

                                     Figura 4.8: Features

      come quelle in figura 4.8.

      Point budget è una variabile indicante a grosso modo il numero di punti da renderiz-
      zare. Aumentando questa variabile i nodi dell’octree in lontananza vengono percorsi
      più a fondo, portando ad un numero maggiore di punti renderizzati e quindi maggiore
      dettaglio.

      Field of view (FOV) è l’estensione della scena visibile in un dato momento.

      Eye-Dome-Lightning è una tecnica di ombreggiatura che aumenta la percezione della
      profondità, i bordi risultano più marcati.

      Background come dice il nome è l’immagine da visualizzare che racchiude il point
      cloud.

      La splat quality determina la forma dei punti. Una standard quality farà si che ogni
      punto del point cloud sarà renderizzato come quadrato, mentre una high quality ren-
      derizza i punti come circonferenze.

      Min node size indica la grandezza minima dei punti. Incrementandola aumentano di
      dimensione i punti.

      La checkbox "Box" permette di visualizzare i nodi dell’octree.

      "Lock view" blocca il livello di dettaglio che si ha quando viene attivata. Quindi se sia-
      mo lontani dal point cloud, mettiamo la spunta su lock view e ci avviciniamo, vedremo
      un livello di dettaglio scarso, che era quello di quando eravamo ancora lontani.

4.4    Informazioni utili per interagire con Potree

Dato che il codice di Potree non è documentato pongo qui alcune informazioni utili per
interagire con i punti del point cloud. La struttura dati che da accesso ai dati di Potree è:

                                                                         Navigatore virtuale 3D
18                                                                           Point cloud renderer

1   window . viewer = new Potree . Viewer ( document . getElementById (
2   " potree_render_area " ) ) ;

    Questa linea fa parte del codice che viene generato insieme alla pagina html quando si usa
    Potree Converter. Per una visualizzazione della gerarchia di alcune delle seguenti strutture
    dati guardare la figura 4.9.

         • viewer.scene.view è l’oggetto che controlla la camera di three.js. Tra gli attributi che
             contiene ci sono direction e position della camera, entrambi di tipo THREE.Vector3.

         • viewer.scene.pointclouds è l’array che contiene i vari point cloud. Io ho sempre
             lavorato con un solo point cloud quindi accedo sempre all’elemento 0.

         • viewer.scene.pointclouds[0].root è la radice del point cloud. Il campo children
             contiene i vari nodi figli.

         • viewer.scene.pointclouds[0].matrixWorld contiene la matrice con qui bisogna mol-
             tiplicare alcune matrici di oggetti per ottenere le world coordinates (tipo le bounding
             sphere dei nodi).

         • viewer.scene.pointclouds[0].root.geometryNode.geometry.attributes è un ogget-
             to BufferGeometry che contiene gli attributi dei punti quali posizione e colore.

         • node.sceneNode.matrixWorld, dove node è un certo nodo, rappresenta la matrice
             che deve essere moltiplicata per i punti di quel nodo per ottenere le world coordinates
             dei punti.

         • viewer.scene.pointclouds[0].visibleNodes contiene tutti i nodi visibili dalla camera.

         • node.geometryNode contiene anche la bounding sphere e bounding box del nodo.

         • viewer.scene.pointclouds[0].nodesOnRay(viewer.scene.pointclouds[0].visibleNodes,
             ray); restituisce i nodi la cui bounding sphere interseca un dato raggio.

         • node.geometryNode.geometry.attributes.position.array è il luogo dove effettiva-
             mente sono scritte le posizioni dei punti in un nodo.

         • node.geometryNode.geometry.attributes.color.needsUpdate=true è il comando da
             eseguire una volta cambiata una proprietà affinchè le modifiche vengano apportate
             (in questo caso il colore). Il seguente snippet cambia il colore dei primi tre punti di un
             nodo in rosso.
         1     for ( let i = 0; i < 3; i ++) {
         2     node . geometryNode . geometry . attributes . color . array [ i * 3] = 255;
         3     node . geometryNode . geometry . attributes . color . array [ i * 3 + 1] = 0;
         4     node . geometryNode . geometry . attributes . color . array [ i * 3 + 2] = 0;
         5     }

    Navigatore virtuale 3D
19

Figura 4.9: Struttura root in Chrome

                                       Navigatore virtuale 3D
20                       Point cloud renderer

Navigatore virtuale 3D
21

Capitolo 5

Sviluppo

5.1      Conversione WGS84 a LV95

I dispositivi GPS, quindi anche quello che ho usato io, lavorano con coordinate che si rife-
riscono al World Geodetic System 1984, uno standard che viene usato in ambiti tra i quali
navigazione satellitare e cartografia. Esso ha l’origine nel centro di massa della Terra, il
meridiano di riferimento è quello di Greenwich.

           Source: http://code7700.com/wgs-84.htm

                                      Figura 5.1: WGS84

Per le formule matematiche mi sono basato sul documento "Formulas and constants for the
calculation of the Swiss conformal cylindrical projection and for the transformation between
coordinate systems", rilasciato dalla Swiss Federal Office of Topography1 .
Quello che segue è un estratto del documento che è poi la parte da me implementata.

  1
      https://www.swisstopo.admin.ch/en/maps-data-online/calculation-services.html

                                                                      Navigatore virtuale 3D
22                                                                                 Sviluppo

                          Figura 5.2: Conversione WGS84->LV95

Il dispositivo GPS usato in questo progetto è un South S660P, dispone di un’interfaccia web
accessibile collegandolo con un cavo micro-USB, dove è possibile cambiare la configurazio-
ne del dispositivo come ad esempio l’hotspot a cui collegarsi per accedere a internet, dove
inviare le coordinate, e varie impostazioni legate alla navigazione satellitare.

Navigatore virtuale 3D
23

              Source: http://www.southinstrument.com

                                       Figura 5.3: South S660P

     5.2    Movimento della camera

     Per muovere la camera tra una coordinata e la successiva ho deciso di usare TweenJS,
     libreria di cui ho scoperto l’esistenza analizzando il sorgente di Potree (in Potree viene usata
     per animare lo zoom in/out). TweenJS serve a fare tweening, termine usato nell’animazione
     computerizzata per indicare il processo di generazione di frame intermedi tra un fotogramma
     iniziale ed uno finale, in questo modo lo spostamento della camera non è istantaneo ma
     avviene in modo più naturale. Dato che il dispositivo GPS a volte segna leggere variazioni di
     posizione anche se fermo, prima di muovere la camera controllo che il vettore spostamento
     sia lungo almeno 0.5 metri.
1    async function followGPS ( nextX , nextY , nextZ ) {
2    // stableX and stableY are the last valid coordinates received
3    if ( stableX == 0 && stableY == 0) {
4    viewer . scene . view . position . setX ( nextX ) ;
5    viewer . scene . view . position . setY ( nextY ) ;
6    viewer . scene . view . position . setZ ( nextZ ) ;
7    // When I receive the first coordinate I can 't know the direction yet , so
           I set a fixed one .
8    viewer . scene . view . lookAt ({
9    x : 2717978 ,
10   y : 1098162 ,
11   z : 300
12   }) ;
13   stableX = nextX ;

                                                                              Navigatore virtuale 3D
24                                                                                Sviluppo

14   stableY = nextY ;
15   return ;
16   }
17
18   let deltaX = nextX - stableX ;
19   let deltaY = nextY - stableY ;
20   if ( Math . sqrt ( Math . pow ( deltaX , 2) + Math . pow ( deltaY , 2) ) > 0.5 && Math .
          sqrt ( Math . pow ( deltaX , 2) + Math . pow ( deltaY , 2) ) < 100) {
21   viewer . scene . view . lookAt ({
22   x : nextX ,
23   y : nextY ,
24   z : nextZ
25   }) ;
26   setupCameraPositionTween ({
27   x : viewer . scene . view . position .x ,
28   y : viewer . scene . view . position .y ,
29   z : viewer . scene . view . position . z
30   }, {
31   x : nextX ,
32   y : nextY ,
33   z : nextZ
34   },
35   500) ;
36   stableX = nextX ;
37   stableY = nextY ;
38   }
39   }
40
41   function setupCameraPositionTween ( source , target , duration , delay , easing
         ) {
42   var l_delay = ( delay !== undefined ) ? delay : 0;
43   var l_easing = ( easing !== undefined ) ? easing : TWEEN . Easing . Linear . None
         ;
44
45   new TWEEN . Tween ( source )
46   . to ( target , duration )
47   . delay ( l_delay )
48   . easing ( l_easing )
49   . onUpdate ( function () {
50   // copy incoming position into camera position
51   viewer . scene . view . position . copy ( source ) ;
52   })
53   . start () ;
54   }

     Navigatore virtuale 3D
25

5.3     Calcolo altitudine per camera

Per calcolare l’altitudine avrei potuto sfruttare il GPS, ma dato che un possibile obbiettivo
era quello di "rilevare" gli ostacoli in base al dislivello rispetto all’asfalto ho deciso di basarmi
sui punti del point cloud. L’algoritmo che uso per calcolare il livello della strada può essere
riassunto come segue:

   • Uso una funzione di potree che restituisce i nodi che intersecano un dato raggio,
       passando come argomento i nodi visibili dalla camera (nel frustum) e un raggio che
       ha come origine la posizione della camera e direzione z=-1
   1   let camPosition = viewer . scene . view . position ;
   2   let raycaster = new THREE . Raycaster () ;
   3   let ray = raycaster . ray ;
   4   ray . direction ={ x :0 , y :0 , z : -1};
   5   ray . origin ={ x : camPosition .x , y : camPosition .y , z : camPosition . z };
   6   let nodes = viewer . scene . pointclouds [0]. nodesOnRay (
   7   viewer . scene . pointclouds [0]. visibleNodes , ray ) ;

   • Filtro i nodi con una bounding sphere il cui raggio è compreso tra 8 e 6 metri. Questo
       perchè i nodi che contengono i punti dell’asfalto in questo point cloud hanno un raggio
       poco maggiore di 6 metri.
   1   let radius6Nodes = intNodes . filter ( function ( elem ){
   2      let radius = elem . geometryNode . boundingSphere . radius ;
   3      return radius 6;
   4   }) ;

   • Ordino i nodi rimanenti secondo la distanza dal loro centro alla camera e prendo il più
       vicino, ricordandomi che le bounding sphere devono prima essere convertite in world
       coordinates
   1   let matrixWorld = viewer . scene . pointclouds [0]. matrixWorld ;
   2   radius6Nodes . sort ( function (a , b ) {
   3      let distanceCenter1 =( a . geometryNode . boundingSphere . clone () .
   4      applyMatrix4 ( matrixWorld ). center ) . distanceTo ( ray . origin ) ) ;
   5      let distanceCenter2 =( b . geometryNode . boundingSphere . clone () .
   6      applyMatrix4 ( matrixWorld ). center ) . distanceTo ( ray . origin ) ;
   7      return distanceCenter1 - distanceCenter2 ;
   8   }) ;
   9   radius6Nodes = radius6Nodes [0];

   • Infine calcolo la z media di k punti presi ogni k/pointsOf N ode. Di solito k è intorno
       a 10.
   1   for ( let i =0; i < radius6Nodes . geometryNode . numPoints ;
   2     i += Math . ceil ( radius6Nodes . geometryNode . numPoints / k ) )

                                                                            Navigatore virtuale 3D
26                                                                                         Sviluppo

     3     meanOfKPoints += radius6Nodes . geometryNode . geometry . attributes .
     4     position . array [ i *3+2]+ radius6Nodes . sceneNode . matrixWorld .
     5     elements [14];
     6   meanOfKPoints /= k ;

         In questo modo anche se c’è un dislivello tra i punti del nodo, come un marciapiede,
         ciò influerà poco sulla z media. E comunque delle lievi variazioni dell’altezza della
         camera non sono problematiche.

5.4       Rilevazione ostacoli

L’identificazione di punti come ostacoli non è esattamente un’impresa banale, le soluzioni
che ho intravisto si basavano su due approcci diversi: uno che utilizza tecniche di machine
learning, uno che si basa sulla deviazione nell’altezza dei punti rispetto a quello che è
considerato asfalto. Il machine learning risulterebbe più efficacie ma essendo questo un
obbiettivo aggiuntivo ed essendo questa soluzione abbastanza complessa da meritare un
suo progetto indipendente, ho deciso di optare per la seconda.
L’algoritmo implementato è il risultato dei seguenti ragionamenti. Non posso sapere con
certezza cosa è e cosa non è asfalto, quello su cui posso appoggiarmi è il fatto che la posi-
zione della camera (quindi quella del GPS e della macchina che usa questo programma) è
nel mezzo della corsia che si sta percorrendo. Non posso semplicemente prendere dei punti
vicino alla camera, calcolare la z media e iniziare a colorare di rosso tutti i punti superiori
alla media per il semplice motivo che il livello stradale continua a cambiare man mano che
si prosegue, aggiungiamo il rumore durante il processo di acquisizione digitale dei punti e
l’algoritmo non è per niente efficacie.
Per rendere l’algoritmo invariante all’evoluzione dell’asfalto percorso ho deciso di segmen-
tare i punti lungo la direzione di guida in segmenti orizzontali di spessore 0.4 metri cir-
ca, calcolando che in questo spazio percorso il livello stradale non subisce cambiamenti
significativi.
A questo punto potrei iniziare ad analizzare i punti in ogni segmento partendo dai punti
più vicini alla camera, ma questa soluzione non è efficacie per il seguente motivo. I punti
analizzati partirebbero dal centro del segmento e si estenderebbero simultaneamente agli
estremi, il problema è nel simultaneamente perchè se il programma incontra degli ostacoli su
un estremo la media inizia ad alzarsi e i punti verso l’altro estremo del segmento potrebbero
essere classificati come ostacoli anche se la loro altezza non è cambiata.
Per risolvere questo problema semplicemente suddivido i segmenti in due parti, una conte-
nente tutti i punti a sinistra del vettore direzione e l’altra contenente tutti i punti a destra.
Per testare il corretto funzionamento della segmentazione ho scritto una funzione che mi co-
lora in modo alternato i punti nei segmenti indipendentemente dalla loro altezza. Il risultato
è il seguente.

Navigatore virtuale 3D
27

                              Figura 5.4: Prova di segmentazione

Dopo che i punti sono stati segmentati posso percorrere ogni segmento nelle due direzioni
indipendenti partendo da quelli più vicini al vettore direzione(i segmenti sono sempre per-
pendicolari al vettore direzione). Prima di testare se i punti analizzati superano di un certo
threshold la media progressiva, calcolo come parte dell’asfalto un certo numero di punti in-
dipendentemente dalla loro altezza così da avere una media di riferimento. La media che
viene calcolata è sempre basata sugli ultimi m punti analizzati, quindi quando analizzo un
nuovo punto faccio il push di questo mentre eseguo anche un pop sulla struttura trattanto
l’array che contiene i punti come una queue (FIFO). Io pongo m a circa 60, di conseguenza
la media si adatta abbastanza in fretta all’altezza dei nuovi punti così da non prolungare
troppo le linee rosse. Il threshold (delta di altezza rispetto alla media) da superare per es-
sere considerato ostacolo è stato posto da me intorno ai 5cm, empiricamente è risultato un
buon limite per rilevare i marciapiedi che sono stati digitalizzati discretamente.

Il numero di nodi da processare per la rilevazione di ostacoli è ovviamente limitato. Ini-
zialmente per scegliere i nodi semplicemente filtravo tra i nodi visibili quelli la cui bounding
sphere intersecava una bounding sphere intorno alla camera di raggio circa 20 metri.

Però in questo modo prendevo in considerazione troppi nodi laterali alla strada con conse-
guente penalità sul tempo per processare i punti, allora per diminuire l’estensione laterale
ma mantenere quella lungo il vettore direzione ho deciso di usare un approccio diverso.

Dopo aver ricavato i nodi come descritto sopra, filtro quelli la cui bounding sphere ha il centro
distante meno di 12 metri da un raggio che ha come origine la camera e come direzione la
direzione della camera. In questo modo costringo i nodi da processare ad essere vicini alla
strada. Il risultato è il seguente.

                                                                         Navigatore virtuale 3D
28                                                                                   Sviluppo

                                  Figura 5.5: Rilevazione di ostacoli

     Se la queue che contiene la coordinata z dei punti fosse più lunga allora tutto il marciapiede
     sarebbe diventato rosso perchè la media ci metterebbe più tempo ad adattarsi.
     Per far sì che la segmentazione dei punti abbia complessità O(n) uso direttamente la di-
     stanza come indice del segmento in cui mettere i punti, come si può vedere nel piccolo
     snippet di codice sottostante. Per velocizzare l’algoritmo è stato fatto anche utilizzo dei Web
     Workers, delle sorte di thread in javascript, però il passaggio delle strutture dati a questi
     thread è oneroso (i dati vengono serializzati e deserializzati per ogni comunicazione al/dal
     main thread) e induce un ritardo.

1    let camera = viewer . scene . view ;
2    let perpendicularDirectionCamera = new THREE . Vector3 ( - camera . direction .y ,
3    camera . direction .x , 0) ;
4    // Ray passing through camera perpendicular to the direction
5    let rayPerpendicular = new THREE . Line3 ( camera . position . clone () ,
6    camera . position . clone () . add ( perpendicularDirectionCamera ) ) ;
7    // If to the right of the direction vector
8    if ( perpendicularDirectionCamera . dot ( new THREE . Vector2 ( point . x - viewer .
          scene . view . position .x , point . y - viewer . scene . view . position . y ) ) < 0)
9    side = 1;
10   else
11   side = 0;
12   // Closest point in the ray perpendicular to the camera direction passing
13   // through the camera
14   let closestPoint = new THREE . Vector3 () ;
15   rayPerpendicular . closestPointToPoint ( point , false , closestPoint ) ;

     Navigatore virtuale 3D
29

16   // 0.4 is the width of a segment ( arbitrary )
17   let distance = closestPoint . distanceTo ( point ) / 0.4;
18   let segment = Math . trunc ( distance ) ;
19   pointsInSegments [ side ][ segment ]. push ({
20   nodeIndex : node ,
21   arrayIndex : i ,
22   x : point .x ,
23   y : point .y ,
24   z : point . z
25   }) ;

     5.5    Lettura coordinate GPS - Firebase

     Le coordinate GPS non vengono direttamente lette dal dispositivo bensì le ricevo da un
     server di Device SA la cui connessione mi è stata gentilmente offerta da Paolo Romani. Il
     vantaggio è che i dati grezzi vengono elaborati dal loro server e il mio applicativo esegue il
     fetch delle coordinate già in formato LV03 (che io converto in LV95).
     Il database dal quale leggo le coordinate è un cloud-database, cioè gira su una piattaforma
     che sfrutta il cloud computing. Esistono due tipologie di cloud database, nella prima l’utente
     deve comprare delle macchine virtuali su cui poi far girare il database, nella seconda il
     database viene fornito as-a-service cioè il proprietario della piattaforma cloud si occupa
     di installare e mantenere il database. Il database al quale mi connetto è Firebase Realtime
     Database, quindi la seconda categoria. Firebase è una piattaforma di sviluppo web e mobile
     acquistata da Google. Essa offre una suite di servizi quali:

        • Firebase Cloud Messaging

        • Firebase Auth

        • Realtime Database

        • Firebase Storage

        • Firebase Hosting

        • ML Kit (machine learning)

     Uno dei vantaggi del database Firebase è che non bisogna controllare periodicamente per
     nuovi dati bensì una volta aperta la connessione è il server a chiamare una tua callback
     quando ha nuovi dati.

                                                                             Navigatore virtuale 3D
30                                                                                        Sviluppo

         Source: www.fotolia.com, www.YourFreeTemplates.com, www.openclipart.org,
         www.logolynx.com, www.pfcad.it

Figura 5.6: 1. Il dispositivo GPS si connette ai satelliti (4 per avere un’alta precisione);
2. Manda le coordinate a Berna per una correzione; 3. Scrive le coordinate nel database
Firebase; 4. Quando ci sono cambiamenti Firebase invia le coordinate al mio client

5.6    Pulizia point cloud

Il point cloud di Cornaredo in alcune zone contiene molto rumore, soprattutto nei tratti
stradali sotto gli alberi e questo fa sì che il mio algoritmo di rilevazione ostacoli classifichi

                                Figura 5.7: Point cloud originale

erroneamente diversi punti come in figura 5.7 (quelli a destra sono giusti perchè si tratta

Navigatore virtuale 3D
31

    del marciapiede). Quindi ho scritto una funzione javascript che dati quattro vertici (punti
    selezionati con il tool di Potree) salva su file le coordinate e il colore di tutti i punti rilevati
    come ostacoli all’interno del poligono definito dai quattro vertici. In seguito ho creato un
    piccolo programma in C++ che prende in ingresso il point cloud .pts e la lista dei punti salvati,
    e crea una nuova lista di punti (un point cloud quindi) scartando i punti precedentemente
    salvati. Per velocizzare la ricerca dei punti, una volta caricato il file .pts in RAM i punti
    vengono ordinati rispetto alla coordinata x così che posso effettuare una ricerca binaria.
    L’obbiettivo che mi sono posto era quello di eliminare i falsi positivi. Purtroppo però non
    esiste una corrispondenza esatta tra le coordinate dei punti su Potree e i punti su file, il
    motivo è secondo me a causa dei calcoli floating-point che Potree esegue sulle coordinate
    grezze, e anche perchè Potree applica una distribuzione di Poisson ai punti per ottenere
    maggiore uniformità. Nonostante ciò test empirici mi suggeriscono che questa deviazione
    inserita da Potree nelle coordinate non è abbastanza grande da impedire il ritrovamento dei
    punti originali nei file cercando il punto nel file più vicino a quello presente su Potree. Inoltre
    uso i valori dei canali r, g, b come criterio aggiuntivo.

                                   Figura 5.8: Point cloud modificato

    Il mio programma C++ produce come output il point cloud in figura 5.8, dove si può notare
    che la maggior parte dei falsi positivi è stata eliminata. Il motivo dei rimanenti falsi posi-
    tivi dovrebbe essere una leggera variazione nella posizione e direzione della camera nel
    momento in cui l’algoritmo è stato lanciato nelle due figure.
    Segue la parte di codice che salva i punti dentro il poligono specificato su file.
1   // The polygon must be defined either in a clockwise order or in a
        counter - clockwise one
2   async function saveRedPointsIn4PointsPolygon ( fileName ) {
3   let textToWrite = " " ;
4   let p1 = viewer . scene . measurements [0]. points [0]. position ;

                                                                                Navigatore virtuale 3D
32                                                                         Sviluppo

5    let p2 = viewer . scene . measurements [1]. points [0]. position ;
6    let p3 = viewer . scene . measurements [2]. points [0]. position ;
7    let p4 = viewer . scene . measurements [3]. points [0]. position ;
8    let triangleA = new THREE . Triangle ( p1 , p2 , p3 ) ;
9    let triangleB = new THREE . Triangle ( p1 , p3 , p4 ) ;
10   // Create a sphere around the camera
11   var customSphere = new THREE . Mesh ( new THREE . SphereGeometry (8 * 3) ) ;
12   customSphere . position . copy ( viewer . scene . view . position ) ;
13   // Find intersecting bounding spheres
14   var intersectingNodes = viewer . scene . pointclouds [0]. visibleNodes . filter (
          function ( elem ) {
15   let radiusSum = elem . geometryNode . boundingSphere . radius + customSphere .
          geometry . parameters . radius ;
16   let distanceCenters = customSphere . position . distanceTo ( elem . geometryNode .
          boundingSphere . clone () . applyMatrix4 ( viewer . scene . pointclouds [0].
          matrixWorld ) . center ) ;
17   return distanceCenters * distanceCenters
33

40   download ( textToWrite , fileName , " text / plain " ) ;
41
42
43   }
44
45   // Function to download data to a file
46   // taken from : https :// stackoverflow . com / questions /13405129/ javascript -
           create - and - save - file
47   function download ( data , filename , type ) {
48   var file = new Blob ([ data ] , {
49   type : type
50   }) ;
51   if ( window . navigator . msSaveOrOpenBlob ) // IE10 +
52   window . navigator . msSaveOrOpenBlob ( file , filename ) ;
53   else { // Others
54   var a = document . createElement ( " a " ) ,
55   url = URL . createObjectURL ( file ) ;
56   a . href = url ;
57   a . download = filename ;
58   document . body . appendChild ( a ) ;
59   a . click () ;
60   setTimeout ( function () {
61   document . body . removeChild ( a ) ;
62   window . URL . revokeObjectURL ( url ) ;
63   } , 0) ;
64   }
65   }

                                                                     Navigatore virtuale 3D
34                       Sviluppo

Navigatore virtuale 3D
35

Capitolo 6

Risultati e conclusione

6.1    Risultati

Per testare l’applicazione io e il mio relatore ci siamo recati nella zona interessata, vicino
al cinema "Cinestar" in zona Cornaredo, una volta fissato il dispositivo GPS al tetto della
macchina e collegatolo all’hotspot di uno smartphone, abbiano fatto dei giri di prova. Inizial-
mente la frequenza di richiesta della posizione del GPS era settata a una volta al secondo,
dopo aver notato che il viewer riusciva a tenere il ritmo siamo passati a due volte al secondo,
e anche qui il viewer non aveva problemi.

                                                                        Navigatore virtuale 3D
36                                                                    Risultati e conclusione

                            Figura 6.1: GPS sopra la macchina

Abbiamo anche provato ad attivare la rilevazione di ostacoli in tempo reale però a causa del
tempo necessario all’algoritmo per analizzare i punti, di circa un secondo, l’applicazione non
riusciva a stare al passo con la posizione della macchina. Gran parte della zona analizzata
veniva sorpassata quando la rilevazione terminava.

Navigatore virtuale 3D
37

    (a) Visuale reale

(b) Visuale nel point cloud

                              Navigatore virtuale 3D
38                                                                       Risultati e conclusione

                                        (a) Visuale reale

                                   (b) Visuale nel point cloud

6.2    Difficoltà incontrate

Le difficoltà maggiore che ho incontrato è stata senza dubbio capire come funziona interna-
mente Potree, che non è una libreria bensì un software standalone. Nonostante io mi sia
limitato a capire ciò che mi sarebbe servito, navigare tra più di una decina di migliaia di righe
di codice in javascript non documentate è stato il fattore che mi ha preso più tempo.

6.3    Considerazioni finali

L’obbiettivo principale di questo progetto consiste nella creazione di un’applicazione che
assiste il guidatore durante la guida grazie alla visualizzazione dell’ambiente circostante
mediante un point cloud. Questa applicazione sicuramente non è perfetta, anche se il di-
spositivo GPS era impostato ad inviare dati con una certa frequenza a volte sembravano
arrivare leggermente in ritardo. Ciò nonostante ritengo che il progetto dimostra la fattibili-

Navigatore virtuale 3D
39

tà dell’impresa. Durante le prove si riusciva chiaramente a capire che la visuale mostrata
nel point cloud era quella del guidatore, anche se ovviamente nei tratti di curva si nota in
modo marcato la correzione della direzione man mano che arrivano le nuove coordinate,
generando degli scatti nella visuale. Questo inconveniente è però risolvibile aumentando la
frequenza con qui vengono mandate le coordinate GPS, sarebbe quindi interessante prova-
re con frequenze maggiori (che il dispositivo GPS offre). Inoltre si potrebbe utilizzare quella
che si chiama movement prediction, cioè avendo a disposizione l’informazione riguardante
posizione e velocità attuale si tenta di predire quale sarà la posizione futura, nel tentativo
di ridurre la correzione che avviene quando effettivamente si ricevono le coordinate succes-
sive. Il problema della latenza introdotta dall’usare l’algoritmo di rilevazione di ostacoli in
tempo reale è risolvibile usando l’algoritmo in una fase di pre-processing e quindi avendo
un point cloud che è processato a priori.

Questo progetto è risultato sicuramente interessante e ha contribuito ad una crescita per-
sonale. Mi ha permesso di ampliare le mie conoscenze di javascript, che erano basilari, e
di conoscere librerie come three.js.

                                                                        Navigatore virtuale 3D
40                       Risultati e conclusione

Navigatore virtuale 3D
41

Bibliografia

[1] Potree,
   http://potree.org/

[2] Potree github,
   https://github.com/potree/potree

[3] Three.js,
   https://threejs.org/

[4] SUPSI-DTI,
   http://progettistudio.dti.supsi.ch/index.php

[5] Wikipedia,
   https://it.wikipedia.org/wiki/Nuvola_di_punti

[6] WebGL,
   https://get.webgl.org

[7] Developer Mozilla,
   https://developer.mozilla.org/bm/docs/Web/JavaScript

[8] Leica Geosystems,
   https://w3.leica-geosystems.com/kb/?guid=5532D590-114C-43CD-A55F-FE79E5937CB2

[9] Swisstopo,
   https://www.swisstopo.admin.ch/

[10] Tween.js,
   https://github.com/tweenjs/tween.js

                                                          Navigatore virtuale 3D
Puoi anche leggere