Ajout du jumeau numérique

This commit is contained in:
Philippe Roy 2022-11-02 19:21:27 +01:00
parent 9746cac173
commit 08dafb9d44
7 changed files with 138 additions and 19 deletions

View File

@ -9,13 +9,14 @@ Ropy a fortement été inpiré par [RobotProg](http://www.physicsbox.com/indexro
Ce jeu sérieux fait partie du projet open source [Blender-EduTech (Blender/UPBGE pour l'Enseignement Technologique)](https://gitlab.com/blender-edutech).
L'environnement de développement est basé sur : la plateforme de modélisation et d'animation 3D Blender ( https://blender.org ), le langage Python
(https://python.org ) et le moteur de jeu 3D UPBGE ( https://upbge.org ).
![Screenshot](img/screenshot-v2b.jpg)
![Poster](img/poster.png)
## Téléchargement
Les binaires (Game Engine Runtime) sont hébergés sur [apps.education.fr](https://nuage03.apps.education.fr/index.php/s/f5jELp5xifEM5Xx).
![Screenshot](img/screenshot-v2b.jpg)
![Poster](img/poster.png)
## Instructions et missions
Le script Python qui permet la commande du robot est le fichier 'rp_cmd.py'.
@ -27,13 +28,13 @@ Les instructions de base sont :
- Marquer la case : **rp_marquer()**
- Détecter la présence d'un mur devant à un pas : **rp_detect()** -> retourne True en présence d'un mur et False en absence de mur
Les niveaux sont :
- Niveau 1 : Les premiers pas de Ropy
- Niveau 2 : Ma première fonction
- Niveau 3 : Sécuriser Ropy
- Niveau 4 : Partir au bout du monde
- Niveau 5 : Faire face à l'inconnu
- Niveau 6 : Se rendre utile
Il y a 6 missions :
- Mission 1 : Les premiers pas de Ropy
- Mission 2 : Ma première fonction
- Mission 3 : Sécuriser Ropy
- Mission 4 : Partir au bout du monde
- Mission 5 : Faire face à l'inconnu
- Mission 6 : Se rendre utile
Du niveau 1 au niveau 5, chaque niveau donne lieu à la découverte d'une nouvelle structure algorithmique. Le niveau 6 correspond à la mission principale,
il faudra mobiliser l'ensemble de structures vues précédement.
@ -41,4 +42,20 @@ il faudra mobiliser l'ensemble de structures vues précédement.
Ropy est une plateforme pédagogique où d'autres missions pouvent être dévelopées pour mettre en oeuvre des concepts comme la programmation objet, le machine
learning ou encore le jumeau numérique.
## Documents pédagogiques
Les applications pédagogique se trouvent dans le [dépôt des documents pédagogiques du projet Blender-EduTech](https://gitlab.com/blender-edutech/blender-edutech-oer-french) .
## Développement
L'environnement de développement est basé sur : la plateforme de modélisation et d'animation 3D Blender ( https://blender.org ), le langage Python
(https://python.org ) et le moteur de jeu 3D UPBGE ( https://upbge.org ).
Le code source, les fichiers blender et les assets sont hébergés sur le dépôt [gitlab](https://gitlab.com/blender-edutech/ropy).
Ropy peut être un jumeau numérique via la liaison série. Il est donc nécessaire que l'environnement de développement Python d'UPBGE contienne la bibliothèque serial.
Les étapes sont :
- La configuration ici présente est UPBGE installé sous GNU-Linux sur ~ avec Python 3.9
- Aller dans le répertoire local de Python de UPBBE: "$ cd ~/UPBGE-0.30-linux-x86_64/3.0/python/bin"
- Installer localement (UPBGE) le gestionnaire de paquet pip : $ ./python3.9 -m pip serial"
- Installer localement (UPBGE) la bibliothèque serial : $ pip install serial -t ~/UPBGE-0.30-linux-x86_64/3.0/python/lib/python3.9/site-packages

View File

@ -0,0 +1 @@
<svg style="height: 512px; width: 512px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M2 2h508v508H2z" fill="#ffffff" fill-opacity="1" stroke="#a62a2a" stroke-opacity="1" stroke-width="2"></path><g class="" style="" transform="translate(0,0)"><path d="M138.94 22.99c-.566-.014-1.087-.01-1.56.006-.902.028-1.486.074-2.04.1-.56-.027-1.14-.072-2.043-.1-1.172-.037-2.63-.02-4.37.203h-.013l-.012.003c-33.88 4.402-58.95 36.95-58.95 78.18 0 17.88 4.53 35.75 12.616 50.138-11 4.404-20.23 11.382-27.5 20.107-9.996 11.997-16.58 27.015-21.123 43.496-9.085 32.963-10.13 72.213-10.13 107.604v9.345H65.86l10.513 163.524h54.815v.015h255.886v-.014h53.457l10.515-163.524h42.047v-9.345c0-35.39-1.048-74.64-10.133-107.604-4.544-16.48-11.125-31.5-21.122-43.496-7.27-8.725-16.498-15.703-27.5-20.106 8.085-14.386 12.617-32.257 12.617-50.137 0-41.23-25.07-73.778-58.95-78.18l-.013-.002h-.012c-.314-.04-.61-.067-.906-.095v-.007h-.066c-1.315-.12-2.454-.132-3.4-.102-.894.028-1.464.07-2.022.098-.55-.026-1.127-.07-2.022-.098-.944-.03-2.084-.018-3.4.102H140.78c-.657-.06-1.27-.094-1.84-.108zm-3.6 18.813c.236.002.35.01.605.01 1.135 0 2.276.075 3.416.197h238.185c1.14-.122 2.28-.197 3.416-.197.266 0 .383-.008.626-.01.244.002.362.01.627.01 5.338 0 10.785 1.386 15.875 3.783l.072-.153c17.34 8.21 30.108 28.395 30.108 55.94 0 18.664-6.87 38.574-15.952 49.515l-10.142 12.217 15.605 2.934c12.81 2.407 22.07 8.383 29.7 17.54 7.63 9.157 13.387 21.71 17.463 36.5 7.438 26.984 9.096 60.97 9.344 93.293h-40.77l-10.51 163.525H340.165l-.002-.015H176.78v.015H93.9L83.387 313.383H42.62c.247-32.323 1.905-66.31 9.343-93.293 4.076-14.79 9.833-27.343 17.463-36.5 7.63-9.157 16.89-15.133 29.7-17.54l15.606-2.935-10.142-12.217c-9.083-10.94-15.95-30.85-15.95-49.515 0-27.563 12.783-47.753 30.14-55.953l.077.166c5.09-2.397 10.537-3.783 15.875-3.783.258 0 .37-.008.608-.01zM169.977 60.7c3.935 5.41 7.082 11.84 9.17 19.146h158.65c2.09-7.307 5.235-13.735 9.17-19.145h-176.99zm12.013 37.837c.03.94.05 1.888.05 2.846 0 5.412-.594 10.926-1.636 16.3H336.54c-1.04-5.374-1.634-10.888-1.634-16.3 0-.958.02-1.906.05-2.846H181.99zm-7.316 37.836c-2.452 5.657-5.376 10.658-8.586 14.525l-3.834 4.62H354.69l-3.833-4.62c-3.21-3.867-6.134-8.868-8.586-14.525H174.675zm16.576 37.836c3.67 2.61 6.968 5.74 10.002 9.38 2.433 2.92 4.674 6.19 6.732 9.764H308.96c2.06-3.574 4.3-6.844 6.733-9.764 3.034-3.64 6.33-6.77 10-9.38H191.25zm25.004 37.835c.88 2.6 1.7 5.283 2.46 8.045.988 3.58 1.867 7.29 2.66 11.097h74.196c.794-3.806 1.674-7.517 2.66-11.097.762-2.762 1.582-5.446 2.46-8.045h-84.436zm8.225 37.834c.81 6.24 1.447 12.642 1.942 19.143h64.1c.496-6.5 1.134-12.903 1.945-19.144H224.48zm3.006 37.835c.253 6.384.393 12.778.483 19.144h61.007c.09-6.367.23-12.76.482-19.145h-61.974zM186.51 325.55l-1.233 19.145h146.39l-1.23-19.144H186.51zm-2.434 37.837l-1.23 19.144H334.1l-1.23-19.143H184.075zm-2.43 37.836l-1.232 19.142H336.53l-1.23-19.142H181.646zm-2.433 37.834l-1.23 19.144h160.98l-1.23-19.143h-158.52z" fill="#000000" fill-opacity="1"></path></g></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg8"
sodipodi:docname="icon_twins.svg"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1646"
inkscape:window-height="1015"
id="namedview10"
showgrid="false"
inkscape:zoom="0.68069092"
inkscape:cx="520.62575"
inkscape:cy="320.32841"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg8" />
<defs
id="defs2" />
<g
id="g6">
<path
stroke="none"
fill="#000000"
d="m 40.527894,27.248742 c 0,-1.533333 0.53333,-2.816667 1.6,-3.85 1.06667,-1.066667 2.33333,-1.6 3.8,-1.6 1.5,0 2.78333,0.533333 3.85,1.6 1.03333,1.033333 1.55,2.316667 1.55,3.85 0,1.466667 -0.51667,2.716667 -1.55,3.75 1.2,0.5 2.3,1.25 3.3,2.25 1.96667,1.966667 2.95,4.366667 2.95,7.2 0,1.5 -0.98333,2.766667 -2.95,3.8 -1.96667,1.033333 -4.35,1.55 -7.15,1.55 l -5.15,-0.7 c 1.76667,-1.3 2.58333,-2.85 2.45,-4.65 0,-3.2 -1.06667,-5.966667 -3.2,-8.3 0.63333,-0.466667 1.31667,-0.85 2.05,-1.15 -1.03333,-1.033333 -1.55,-2.283333 -1.55,-3.75 m -5.55,3.75 c 1.2,0.5 2.3,1.25 3.3,2.25 l 0.25,0.25 c 1.8,1.933333 2.7,4.25 2.7,6.95 0,1.433333 -0.9,2.65 -2.7,3.65 l -0.25,0.15 c -1.96667,1.033333 -4.35,1.55 -7.15,1.55 -2.8,0 -5.18333,-0.516667 -7.15,-1.55 -1.93333,-1.033333 -2.91667,-2.3 -2.95,-3.8 0,-2.833333 0.98333,-5.233333 2.95,-7.2 1,-1 2.08333,-1.75 3.25,-2.25 -1,-1.033333 -1.5,-2.283333 -1.5,-3.75 0,-1.533333 0.53333,-2.816667 1.6,-3.85 1.03333,-1.066667 2.3,-1.6 3.8,-1.6 1.5,0 2.78333,0.533333 3.85,1.6 1.03333,1.033333 1.55,2.316667 1.55,3.85 0,1.466667 -0.51667,2.716667 -1.55,3.75"
id="path4"
sodipodi:nodetypes="ccssscssscccccccscsccsccscscsssc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

BIN
ropy-29.blend Normal file

Binary file not shown.

View File

@ -41,7 +41,7 @@ missions_card=rp_map1.get_missions_card()
# Documentation Rover
################################################################################
rover_card=["forward-card", "turn-card", "delineate-card", "detect-card", "radar-card"]
rover_card=["forward-card", "turn-card", "delineate-card", "detect-card", "radar-card", "twins-card"]
rover_card=rover_card+["speed-card", "paint-card", "battery-card", "beacon-card"]
# Avancer et reculer
@ -77,6 +77,15 @@ rp_radar_text=" Le radar n'est toujours pas \n opérationnel ! \n\n Mais où est
rp_radar_type="mission"
card_description.update({"radar-card" : [rp_radar_title, rp_radar_text, rp_radar_type]})
# Jumeau numérique
rp_twins_title="Jumeau numérique"
rp_twins_text=" En utilisant une liaison série, Ropy peut être le jumeau numérique d'un robot réel. \n"
rp_twins_text = rp_twins_text + " rp_jumeau(port, baud) \n -> Configure et ouvre la liaison série sur le port et à la vitesse spécifiés. \n"
rp_twins_text = rp_twins_text + " rp_jumeau_close() \n -> Ferme la liaison série.\n\n"
rp_twins_text = rp_twins_text + " Messages envoyés (asynchrone) : avancer : 'a', reculer 'r', droite : 'd', gauche 'g', marquer : 'm' et forer : f"
rp_twins_type="standard"
card_description.update({"twins-card" : [rp_twins_title, rp_twins_text, rp_twins_type]})
# Cards description pour le magasin
storecard_description ={}

View File

@ -8,6 +8,7 @@ import time
import math
import mathutils
import random
import serial # Liaison série (jumeau numérique)
import rp_map1 as rp_map # Map definition
@ -28,6 +29,13 @@ import rp_map1 as rp_map # Map definition
scene = bge.logic.getCurrentScene()
debug_mvt = scene.objects['Terrain']['debug_mvt']
# twins = scene.objects['Terrain']['twins']
twins=True
# Paramétrage de la communication avec la carte de communication (Arduino, Micro:bit)
#serial_port='COM5' # Windows
serial_port='/dev/ttyACM0' # GNU/Linux
serial_baud=9600 # 115200
# Sounds
audiodev = aud.Device()
@ -197,10 +205,13 @@ def rp_avancer ():
if obj['stop']:
return False
# Points et console
if (debug_mvt):
# Points, console et jumeau numérique
if debug_mvt:
print ("rp_avancer()")
scene.objects['Points']['step'] +=1
if twins:
serial_msg = "a\n"
serial_comm.write(serial_msg.encode()) # Communication série : modele 3d -> carte communication ( arduino | micro:bit )
# Animation rapide
if scene.objects['Commands']['speed'] >= 10 and scene.objects['Points']['step']> 2: # A tendance à planter sur les premiers mouvements en rapide + balisage
@ -235,7 +246,7 @@ def rp_avancer ():
# rp_tempo (0.1*step)
# Animation
if scene.objects['Commands']['speed'] < 10 or scene.objects['Points']['step'] <=2 :
if scene.objects['Commands']['speed'] < 10:
start = 1
end = 100
layer = 0
@ -275,7 +286,7 @@ def rp_avancer ():
##
# Avancer le rover
# Reculer le rover
##
def rp_reculer ():
@ -315,10 +326,13 @@ def rp_reculer ():
if obj['stop']:
return False
# Points et console
# Points, console et jumeau numérique
if (debug_mvt):
print ("rp_reculer()")
scene.objects['Points']['step'] +=1
if twins:
serial_msg = "r\n"
serial_comm.write(serial_msg.encode()) # Communication série : modele 3d -> carte communication ( arduino | micro:bit )
# Animation rapide
if scene.objects['Commands']['speed'] >= 10 and scene.objects['Points']['step']> 2: # A tendance à planter sur les premiers mouvements en rapide + balisage
@ -380,11 +394,14 @@ def rp_gauche ():
if obj['stop']:
return False
# Points et console
# Points, console et jumeau numérique
if (debug_mvt):
print ("rp_gauche()")
scene.objects['Points']['step'] +=1
step=math.pi/2 # Pas angulaire
if twins:
serial_msg = "g\n"
serial_comm.write(serial_msg.encode()) # Communication série : modele 3d -> carte communication ( arduino | micro:bit )
# Animation rapide
if scene.objects['Commands']['speed'] >= 10:
@ -426,11 +443,14 @@ def rp_droite ():
if obj['stop']:
return False
# Points et console
# Points, console et jumeau numérique
if (debug_mvt):
print ("rp_droite()")
scene.objects['Points']['step'] +=1
step=math.pi/2 # Pas angulaire
if twins:
serial_msg = "d\n"
serial_comm.write(serial_msg.encode()) # Communication série : modele 3d -> carte communication ( arduino | micro:bit )
# Rapide
if scene.objects['Commands']['speed'] >= 10:
@ -741,6 +761,11 @@ def rp_batterie ():
def rover_colision_montain (back):
obj=scene.objects['Rover']
# Jumeau
if twins:
serial_msg = "c\n"
serial_comm.write(serial_msg.encode()) # Communication série : modele 3d -> carte communication ( arduino | micro:bit )
# Animation
start = 1
end = 120
@ -796,6 +821,11 @@ def rover_colision_montain (back):
def rover_colision_station (back):
obj=scene.objects['Rover']
# Jumeau
if twins:
serial_msg = "c\n"
serial_comm.write(serial_msg.encode()) # Communication série : modele 3d -> carte communication ( arduino | micro:bit )
# Animation
start = 1
end = 120
@ -959,6 +989,11 @@ def rover_drill (x,y):
scene.objects['Sun'].applyMovement((0, 0, 0), True)
rp_tempo (0.1)
# Jumeau
if twins:
serial_msg = "f\n"
serial_comm.write(serial_msg.encode()) # Communication série : modele 3d -> carte communication ( arduino | micro:bit )
# Tuile
for i in range (10):
if scene.objects['Drill_tile-'+str(i)].visible==False: