giovedì 28 dicembre 2023

Docker Compose esempio

 In ufficio stanno spingendo per utilizzare docker per ogni applicazione

Per rendere lo sviluppo piu' tracciabile viene richiesto che oltre al docker file vi sia anche il file yaml di docker compose (in pratica le impostazioni del container che si dovrebbero passare sulla linea di comando sono scritti nel file compose.yaml

con build . (punto) viene indicato di usare il dockerfile compreso nello stesso folder

Per lanciare si usa

docker compose up -d

alla fine della costruzione dell'immagine viene fatto in automatico lo start

Si accede quindi con

docker exec -it Omnia bash

si termina con

docker compose stop

version: '3'

services:
omnia_apuane:
build: .
container_name: Omnia
ports:
- "9192:80"
dns:
- "10.100.1.3"
environment:
- HOST=omnia
- VIRTUAL_HOST=omnia.aaaa.aaaa.it
- VIRTUAL_PROTO=http
- VIRTUAL_PORT=80
- TZ=Europe/Rome
restart: always
network_mode: bridge

mercoledì 27 dicembre 2023

Frana M.Javello e Sentinel 1

Qualche settimana fa un conoscente mi ha mandato um video di una corona di frana sul monte Javello legata all'evento piovoso del 6 novembre


Ho provato a vedere se riuscivo a vedere l'estensione della frana dalle immagini di Sentinel 2. Sono riuscito ad inviduare un aspetto interessante ovvero che sul versante era presente una zona disboscata che e' stata tagliata nel 2023 ed i corrispondenza di questa area 


Immagine dell'area disboscata

Prima del taglio forestale

dopo il taglio forestale


Come si puo' vedere dopo l'evento l'impluvio risulta essere interessato da trasporto solido (e' la striscia bianca che scende verso valla a circa meta' dell'immagine leggermente a sinistra)

Nonostante cio' in ottico della frana nemmeno l'ombra. Ho provato, cosa che non avevo mai provato, ad utilizzare Sentinel 1.

Per fare change detection con immagini radar si devono cercare immagini appartenenti alla stessa orbita. il primo tentativo e' fallito perche' il sensore illuminava il versante sbagliato del M.Ferrato e quindi non si mostravano modifiche al versante

Ho preso quindi la coppia 

S1A_IW_GRDH_1SDV_20231031T171457_20231031T171522_051012_062696_0499.SAFE
S1A_IW_GRDH_1SDV_20231112T171456_20231112T171521_051187_062C9B_8EBB.SAFE

Ciascuna immagine e' stata trattata con in SNAP con

Radar/Apply Orbit
Radar/Radiometric/S1 Remove Thermal Noise
Radar/Radiometric/Calibrate (attivando sia Sigma0 che Beta0)
Radar/Speckle Filtering/Single Product Speckle Filtering
Radar/Geometric/Terrain Correction/Range Doppler Terrain Correction
Raster/Subset (per inquadrare solo l'area di interesse)
Raster/Data Conversion/Linear to/fromDb
Radar/Coregistration (per passare da due prodotti ad un prodotto solo)

Per il change detection sono utilizzati diversi algoritmi (sia basati su dati SLC che GRD) come . Ho provato il metodo piu' semplice che corrisponde al fare il rapporto (non la differenza) tra le bande Beta0  prima e dopo l'evento

rapporto beta0

scontornando manualmente le aree

Il metodo non e' particolarmente diagnostico. L'algoritmo indicava una frana anche a monte di Schignano ma persone del luogo mi hanno detto che non si sono verificati movimenti franosi. Diciamo che puo' essere una indicazione ma non altro

in effetti sembra che Sentinel 1 riesca a verificare delle zone di potenziale frana dove Sentinel 2 non riusciva a vedere. Spero di riuscire a trovare il tempo per un sopralluogo di persona 

1) Strategies for landslide detection using open-access synthetic aperture radar backscatter change in Google Earth Engine Alexander L. Handwerger , Shannan Y. Jones , Pukar Amatya  Hannah R. Kerner  , Dalia B. Kirschbaum , and Mong-Han Huang https://doi.org/10.5194/nhess-2021-283

2) Exploring event landslide mapping using Sentinel-1 SAR backscatter products Michele Santangelo, Mauro Cardinali, Francesco Bucci, Federica Fiorucci, Alessandro Cesare Mondini  Geomorphology Volume 397, 15 January 2022, 108021


domenica 26 novembre 2023

