spacer.png, 0 kB

Torna indietro   Roboitalia.com - Il primo portale in Italia sulla robotica amatoriale > Robotica di base > Informatica

Rispondi
 
Strumenti discussione Modalità  visualizzazioe
  #1  
Vecchio 30-07-2014, 16.15.57
L'avatar di sergio_camici
sergio_camici sergio_camici non è collegato
Administrator
 
Data registrazione: 24-05-2002
Residenza: Binasco (MI)
Età : 55
Messaggi: 2,665
Potenza reputazione: 303
sergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua fama
Predefinito GUI in javascript

Se avete un dispositivo touch tipo smartphone o tablet, vi sarà punta vaghezza di usarlo come GUI per le vostre creature.
Ecco una bella libreria che vi permette di creare due joy da spolliciare...
Codice:
<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0," /> 
<title></title>
<style type="text/css"> 
	
	* {
	  -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
	  -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
	/* make transparent link selection, adjust last value opacity 0 to 1.0 */
	  -webkit-tap-highlight-color: rgba(0,0,0,0); 
	  -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
	  -webkit-tap-highlight-color: rgba(0,0,0,0); 
	}
	
	body {
		background-color: #000000;
		margin: 0px;
	}
	canvas {
		display:block; 
		position:absolute; 
	}
	.container {
		width:auto;
		text-align:center;
		background-color:#ff0000;
	}
</style>


</head>
<body onload = "init()">
<script src="js/Vector2.js"></script>
<script>

var canvas,
 	c, // c is the canvas' context 2D
	container, 
	halfWidth, 
	halfHeight,
	leftTouchID = -1, 
	leftTouchPos = new Vector2(0,0),
	leftTouchStartPos = new Vector2(0,0),
	leftVector = new Vector2(0,0); 
	rightTouchID = -1, 
	rightTouchPos = new Vector2(0,0),
	rightTouchStartPos = new Vector2(0,0),
	rightVector = new Vector2(0,0); 
	

setupCanvas();

var mouseX, mouseY, 
	// is this running in a touch capable environment?
	touchable = 'createTouch' in document,
	touches = []; // array of touch vectors
	
	
setInterval(draw, 1000/35); 


if(touchable) {
	canvas.addEventListener( 'touchstart', onTouchStart, false );
	canvas.addEventListener( 'touchmove', onTouchMove, false );
	canvas.addEventListener( 'touchend', onTouchEnd, false );
	window.onorientationchange = resetCanvas;  
	window.onresize = resetCanvas;  
} else {
	canvas.addEventListener( 'mousemove', onMouseMove, false );
}

function resetCanvas (e) {  
 	// resize the canvas - but remember - this clears the canvas too. 
  	canvas.width = window.innerWidth; 
	canvas.height = window.innerHeight;
	
	halfWidth = canvas.width/2; 
	halfHeight = canvas.height/2;
	
	//make sure we scroll to the top left. 
	window.scrollTo(0,0); 
}

function init(){
	
}

function draw() {
  
	c.clearRect(0,0,canvas.width, canvas.height); 

	if(touchable) {
	
		c.fillStyle	 = "white"; 
		c.fillText("L : "+leftVector.x + "-"+ leftVector.y, 10, 10); 
		c.fillText("R : "+rightVector.x + "-"+ rightVector.y, 500, 10); 
		
		for(var i=0; i<touches.length; i++) {
			
			var touch = touches[i]; 
			
			if(touch.identifier == leftTouchID){
				c.beginPath(); 
				c.strokeStyle = "cyan"; 
				c.lineWidth = 6; 
				c.arc(leftTouchStartPos.x, leftTouchStartPos.y, 40,0,Math.PI*2,true); 
				c.stroke();
				c.beginPath(); 
				c.strokeStyle = "cyan"; 
				c.lineWidth = 2; 
				c.arc(leftTouchStartPos.x, leftTouchStartPos.y, 60,0,Math.PI*2,true); 
				c.stroke();
				c.beginPath(); 
				c.strokeStyle = "cyan"; 
				c.arc(leftTouchPos.x, leftTouchPos.y, 40, 0,Math.PI*2, true); 
				c.stroke(); 
				
			} 
			if(touch.identifier == rightTouchID)
			{
				c.beginPath(); 
				c.strokeStyle = "red"; 
				c.lineWidth = 6; 
				c.arc(rightTouchStartPos.x, rightTouchStartPos.y, 40,0,Math.PI*2,true); 
				c.stroke();
				c.beginPath(); 
				c.strokeStyle = "red"; 
				c.lineWidth = 2; 
				c.arc(rightTouchStartPos.x, rightTouchStartPos.y, 60,0,Math.PI*2,true); 
				c.stroke();
				c.beginPath(); 
				c.strokeStyle = "red"; 
				c.arc(rightTouchPos.x, rightTouchPos.y, 40, 0,Math.PI*2, true); 
				c.stroke(); 
			}
		}
	} else {
		
		c.fillStyle	 = "white"; 
		c.fillText("mouse : "+mouseX+", "+mouseY, mouseX, mouseY); 
		
	}
	//c.fillText("hello", 0,0); 
	
}

function makeBullet() {
}

/*	
 *	Touch event (e) properties : 
 *	e.touches: 			Array of touch objects for every finger currently touching the screen
 *	e.targetTouches: 	Array of touch objects for every finger touching the screen that
 *						originally touched down on the DOM object the transmitted the event.
 *	e.changedTouches	Array of touch objects for touches that are changed for this event. 					
 *						I'm not sure if this would ever be a list of more than one, but would 
 *						be bad to assume. 
 *
 *	Touch objects : 
 *
 *	identifier: An identifying number, unique to each touch event
 *	target: DOM object that broadcast the event
 *	clientX: X coordinate of touch relative to the viewport (excludes scroll offset)
 *	clientY: Y coordinate of touch relative to the viewport (excludes scroll offset)
 *	screenX: Relative to the screen
 *	screenY: Relative to the screen
 *	pageX: Relative to the full page (includes scrolling)
 *	pageY: Relative to the full page (includes scrolling)
 */	

function onTouchStart(e) {
 
	for(var i = 0; i<e.changedTouches.length; i++){
		var touch =e.changedTouches[i]; 
		//console.log(leftTouchID + " " 
		if((leftTouchID<0) && (touch.clientX<halfWidth))
		{
			leftTouchID = touch.identifier; 
			leftTouchStartPos.reset(touch.clientX, touch.clientY); 	
			leftTouchPos.copyFrom(leftTouchStartPos); 
			leftVector.reset(0,0); 
		} 
		if((rightTouchID<0) && (touch.clientX>halfWidth))
		{
			rightTouchID = touch.identifier; 
			rightTouchStartPos.reset(touch.clientX, touch.clientY); 	
			rightTouchPos.copyFrom(rightTouchStartPos); 
			rightVector.reset(0,0); 
		} 
	}
	touches = e.touches; 
}
 
function onTouchMove(e) {
	 // Prevent the browser from doing its default thing (scroll, zoom)
	e.preventDefault();
	
	for(var i = 0; i<e.changedTouches.length; i++){
		var touch =e.changedTouches[i]; 
		if(leftTouchID == touch.identifier)
		{
			leftTouchPos.reset(touch.clientX, touch.clientY); 
			leftVector.copyFrom(leftTouchPos); 
			leftVector.minusEq(leftTouchStartPos); 	
		}		
		if(rightTouchID == touch.identifier)
		{
			rightTouchPos.reset(touch.clientX, touch.clientY); 
			rightVector.copyFrom(rightTouchPos); 
			rightVector.minusEq(rightTouchStartPos); 	
		}		
	}
	touches = e.touches; 
} 
 
function onTouchEnd(e) { 
   
   	touches = e.touches; 

	for(var i = 0; i<e.changedTouches.length; i++){
		var touch =e.changedTouches[i]; 
		if(leftTouchID == touch.identifier)
		{
			leftTouchID = -1; 
			leftVector.reset(0,0); 
		}		
		if(rightTouchID == touch.identifier)
		{
			rightTouchID = -1; 
			rightVector.reset(0,0); 
		}		
	}
   
}