venerdì 24 novembre 2023

DS0152 e geofono

Volevo provare l'oscilloscopio DS0152 e visto che ho in prestito un geofono ho guardato il segnale in uscita. Francamente pensavo che il sensore facesse uscire poche decine di millivolt ma come si vede dalla foto si passa da qualche decina di Volts fino a qualche Volt (ho letto anche fino a 9V ma con sollecitazioni meccaniche che non sono ragionevoli per un geofono)



 Anche la lettura del periodo del geofono (15 Hz) risulta coerente con le caratteristiche di fabbrica










martedì 21 novembre 2023

MilkV camera




per mandare in auto esecuzione lo script di streaming si edita il file /mnt/system/auto.sh aggiungendo

/mnt/data/install/CviIspTool.sh 64M

Non riesco a vedere lo stream con VLC su Linux ma usando mpv non ci sono problemi

mpv --no-cache --untimed --no-demuxer-thread --video-sync=audio --vd-lavc-threads=1 rtsp://192.168.42.1:8554/stream0

mercoledì 8 novembre 2023

R 3.6 docker personalizzato

 Un esempio di Dockerfile complesso per R 3.6



FROM rstudio/r-base:3.6-bookworm

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get -y update
RUN apt-get -y install gdal-bin libgdal-dev libpng-dev libudunits2-dev libfontconfig1-dev libmagick++-dev openjdk-17-jdk apache2 mc nano locales && apt-get clean




RUN service apache2 restart


#ENTRYPOINT ["/usr/sbin/apache2", "-k", "start"]
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
EXPOSE 80
CMD ["apachectl", "-D", "FOREGROUND"]

CMD apachectl -D FOREGROUND

# installa client Oracle
RUN wget https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-23.2.0.178.1027.zip && unzip sqlcl*.zip
ENV PATH=sqlcl/bin:$PATH


#imposta la localizzazione italiana
RUN sed -i -e 's/# it_IT.UTF-8 UTF-8/it_IT.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
ENV LANG it_IT.UTF-8
ENV LANGUAGE it_IT:it
ENV LC_ALL it_IT.UTF-8

# imposta la timezone a Europe/Rome
ENV TZ="Europe/Rome"

# scarica il sorgente della libreria non presente su CRAN
RUN curl -O "https://cran.r-project.org/src/contrib/Archive/randomForest/randomForest_4.6-10.tar.gz"
#setup R configs
RUN echo "r <- getOption('repos'); r['CRAN'] <- 'http://cran.us.r-project.org'; options(repos = r);" > ~/.Rprofile
RUN Rscript -e "install.packages('zoo')"
RUN Rscript -e "install.packages('leaflet')"
RUN Rscript -e "install.packages('sf')"
RUN Rscript -e "install.packages('leafpop')"
RUN Rscript -e "install.packages('forecast')"
RUN Rscript -e "install.packages('stringr')"
RUN Rscript -e "install.packages('lubridate')"
RUN Rscript -e "install.packages('randomForest_4.6-10.tar.gz', repos = NULL, type='source')"
RUN Rscript -e "install.packages('rpart')"
RUN Rscript -e "install.packages('e1071')"
RUN Rscript -e "install.packages('kknn')"
RUN Rscript -e "install.packages('jpeg')"
RUN Rscript -e "install.packages('data.table')"
RUN Rscript -e "install.packages('tidyr')"
RUN Rscript -e "install.packages('magick')"
RUN Rscript -e "install.packages('leaflet.extras')"
RUN Rscript -e "install.packages('leafem')"
RUN Rscript -e "install.packages('raster')"

# copia i file
ADD go.sh /root/go.sh
ADD omnia_apuane_spool.sql /root/omnia_apuane_spool.sql
ADD omnia_apuane.R /root/omnia_apuane.R
ADD omnia_arno.R /root/omnia_arno.R
ADD omnia_laguna.R /root/omnia_laguna.R

#crea folders in html
RUN mkdir /var/www/html/mappe
RUN mkdir /var/www/html/mappe/omnia_apuane
RUN mkdir /var/www/html/Acque
RUN mkdir /var/www/html/Acque/LAGUNA
RUN mkdir /var/www/html/Acque/ARNO
RUN mkdir /var/www/html/Acque/ARNO/bollettini