function onMouseMove(event) {

	mouseX = event.offsetX;
	mouseY = event.offsetY;
}


function setupCanvas() {
	
	canvas = document.createElement( 'canvas' );
	c = canvas.getContext( '2d' );
	container = document.createElement( 'div' );
	container.className = "container";

	document.body.appendChild( container );
	container.appendChild(canvas);	

	resetCanvas(); 
	
	c.strokeStyle = "#ffffff";
	c.lineWidth =2;	
}


</script>
<div style="position:absolute; top:100px; left:200px; color:white"></div>
</body>

</html>
__________________
ciao
Sergio
---
Hai deciso di costruire un robot? Bene...
Cominciamo dalle brutte notizie: non e' facile...
Rispondi citando
  #2  
Vecchio 30-07-2014, 16.22.22
L'avatar di marnic
marnic marnic non è collegato
Administrator
 
Data registrazione: 24-05-2002
Residenza: Monselice (PD)
Età : 57
Messaggi: 5,458
Potenza reputazione: 422
marnic La sua reputazione è oltre la sua famamarnic La sua reputazione è oltre la sua famamarnic La sua reputazione è oltre la sua famamarnic La sua reputazione è oltre la sua famamarnic La sua reputazione è oltre la sua famamarnic La sua reputazione è oltre la sua famamarnic La sua reputazione è oltre la sua famamarnic La sua reputazione è oltre la sua famamarnic La sua reputazione è oltre la sua fama
Predefinito

Sergio, direi volentieri che lo chiedo per aiutare tutti gli utenti, in realtà sono il primo a non capire come mettere in pratica....

mi fai un passo passo?
comincia con:
Sei davanti al computer? si? bene, è acceso? ottimo, adesso clicca.....

__________________
Marnic
Roboitalia Staff
www.fabbrimarco.com
Rispondi citando
  #3  
Vecchio 30-07-2014, 16.36.02
L'avatar di astrobeed
astrobeed astrobeed non è collegato
Robottaro sostenitore
 
Data registrazione: 18-03-2004
Residenza: Roma
Età : 60
Messaggi: 3,377
Potenza reputazione: 350
astrobeed La sua reputazione è oltre la sua famaastrobeed La sua reputazione è oltre la sua famaastrobeed La sua reputazione è oltre la sua famaastrobeed La sua reputazione è oltre la sua famaastrobeed La sua reputazione è oltre la sua famaastrobeed La sua reputazione è oltre la sua famaastrobeed La sua reputazione è oltre la sua famaastrobeed La sua reputazione è oltre la sua fama
Predefinito

Citazione:
Orginalmente inviato da marnic Visualizza messaggio
comincia con:
Sei davanti al computer? si? bene, è acceso? ottimo, adesso clicca.....
Come prima cosa verifica che la tastiera del tuo pc sia identica a questa

__________________
Bye
Rispondi citando
  #4  
Vecchio 30-07-2014, 16.43.43
L'avatar di sergio_camici
sergio_camici sergio_camici non è collegato
Administrator
 
Data registrazione: 24-05-2002
Residenza: Binasco (MI)
Età : 55
Messaggi: 2,665
Potenza reputazione: 303
sergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua fama
Predefinito

Citazione:
Orginalmente inviato da marnic Visualizza messaggio
Sergio, direi volentieri che lo chiedo per aiutare tutti gli utenti, in realtà sono il primo a non capire come mettere in pratica....

mi fai un passo passo?
comincia con:
Sei davanti al computer? si? bene, è acceso? ottimo, adesso clicca.....

Har har har

Prendi il pezzo di codice, copialo in un file che chiameremo "index.html"
aprilo da un dispositivo dotato di touch...

Ok ok devo fare un passo indietro e spiegare come collegare il tutto al post sul python...
__________________
ciao
Sergio
---
Hai deciso di costruire un robot? Bene...
Cominciamo dalle brutte notizie: non e' facile...
Rispondi citando
  #5  
Vecchio 31-07-2014, 07.47.44
L'avatar di guiott
guiott guiott non è collegato
Robottaro sostenitore
 
Data registrazione: 23-04-2004
Residenza: Roma
Età : 63
Messaggi: 1,418
Potenza reputazione: 336
guiott La sua reputazione è oltre la sua famaguiott La sua reputazione è oltre la sua famaguiott La sua reputazione è oltre la sua famaguiott La sua reputazione è oltre la sua famaguiott La sua reputazione è oltre la sua famaguiott La sua reputazione è oltre la sua famaguiott La sua reputazione è oltre la sua famaguiott La sua reputazione è oltre la sua famaguiott La sua reputazione è oltre la sua fama
Invia un messaggio via AIM a guiott Invia un messaggio via MSN a guiott Invia un messaggio via Yahoo a guiott Send a message via Skype™ to guiott
Predefinito

In effetti il discorso è un po' complicato e ci sono diversi step da capire. Mi rendo conto che li ho studiati in un modo piuttosto caotico e farei molta fatica a fare un tutorial specifico sull'argomento.

Io il server lo fatto con node.js e non con python quindi sia il lato server che client sono scritti in javascript, ma i concetti sono molto simili.

Cominciamo almeno ad elencare i punti da studiare e poi, pian piano, con l'aiuto di Sergio che conosce l'argomento in modo più sistematico, forse riusciamo a fare, anche se non un tutrial, almeno una serie di passi da seguire per arrivare al risultato.

Prima puntata.

Partiamo dal server. Nel caso generico può essere un PC qualsiasi con una distro qualsiasi di Linux. Nel nostro caso (robotico) concentriamoci sulle schede più usate, che mettono a disposizione anche una serie di periferiche utili per i nostri scopi.
Rasperry Pi

Beagle Bone Black
Cubie Board
e tutte quelle, italianissime, di ACME systems:
Aria, Arietta, Acqua, e tutto il resto.

Non ho citato tutto il mondo Arduino (shield, Yun, Galileo) ma in queste pagine potete trovare molti esempi in merito che sono applicabili (è questo il bello di tutto questo sistema) anche a tutte le altre combinazioni HW/OS/Linguaggio/web server/application server/etc.

Una volta installato l'OS più adatto per la scheda scelta, Cominciamo ad elencare gli argomenti da studiare per realizzare una GUI che si interfacci con la nostra elettronica;
1 - web server specifico del linguaggio/ambiente di programmazione scelto con il relativo application server (Tornado/Python oppure Javascript/node.js). Da integrare a seconda delle esigenze con PHP e/o tutte le altre parti necessarie per arrivare al livello HW della scheda.
2 - web scocket per scambiare dati tra il server e la GUI
3 - HTML5, e quindi Javascript, per realizzare le funzioni necessarie lato client.
4 - librerie per realizzare gli strumenti, controlli, funzioni, eccetera necessari. Come i joystick proposti da Sergio (oppure questi) gli strumenti,
5 - strumenti per realizzare lo streaming video.
6 - ...
7 - ...
8 - ???

E poi... ci rivediamo tra un annetto quando avrete digerito tutta questa roba.

Scherzi a parte. Il bello di questo mondo è proprio che i concetti sono interscambiabili tra moltissimi mondi diversi e su qualsiasi argomento si abbia necessità si trovano tonnellate di pagine in rete.

Ripeto, il mio non è e non vuole/può essere un tutorial (mi mancano proprio le basi) però spero che sia uno spunto per avviare una discussione molto interessante in merito.
__________________
Guido
------
www.guiott.com
Rispondi citando
  #6  
Vecchio 31-07-2014, 12.37.08
L'avatar di sergio_camici
sergio_camici sergio_camici non è collegato
Administrator
 
Data registrazione: 24-05-2002
Residenza: Binasco (MI)
Età : 55
Messaggi: 2,665
Potenza reputazione: 303
sergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua fama
Predefinito