# per il ROracle
ADD instantclient-basic-linux.x64-21.11.0.0.0dbru.zip instantclient-basic-linux.x64-21.11.0.0.0dbru.zip
ADD instantclient-sdk-linux.x64-21.11.0.0.0dbru.zip instantclient-sdk-linux.x64-21.11.0.0.0dbru.zip
# ATTENZIONE il comando ADD decompatta in automatico
# i file tar.gz. Per questo motivo la riga successiva usa COPY
COPY ROracle_1.3-2_R_x86_64-linux-gnu.tar.gz /root/ROracle_1.3-2_R_x86_64-linux-gnu.tar.gz

RUN unzip instantclient-basic-linux.x64-21.11.0.0.0dbru.zip -d /opt/oracle/
RUN unzip instantclient-sdk-linux.x64-21.11.0.0.0dbru.zip -d /opt/oracle/

RUN apt-get install -y libaio1
ENV PATH="${PATH}:/opt/oracle/instantclient_21_11"
ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/oracle/instantclient_21_11"

RUN ldconfig

# compila ROracle
RUN Rscript -e 'install.packages("/root/ROracle_1.3-2_R_x86_64-linux-gnu.tar.gz",repos=NULL,type="source")'
RUN Rscript -e "install.packages('RCurl')"
RUN Rscript -e "install.packages('stringr')"


#cancella i file temporanei
RUN rm randomForest_4.6-10.tar.gz
RUN rm sqlcl*.zip
RUN rm /root/*.tar.gz
RUN rm /root/*.zip

ROracle in R 4

 Per usare ROracle in R v.4 si deve compilare il codice scaricando il pacchetto ROracle_1.3-1.1.tgz e istantclient base ed sdk da Oracle https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html

export PATH="$PATH:/opt/oracle/instantclient_21_12"

export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/oracle/instantclient_21_12"

R CMD INSTALL --configure-args='--with-oci-lib=/opt/oracle/instantclient_21_12/ --with-oci-inc=/opt/oracle/instantclient_21_12/sdk/include' ROracle_1.3-1.1.tar.gz

sudo sh -c "echo /opt/oracle/instantclient_21_12 > /etc/ld.so.conf.d/oracle-instantclient.conf"

sudo ldconfig

Per effettuare la connesione da R

library('ROracle')
library(DBI)
host <- "dbaaaa.aaaa.it"
port <- 1521
svc <- "dbaaaa.aaaaaa.it"
connect.string <- paste(
  "(DESCRIPTION=",
  "(ADDRESS=(PROTOCOL=tcp)(HOST=", host, ")(PORT=", port, "))",
  "(CONNECT_DATA=(SERVICE_NAME=", svc, ")))", sep = "")
drv = dbDriver("Oracle")
con  = dbConnect(drv, "username", "password", dbname=connect.string)

Gnome Tracker

 All'avvio del portatile mi sono accorto che il comando top riportava un processo chiamato tracker che occupava praticamente gran parte dei cicli di CPU


Non lo sapevo ma cercando ho scoperto che questo e' un servizio di indicizzazione file di Gnome

Per disabilitarlo non e' banalissimo

systemctl --user mask tracker-extract-3.service tracker-miner-fs-3.service tracker-miner-rss-3.service tracker-writeback-3.service tracker-xdg-portal-3.service tracker-miner-fs-control-3.service

e successivamente

tracker3 reset -s -r

Foraminiferi e Yolo 8

Qualche anno fa avevo provato ad addestrare una rete neurale per il riconoscimento di foraminiferi con risultati diciamo mediocri



Ho visto che i migliori risultati non si ottengono partendo da una rete ex-novo ma riaddestrando reti gia' elaborate. In questo caso ho provato ad addestrare Yolo 8 con il dataset dei foraminiferi

La prima prova la ho fatto, anche con ottimi risultati, utilizzando il cloud di Roboflow ma volevo una soluzione da fare girare on the edge


Per prima cosa ho creato un virtualenv in Python 

I dati sono inclusi in un folder in cui ci sono le sottodir test,train e valid in cui sono in ciascuna ci sono inclusi i folder images e labels


Per creare le labels ho utilizzato labelImg. Avendo problemi con l'installazione ho utilizzato il docker a questo link


Si deve selezionare il folder dove sono contenute le immagini, il folder dove saranno salvati i file txt in cui sono salvate le annotations, il tipo di annotation (di default viene indicato PascalVOC ma deve andare a Yolo) ed in View conviene indicare autosave 

Nel folder alla radice deve essere create un file data.yaml in cui sono indicati i percorsi dei folder delle immagini, il numero di classi (4) ed i nomi delle classi

train: ../train/images
val: ../valid/images
test: ../test/images
nc: 4
names: ['Candeina_Nitida', 'Globigerina_Bulloides', 'Globigerina_Falconensis', 'Globigerina_digitata']

a questo punto si procede con l'installazione di Yolo 8 

pip install ultralytics

si procede quindi con l'addestramento. Per una prima prova ho usato il pretrain piu' semplice yoolov8n ma vi sono reti addestrati molto piu' profonde in yolov8s.pt, yolov8m.pt, yolov8l.pt, yolov8x.pt
Il parametro batch dipende dalla potenza della propria CPU/GPU...io ho solo lavorato in CPU


yolo task=detect mode=train model=yolov8n.pt imgsz=640 data=data.yaml epochs=10 batch=8 name=yolov8n_foraminiferi



Nel folder run/detect/yolo8n_foraminiferi si trovano i grafici dei parametri del modello


Si puo' validare il modello con 

yolo task=detect mode=val model=runs/detect/yolov8n_foraminiferi/weights/best.pt name=yolov8n_eval data=data.yaml imgsz=640



I risultati sono peggiori di quelli visti con Roboflow ma in ogni caso si ricorda che in questo caso e' stato usata la rete di addestramento piu' semplificata

Una volta finito l'addestramento si puo' usare la rete per riconoscere oggetti

yolo task=detect mode=predict model=runs/detect/yolov8n_foraminiferi/weights/best.pt source=test/immagine.jpg show=True imgsz=640 name=yolov8n_c1 hide_labels=True











Docker pull via http_proxy

 la configurazione del proxy per effettuare un pull di un container docker si trova in

/etc/systemd/system/docker.service.d/http-proxy.conf

ed ha una sintassi del tipo

[Service]
Environment="HTTP_PROXY=http://proxy.aaaaaaaaaa.it:8080"
Environment="HTTPS_PROXY=http://proxy.aaaaaaaaaa.it:8080"

per rendere effettive le modifiche 

systemctl stop docker

systemctl stop docker.socket

systemctl daemon-reload

systemctl start docker

lunedì 6 novembre 2023

Programmazione Milk-V Duo

Per programmare la Milk-V Duo tramite cross compiling su desktop si puo' usare l'SDK 

https://github.com/milkv-duo/duo-examples

una volta decompilato il pacchetto si lancia envsetup.sh che automaticamente scarica il compilatore

Altrimenti si puo' cross compilare tramite Go


Come compilatori sulla scheda si possono usare python (e' presente 3.9.5) oppure tinyGcc 

Per interagire con l'hardware si puo' usare

1) in Python la libreria pinpong  Ci sono una tonnellata di esempi

2) in C la libreria WiringX https://wiringx.org/ 

3) in Go con la libreria gpiod https://github.com/pavelanni/milkv-duo-experiments 

Per creare l'avvio automatico al boot di uno script si deve creare il file auto.sh in /mnt/data/ e si inseriscono i comandi che si vuole mandare in autoesecuzione

mkdir /mnt/data 

vi /mnt/data/auto.shsh

domenica 5 novembre 2023

Rottura argine Fosso Reale Sentinel 2

Immagine RGB  Sentinel 2 del 4 novembre 2023 che mostra l'esondazione delle acque del Fosso Reale a seguito rottura d'argine nell'area di Case Passerini  



Immagine da Consorzio di Bonifica


venerdì 3 novembre 2023

Golang Milk-V Duo RiscV64

Sto provando la scheda Milk-D Duo con processore RiscV64

La scheda un processore dual core. Sul core primario puo' girare un sistema operativo Linux multi task mentre sul secondo FreeRtos. I due sistema comunicano tramite una porta seriale un po' come funzionava la scheda Intel Galileo

Come immagine disco sto usando quella della ditta ma si pu' montare anche Arch (Debian non ha ancora il supporto di rete e si deve accedere tramite connessione seriale)

Su Linux e' piuttosto facile interagire con la scheda perche' se si collega la porta USB C viene montata in automatico un porta di rete tramite RNDIS all'indirizzo 192.168.42.1 (la scheda rilascia in DHCP un indirizzo della classe 192.168.42.x)

enxf611f7e3617d: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.42.18  netmask 255.255.255.0  broadcast 192.168.42.255
        inet6 fe80::f411:f7ff:fee3:617d  prefixlen 64  scopeid 0x20<link>
        ether f6:11:f7:e3:61:7d  txqueuelen 1000  (Ethernet)
        RX packets 242  bytes 29688 (28.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 311  bytes 43373 (42.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisi


ssh root@192.168.42.1


https://xyzdims.com/3d-printers/misc-hardware-notes/iot-milk-v-duo-risc-v-esbc-running-linux/#References 


La scheda ha 64 Mb di memoria ma con il disco immagine la RAM e' di soli 32 Mb perche' gli altri sono destinati alla connessione della video camera

Mem: 20732K used, 8504K free, 80K shrd, 668K buff, 3260K cached
CPU:   0% usr   1% sys   0% nic  98% idle   0% io   0% irq   0% sirq
Load average: 1.90 0.55 0.19 1/64 385
  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
  374   368 root     R     1200   4%   0% top
  155     1 root     S     4740  16%   0% /usr/sbin/ntpd -g -p /var/run/ntpd.pid
  193     1 root     S     1200   4%   0% {S99user} /bin/sh /etc/init.d/S99user start
  361   163 root     S     1008   3%   0% /usr/sbin/dropbear -R
   10     2 root     IW       0   0%   0% [rcu_preempt]
  204     1 root     S     1204   4%   0% -sh

Per usare Go pero' tale memoria non e' sufficiente e si deve attivare la partizione di swap tramite per avere 256 Mb

mkswap /dev/mmcblk0p3
swapon /dev/mmcblk0p3

la dimensione della partizione di swap puo' essere ridimensionata tramite lo script (in questo caso e' 1 Giga)
 
fdisk /dev/mmcblk0 <<EOF
p
d
3
n
p
3

+1G

w
EOF

fdisk -l /dev/mmcblk0

echo "----- resize /dev/mmcblk0p3 for swap completed -----"


a questo punto si puo' fare la build del programma sul desktop facendo cross compilazione
export GOOS=linux 
export GOARCH=riscv64 
export CGO_ENABLED=1 
export CC=riscv64-linux-gnu-gcc
go build programma.go

e si copia sul dispositivo tramite (attenzione allo switch -O)

Ho fatto qualche prova e non sembrano funzionare le goroutines

Nel caso il cui si voglia esporre la scheda verso Internet si puo' usare o la scheda di espansione che monta una scheda Ethernet



oppure se il PC Desktop assume un IP del tipo 192.168.42.68 si lancia sul desktop

sysctl net.ipv4.ip_forward=1 
iptables -P FORWARD ACCEPT 
iptables -t nat -A POSTROUTING -o outgoing_if -j MASQUERADE

mentre sulla scheda

ip r add default via 192.168.42.68

lunedì 30 ottobre 2023

Trimble GeoXT 2005 Series nel 2023

Ho trovato in cassetto dell'ufficio sepolto da qualche mio predecessore un Trimble GeoXT, un dispositivo GPS che usavo all'Universita'. Era una macchina estremamente costosa che includeva un palmare con Pocket PC

Mi e' stato detto che il GPS era stato accantonato perche' non reggeva la batteria....ovviamente la mia domanda e' stata..si potra' usare nel 2023 un dispositivo del 2005 


Primo aspetto: la batteria non e' assolutamente rovinata...il dispositivo e' rimasto acceso per ore (>5) 

Secondo aspetto: Non ho a disposizione l'accessorio che espone la porta seriale quindi l'unico modo di dialogare con il dispositivo sono Active Sync o via Ethernet (il cradle ha una porta Ethernet RJ45). Per usare Active Sync si puo' usare solo Windows XP (non c'e' compatibilita' con le versioni successive). In macchina Virtualbox Active Sync funziona

Terzo aspetto: anche il dispositivo va in rete via RJ45 c'e' da mettere in conto che oramai i certificati SSL nel dispositivo sono scaduti e non possono essere aggiornati. Ci si puo' scordare di navigare il Web ed anche TerraSync non scarica aggiornamenti degli almanacchi delle effemeridi dei satelliti

Quarto aspetto: non sono riuscito a connettere la WiFi all'hotspot. Le autenticazioni sono WEP (ovviamente ...siamo nel 2004) e WPA. Provando WPA non riesco a connettermi con Access Point moderni

A questo punto il dispositivo funziona in acquisizione??

Premesso che l'antenna e' solo una L1 a 12 canali che puo' essere postprocessata (e quindi non so quanta valga la pena perderci tempo avendo a disposizione delle antenne L1+L2 a costo minore e prestazione migliore) i primi tentativi di salvare i dati su TerraSync sono risultati vani.

Il dispositivo era molto lento nell'aggancio dei satelliti ma questo e' abbastanza ovvio dato che usa un almanacco del 2004. Una volta acquisito il fix Terrasync si rifiutava di salvare i dati per un problema sull'orologio

Ho modificato a mano l'orologio di Windows CE. A questo punto il fix e' stato molto piu' veloce ma persisteva il problema. Controllando ho visto che Terrasync riportava automaticamente l'orologio di sistema al 2004




La soluzione (trovata su un forum) e' stata quella di sincronizzare l'ora tramite ActiveSync (in pratica acquisendo la data dal PC Desktop), poi lanciare TerraSync. A questo punto tutto inizia a funzionare in modo corretto

Ne vale la pena??

Per funzionare funziona ma c'e' da dire che i dati di fase per il postprocessing vengono salvati nel formato binario di Trimble e quindi c'e' da fare un ulteriore passaggio per passarli in Rinex peraltro con un software ConverttoRinex che attualmente non riesco a farlo funzionare in macchina virtuale (problemi con le librerie DotNet) 




lunedì 23 ottobre 2023

Samsung ML2160 su Debian testing nel 2023

 Nonostante sia stata dichiarata legacy la mia ML-2160 continua a stampare.


Il problema e' che i driver su Debian sono stati spostati di pacchetto (e mi scordo sempre quali sono)

apt install printer-driver-splix

martedì 17 ottobre 2023

Small docker for Golang apps

 In ufficio oramai una applicazione non puo' andare in produzione se non e' in in container...anche se e' occupa pochissimo spazio disco...il che vuol dire che si deve cercare di ottimizzare l'occupazione dello spazio disco del container

Nel Dockerfile sottostante viene utilizzato un docker con compilatore per generare un eseguibile che sara' poi copiato in un docker minimale di produzione basato su Alpine



FROM golang as builder
RUN mkdir /app
COPY . /app
WORKDIR /app
RUN https_proxy=http://proxy.toscana.it:8080 go get github.com/go-resty/resty/v2
RUN https_proxy=http://proxy.toscana.it:8080 go get github.com/sijms/go-ora/v2

RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp .

FROM alpine:latest

RUN apk --no-cache add ca-certificates
WORKDIR /root
COPY --from=builder /app/myapp .

lunedì 16 ottobre 2023

NVidia su Debian 12

 Non pensavo che sarei riuscito a montare le librerie NVidia su Debian (di solito usavo Ubuntu per semplicita') ma alla fine con il passare del tempo le cose sono migliorate molto anche in Debian


Come macchina di prova ho utilizzato un Thinkpad 550 con una GeForce 940M (384 cores 1 Gb) 

Per prima cosa si devono modificare i repositories per includere contrib e non-free 

apt install nvidia-driver firmware-misc-nonfree


apt-get install freeglut3-dev build-essential libx11-dev libxmu-dev libxi-dev libgl1-mesa-glx libglu1-mesa libglu1-mesa-dev libglfw3-dev libgles2-mesa-dev

apt -y install nvidia-cuda-toolkit nvidia-cuda-dev

Per testare ho provato a compilare gli esempi delle CUDA libraries

git clone https://github.com/zchee/cuda-sample.git

Per compilare gli esempi si deve modificare il Makefile presente in ogni directory modificando 

CUDA_PATH?=/usr

ed eliminando in SMS ?= tutti i valori ad esclusione di 50 e 52 (20 e 30 sono considerati obsoleti e non compilano piu', i restanti sono indicati come  deprecati)

Si lancia quindi il make aggiungendo prima la GLPATH

GLPATH=/usr/lib make

Il problema finale e' stato che gli esempi che usano le OpenGL non riuscivano ad aprirsi mostrando l'errore code=46(cudaErrorDevicesUnavailable) 

La soluzione e' quella di far precedere al comando le indicazioni

 __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia 

per lanciare Mandelbrot si usera' quindi

__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia ./Mandelbrot

mercoledì 11 ottobre 2023

Proxy server e Docker

Oramai mi trovo sempre piu' spesso a litigare con il mio proxy a lavoro (telelavorando a casa questo problema nono esiste). Per effettuare il download di una immagine docker da dietro ad un proxy in Linux si deve creare il file 

sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf

inserendo le impostazioni del proxy (settare le variabili di ambiente http_proxy non funziona)

[Service]
Environment="HTTP_PROXY=http://proxy.aaaaa.it:8080"
Environment="HTTPS_PROXY=http://proxy.aaaaa.toscana.it:8080"

e si riavvia il servizio 

sudo systemctl daemon-reload

sudo systemctl restart docker 

venerdì 29 settembre 2023

Olivetti M20 ST con CD sorpresa

 Mi sono comprato un Olivetti M20 perche' e' stato il primo computer (il C64 diciamo era piu' una macchina da gioco quando ero piccolo) su cui ho lavorato in un ufficio

Il modello e' un ST e deve essere una prima serie in quanto la CPU e' sotto la tastiera e le etichette di produzione indicano novembre 1982 (la presentazione della macchina e' stata Marzo 82)




Notare le correzioni fatte a mano sul PCB, simili a quelli che si trovano negli M24




Si tratta di una macchina venduta in Spagna come si vede anche dall'etichetta della manutenzione dell'unita' floppy. A proposito del drive floppy interessante vedere la calibrazione del numero di giri sul motore non a presa diretta ma tramite cinghia



ed il fatto che qualche genio ha inserito un cd rom all'interno dell'unita' floppy stesssa bloccando la meccanica (ho dovuto smontare tutto per estrarlo ma con questi computer si poteva ancora fare)


http://www.z80ne.com/m20/index.php?argument=sections/photos/luca_i/luca_i.inc

giovedì 14 settembre 2023

Europa Clipper

 In viaggio verso Giove




PS4 Stereo Camera su Linux

Visto che oramai si trovano anche a prezzi sui 20 euro ho provato la camera stereo di PS4

PS eye versione 1 e 2

Per usarla su PC si deve avere obbligatoriamente una porta USB3 e il convertitore (che costa in proporzione piu' della camera stessa ma si puo' anche autoprodurre) 


https://github.com/sieuwe1/PS4-eye-camera-for-linux-with-python-and-OpenCV

Dopo la connessione fisica deve essere modificato il firmware per usare il dispositivo come UVC



In fase di calibrazione ho avuto un errore di 0.024 con 40 immagini ed usando i file del pacchetto

Per vedere come funziona la camera ho un po' modificato il file GetDepth.py estraendo i dati di profondita' che sono contenuti nella matrice z_values

Come si vede dall'immagine sottostante c'e' una banda a sinistra che non riporta valori. Inoltre le profondita' variano da 0.3  a 2.6 m (valore massimo di profondita' restituito dal software nonostante le dimensioni della stanza siano ben maggiori)

I dati di profondita' sono molto variabili  ma se si mediano i valori accumulando le immagini (nel mio caso ho accumulato 100 immagini) l'errore si avvicina ad 1 cm

Differenza tra due mappe di profondita' consecutive



import numpy as np
import cv2
from matplotlib import pyplot as plt
import time
from datetime import datetime

#Load camera parameters
ret = np.load('param_ret.npy')
K = np.load('param_K.npy')
dist = np.load('param_dist.npy')
h,w = (800, 1264)
new_camera_matrix, roi = cv2.getOptimalNewCameraMatrix(K,dist,(w,h),1,(w,h))

mapx, mapy = cv2.initUndistortRectifyMap(K,dist, None ,new_camera_matrix,(w, h),cv2.CV_16SC2)

#cap = cv2.VideoCapture("/home/sieuwe/Desktop/vidz/full_2.avi")
#cap = cv2.VideoCapture("/home/sieuwe/Desktop/vidz/full_3.avi")
#cap = cv2.VideoCapture("/home/sieuwe/Desktop/vidz/full_1.avi")
cap = cv2.VideoCapture(2)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 3448)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 808)

kernel= np.ones((13,13),np.uint8)

#Stereo matcher settings
win_size = 5
min_disp = 10
max_disp = 16 * 2 + 10
num_disp = max_disp - min_disp # Needs to be divisible by 16
stereo = cv2.StereoSGBM_create(minDisparity= min_disp,
numDisparities = num_disp,
blockSize = 5,
uniquenessRatio = 10,
speckleWindowSize = 1000,
speckleRange = 10,
disp12MaxDiff = 25,
P1 = 8*3*win_size**2,#8*3*win_size**2,
P2 =32*3*win_size**2) #32*3*win_size**2)

sommatore=np.zeros((400,632),np.float32)
contatore = 0
limite = 100


def decode(frame):
left = np.zeros((800,1264,3), np.uint8)
right = np.zeros((800,1264,3), np.uint8)
for i in range(800):
left[i] = frame[i, 64: 1280 + 48]
right[i] = frame[i, 1280 + 48: 1280 + 48 + 1264]
return (left, right)

def get_distance(d):
return 30 * 10/d

while(1):

ret, frame = cap.read()

start = time.time()

right, left = decode(frame)

#Undistort images
#img_1_undistorted = cv2.undistort(left, K, dist, None, new_camera_matrix)
#img_2_undistorted = cv2.undistort(right, K, dist, None, new_camera_matrix)
#img_1_undistorted= cv2.remap(left,mapx,mapy, cv2.INTER_LANCZOS4, cv2.BORDER_CONSTANT, 0)
#img_2_undistorted= cv2.remap(right,mapx,mapy, cv2.INTER_LANCZOS4, cv2.BORDER_CONSTANT, 0)

#downsample image for higher speed
img_1_downsampled = cv2.pyrDown(cv2.cvtColor(left, cv2.COLOR_BGR2GRAY))
img_2_downsampled = cv2.pyrDown(cv2.cvtColor(right, cv2.COLOR_BGR2GRAY))

new_w, new_h = img_1_downsampled.shape

#compute stereo
disp = stereo.compute(img_1_downsampled,img_2_downsampled)
#denoise step 1
denoised = ((disp.astype(np.float32)/ 16)-min_disp)/num_disp
dispc= (denoised-denoised.min())*255
dispC= dispc.astype(np.uint8)
#denoise step 2
denoised= cv2.morphologyEx(dispC,cv2.MORPH_CLOSE, kernel)
#apply color map
disp_Color= cv2.applyColorMap(denoised,cv2.COLORMAP_OCEAN)
f = 0.3*w # 30cm focal length
Q = np.float32([[1, 0, 0, -0.5*new_w],
[0,-1, 0, 0.5*new_h], # turn points 180 deg around x-axis,
[0, 0, 0, f], # so that y-axis looks up
[0, 0, 1, 0]])
points = cv2.reprojectImageTo3D(disp, Q)

z_values = points[:,:,2]
print(np.size(z_values))
print(z_values.shape)
now = datetime.now()
np.save(now.strftime("%Y%m%d%H%M%S%f"),z_values)

cv2.imshow("Z",z_values)
sommatore = sommatore + z_values
contatore = contatore + 1
if (contatore == limite):
contatore = 0
sommatore = sommatore /limite
now = datetime.now()
np.save(now.strftime("%Y%m%d%H%M%S"),sommatore)
sommatore.fill(0)

z_values = z_values.flatten()
indices = z_values.argsort()

precentage = 25280
min_distance = np.mean(np.take(z_values,indices[0:precentage])) # takes the 30% lowest measuerements and gets the average distance from these.
avg_distance = np.mean(z_values) # averages all distances
max_distance = np.mean(np.take(z_values,indices[z_values.shape[0]-precentage:z_values.shape[0]])) # takes the 30% highest measuerements and gets the average distance from these.
#print(np.take(z_values,indices[z_values.shape[0]-precentage:z_values.shape[0]]))
#print(np.take(z_values,indices[:-100]))

#visualize
cv2.imshow("Depth", disp_Color)
left = cv2.resize(left,(632, 400))
color_depth = cv2.addWeighted(left,0.4,disp_Color,0.4,0)

end = time.time()
fps = 1 / (end-start)

cv2.putText(color_depth, "minimum: " + str(round(min_distance,1)),(5, 20),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255),2,cv2.LINE_AA)
cv2.putText(color_depth, "average: " + str(round(avg_distance,1)),(5, 40),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255),2,cv2.LINE_AA)
cv2.putText(color_depth, "maximum: " + str(round(max_distance,1)),(5, 60),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255),2,cv2.LINE_AA)
cv2.putText(color_depth, "FPS: " + str(round(fps)),(5, 80),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255),2,cv2.LINE_AA)

cv2.imshow("color & Depth", color_depth)

if cv2.waitKey(1) & 0xFF == ord('q'):
break

cap.release()
cv2.destroyAllWindows()







Eth0 su LuckFox Pico Mini A

 Le schede Luckfox Pico Mini A (a differenza delle sorelle maggiori) non hanno un connettore RJ45 e nonostante i pin da saldare non sembrano...