E' difficile dare una descrizione chiara ma non prolissa di come funziona Internet.
Di base possiamo dire il Web si basa su architettura client-server.
Per meglio dire il browser (client) richiede ad un altro programma (web-server) il file (pagine ed immagini) da visualizzare.
I due programmi di solito risiedono su due computer differenti, ma non è obbligatorio, per fare delle prove si può usare un solo computer.
Ora se per il client non ci sono grossi problemi, abbiamo detto che basta un browser, per il server ci sono varie possibilità.
Essenzialmente o installiamo un servizio (sotto Debian "sudo apt-get install httpd") o usiamo un linguaggio di script che contenga già un web server.
Ad esempio python o nodejs.
Creato il server potremo collegarci con il client e richiedere file e dati, ma non fermiamoci qui.
Ormai da anni i siti sono diventati dinamici, cioè le pagine vengono create al volo da programmi e non sono più file residenti sul disco.
Avere quindi un web-server creato da script ci permette di ampliare il nostro programma e gestire modifiche della pagina visualizzata in base a fattori esterni.
La tecnica usata prevalentemente per comuncare tra client e server si chiama AJAX.
Essa prevede che il client invii una richiesta al server e che questi risponda senza bisogno di ricaricare tutta la pagina.
caratteristica di questa tecnica è che il client inizia sempre lui con una richiesta ed il server non può mandare liberamente i dati.
Se invece ci interessa che il server possa iniziare a mandare dati senza richieste dal client dobbiamo usare un websocket.
In questo caso il client si aggancia al server, dopodiché la comunicazione è bidirezionale ed asincrona.

Dopo tutte queste buzz-word qualcuno ha ancora voglia di provare a lanciare uno script?
__________________
ciao
Sergio
---
Hai deciso di costruire un robot? Bene...
Cominciamo dalle brutte notizie: non e' facile...
Rispondi citando
  #7  
Vecchio 01-08-2014, 12.48.27
L'avatar di sergio_camici
sergio_camici sergio_camici non è collegato
Administrator
 
Data registrazione: 24-05-2002
Residenza: Binasco (MI)
Età : 55
Messaggi: 2,665
Potenza reputazione: 303
sergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua fama
Predefinito

Ok continuiamo?

Semplifichiamo i primi passi.
Useremo un semplice PC con installato python2.7

creaimo una cartella e dentro scriviamo due file:
index.html
Codice:
<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0," /> 
<title></title>
<style type="text/css"> 
	
	* {
	  -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
	  -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
	/* make transparent link selection, adjust last value opacity 0 to 1.0 */
	  -webkit-tap-highlight-color: rgba(0,0,0,0); 
	  -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
	  -webkit-tap-highlight-color: rgba(0,0,0,0); 
	}
	
	body {
		background-color: #000000;
		margin: 0px;
	}
	canvas {
		display:block; 
		position:absolute; 
	}
	.container {
		width:auto;
		text-align:center;
		background-color:#ff0000;
	}
</style>


</head>
<body>
<script src="js/jquery.min.js"></script>
<script>

var canvas,
 	c, // c is the canvas' context 2D
	container

setupCanvas();

var mouseX, mouseY
	// is this running in a touch capable environment?

	
setInterval(draw, 1000/35); 


canvas.addEventListener( 'mousemove', onMouseMove, false );
canvas.addEventListener( 'click', onMouseClick, false );

function resetCanvas (e) {  
 	// resize the canvas - but remember - this clears the canvas too. 
  	canvas.width = window.innerWidth; 
	canvas.height = window.innerHeight;
	
	//make sure we scroll to the top left. 
	window.scrollTo(0,0); 
}

function draw() {
  
	c.clearRect(0,0,canvas.width, canvas.height); 

	c.fillStyle	 = "white"; 
	c.fillText("mouse : "+mouseX+", "+mouseY, mouseX, mouseY); 
}


function onMouseMove(event) {
	mouseX = event.offsetX;
	mouseY = event.offsetY;
}
function onMouseClick(event) {
	$.ajax({ 
		type:"POST", 
		url: "",
		dataType: "json",
		data: JSON.stringify({valore:2}),
		success: function( data ) {
			alert( "Data Loaded: " + data ); 
		}
	});
}


function setupCanvas() {
	canvas = document.createElement( 'canvas' );
	c = canvas.getContext( '2d' );
	container = document.createElement( 'div' );
	container.className = "container";

	document.body.appendChild( container );
	container.appendChild(canvas);	

	resetCanvas(); 
	
	c.strokeStyle = "#ffffff";
	c.lineWidth =2;	
}


</script>
<div style="position:absolute; top:100px; left:200px; color:white"></div>
</body>

</html>
e server.py
Codice:
import threading
import webbrowser
import BaseHTTPServer
import SimpleHTTPServer
import json
 

PORT = 80

class TestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    """The test example handler."""

    def do_POST(self):
        print("Handle a post request")
        length = int(self.headers.getheader('content-length'))
        data_string = self.rfile.read(length)
        print(data_string)
        data = json.loads(data_string)
        print(data["valore"])
        try:
            result = int(data["valore"]) ** 2
        except:
            result = 'error'
        self.wfile.write(result)

def start_server():
    print("Start the server.")
    server_address = ("", PORT)
    server = BaseHTTPServer.HTTPServer(server_address, TestHandler)
    server.serve_forever()

if __name__ == "__main__":
    start_server()

Inoltre, per semplificarci la vita useremo una libreria javascript jQuery (http://jquery.com/download/)

Pertanto creiamo un sottocartella che chiameremo "js"
e scarichiamoci le jQuery chiamando il file "jquery.min.js"

Apriamo un terminale ed entriamo nella cartella.
Lanciamo "python server.py"

Apriamo il browser del cuore e digitiamo nella barra dell'indirizzo "localhost"

Dovrebbe comparire una schermata nera e se muoviamo il mouse verrà visualizzato un indicatore di coordinate.

Clicchiamo con il mouse e dovrebbe aprirsi un popup con scritto "4".

Cosa abbiamo fatto?

Semplice, iniziamo dal server:
notate il pezzo di codice
Codice:
    def do_POST(self):
        print("Handle a post request")
        length = int(self.headers.getheader('content-length'))
        data_string = self.rfile.read(length)
        print(data_string)
        data = json.loads(data_string)
        print(data["valore"])
        try:
            result = int(data["valore"]) ** 2
        except:
            result = 'error'
        self.wfile.write(result)
Questo codice si occupa di soddisfare le richieste POST.
quando ne riceve una estrae il contenuto (che si aspetta essere in formato JSON)
lo decodifica, estrae il parametro "valore" e ne ritorna il quadrato.

Nel client incece abbiamo registrato una nostra funzione associata al mouse click
Codice:
function onMouseClick(event) {
	$.ajax({ 
		type:"POST", 
		url: "",
		dataType: "json",
		data: JSON.stringify({valore:2}),
		success: function( data ) {
			alert( "Data Loaded: " + data ); 
		}
	});
}
Questo codice spedisce una richiesta POST al server passando come dato la stringa JSON che indica come valore il 2 (che al quadrato quanto fa?)

Confuso come al solito ma spero di avervi dato spunti di riflessione...
__________________
ciao
Sergio
---
Hai deciso di costruire un robot? Bene...
Cominciamo dalle brutte notizie: non e' facile...
Rispondi citando
Rispondi


Utenti attualmente attivi che stanno leggendo questa discussione: 1 (0 utenti e 1 ospiti)
 
Strumenti discussione
Modalità  visualizzazioe

Regole di scrittura
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code è Attivato
Le smilies sono Attivato
[IMG] è Attivato
Il codice HTML è Disattivato

Vai al forum


Tutti gli orari sono GMT. Adesso sono le: 20.23.20.


Basato su: vBulletin Versione 3.8.8
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
Realizzazione siti web Cobaltica Foligno
spacer.png, 0 kB