mirror of
https://forge.apps.education.fr/blender-edutech/jumeaux-numeriques.git
synced 2024-01-27 06:56:18 +01:00
Création du jumeau numérique du bras robotisé Roppy Ergo Jr
This commit is contained in:
parent
4fb9459537
commit
3020957594
12
poppy_ergo_jr/AUTHORS.md
Normal file
12
poppy_ergo_jr/AUTHORS.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Bras robotisé Poppy Ergo Jr
|
||||||
|
|
||||||
|
Maquette numérique : Fichiers STEP
|
||||||
|
- Licence : Creative Commons BY-SA V4
|
||||||
|
- Dépôt : https://github.com/poppy-project/poppy-ergo-jr
|
||||||
|
- Auteur : https://www.poppy-project.org
|
||||||
|
|
||||||
|
Maquette numérique : Fichiers FreeCAD
|
||||||
|
- Licence : Creative Commons BY-SA V4
|
||||||
|
- Dépôt : https://gitlab.com/blender-edutech/blender-edutech
|
||||||
|
- Auteur : Philippe Roy
|
||||||
|
|
423
poppy_ergo_jr/CC-BY-SA-4.0.txt
Normal file
423
poppy_ergo_jr/CC-BY-SA-4.0.txt
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||||
|
does not provide legal services or legal advice. Distribution of
|
||||||
|
Creative Commons public licenses does not create a lawyer-client or
|
||||||
|
other relationship. Creative Commons makes its licenses and related
|
||||||
|
information available on an "as-is" basis. Creative Commons gives no
|
||||||
|
warranties regarding its licenses, any material licensed under their
|
||||||
|
terms and conditions, or any related information. Creative Commons
|
||||||
|
disclaims all liability for damages resulting from their use to the
|
||||||
|
fullest extent possible.
|
||||||
|
|
||||||
|
Using Creative Commons Public Licenses
|
||||||
|
|
||||||
|
Creative Commons public licenses provide a standard set of terms and
|
||||||
|
conditions that creators and other rights holders may use to share
|
||||||
|
original works of authorship and other material subject to copyright
|
||||||
|
and certain other rights specified in the public license below. The
|
||||||
|
following considerations are for informational purposes only, are not
|
||||||
|
exhaustive, and do not form part of our licenses.
|
||||||
|
|
||||||
|
Considerations for licensors: Our public licenses are
|
||||||
|
intended for use by those authorized to give the public
|
||||||
|
permission to use material in ways otherwise restricted by
|
||||||
|
copyright and certain other rights. Our licenses are
|
||||||
|
irrevocable. Licensors should read and understand the terms
|
||||||
|
and conditions of the license they choose before applying it.
|
||||||
|
Licensors should also secure all rights necessary before
|
||||||
|
applying our licenses so that the public can reuse the
|
||||||
|
material as expected. Licensors should clearly mark any
|
||||||
|
material not subject to the license. This includes other CC-
|
||||||
|
licensed material, or material used under an exception or
|
||||||
|
limitation to copyright. More considerations for licensors:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensors
|
||||||
|
|
||||||
|
Considerations for the public: By using one of our public
|
||||||
|
licenses, a licensor grants the public permission to use the
|
||||||
|
licensed material under specified terms and conditions. If
|
||||||
|
the licensor's permission is not necessary for any reason--for
|
||||||
|
example, because of any applicable exception or limitation to
|
||||||
|
copyright--then that use is not regulated by the license. Our
|
||||||
|
licenses grant only permissions under copyright and certain
|
||||||
|
other rights that a licensor has authority to grant. Use of
|
||||||
|
the licensed material may still be restricted for other
|
||||||
|
reasons, including because others have copyright or other
|
||||||
|
rights in the material. A licensor may make special requests,
|
||||||
|
such as asking that all changes be marked or described.
|
||||||
|
Although not required by our licenses, you are encouraged to
|
||||||
|
respect those requests where reasonable. More_considerations
|
||||||
|
for the public:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensees
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons Attribution-ShareAlike 4.0 International Public
|
||||||
|
License
|
||||||
|
|
||||||
|
By exercising the Licensed Rights (defined below), You accept and agree
|
||||||
|
to be bound by the terms and conditions of this Creative Commons
|
||||||
|
Attribution-ShareAlike 4.0 International Public License ("Public
|
||||||
|
License"). To the extent this Public License may be interpreted as a
|
||||||
|
contract, You are granted the Licensed Rights in consideration of Your
|
||||||
|
acceptance of these terms and conditions, and the Licensor grants You
|
||||||
|
such rights in consideration of benefits the Licensor receives from
|
||||||
|
making the Licensed Material available under these terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
|
||||||
|
Section 1 -- Definitions.
|
||||||
|
|
||||||
|
a. Adapted Material means material subject to Copyright and Similar
|
||||||
|
Rights that is derived from or based upon the Licensed Material
|
||||||
|
and in which the Licensed Material is translated, altered,
|
||||||
|
arranged, transformed, or otherwise modified in a manner requiring
|
||||||
|
permission under the Copyright and Similar Rights held by the
|
||||||
|
Licensor. For purposes of this Public License, where the Licensed
|
||||||
|
Material is a musical work, performance, or sound recording,
|
||||||
|
Adapted Material is always produced where the Licensed Material is
|
||||||
|
synched in timed relation with a moving image.
|
||||||
|
|
||||||
|
b. Adapter's License means the license You apply to Your Copyright
|
||||||
|
and Similar Rights in Your contributions to Adapted Material in
|
||||||
|
accordance with the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
c. BY-SA Compatible License means a license listed at
|
||||||
|
creativecommons.org/compatiblelicenses, approved by Creative
|
||||||
|
Commons as essentially the equivalent of this Public License.
|
||||||
|
|
||||||
|
d. Copyright and Similar Rights means copyright and/or similar rights
|
||||||
|
closely related to copyright including, without limitation,
|
||||||
|
performance, broadcast, sound recording, and Sui Generis Database
|
||||||
|
Rights, without regard to how the rights are labeled or
|
||||||
|
categorized. For purposes of this Public License, the rights
|
||||||
|
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||||
|
Rights.
|
||||||
|
|
||||||
|
e. Effective Technological Measures means those measures that, in the
|
||||||
|
absence of proper authority, may not be circumvented under laws
|
||||||
|
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||||
|
Treaty adopted on December 20, 1996, and/or similar international
|
||||||
|
agreements.
|
||||||
|
|
||||||
|
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||||
|
any other exception or limitation to Copyright and Similar Rights
|
||||||
|
that applies to Your use of the Licensed Material.
|
||||||
|
|
||||||
|
g. License Elements means the license attributes listed in the name
|
||||||
|
of a Creative Commons Public License. The License Elements of this
|
||||||
|
Public License are Attribution and ShareAlike.
|
||||||
|
|
||||||
|
h. Licensed Material means the artistic or literary work, database,
|
||||||
|
or other material to which the Licensor applied this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
i. Licensed Rights means the rights granted to You subject to the
|
||||||
|
terms and conditions of this Public License, which are limited to
|
||||||
|
all Copyright and Similar Rights that apply to Your use of the
|
||||||
|
Licensed Material and that the Licensor has authority to license.
|
||||||
|
|
||||||
|
j. Licensor means the individual(s) or entity(ies) granting rights
|
||||||
|
under this Public License.
|
||||||
|
|
||||||
|
k. Share means to provide material to the public by any means or
|
||||||
|
process that requires permission under the Licensed Rights, such
|
||||||
|
as reproduction, public display, public performance, distribution,
|
||||||
|
dissemination, communication, or importation, and to make material
|
||||||
|
available to the public including in ways that members of the
|
||||||
|
public may access the material from a place and at a time
|
||||||
|
individually chosen by them.
|
||||||
|
|
||||||
|
l. Sui Generis Database Rights means rights other than copyright
|
||||||
|
resulting from Directive 96/9/EC of the European Parliament and of
|
||||||
|
the Council of 11 March 1996 on the legal protection of databases,
|
||||||
|
as amended and/or succeeded, as well as other essentially
|
||||||
|
equivalent rights anywhere in the world.
|
||||||
|
|
||||||
|
m. You means the individual or entity exercising the Licensed Rights
|
||||||
|
under this Public License. Your has a corresponding meaning.
|
||||||
|
|
||||||
|
|
||||||
|
Section 2 -- Scope.
|
||||||
|
|
||||||
|
a. License grant.
|
||||||
|
|
||||||
|
1. Subject to the terms and conditions of this Public License,
|
||||||
|
the Licensor hereby grants You a worldwide, royalty-free,
|
||||||
|
non-sublicensable, non-exclusive, irrevocable license to
|
||||||
|
exercise the Licensed Rights in the Licensed Material to:
|
||||||
|
|
||||||
|
a. reproduce and Share the Licensed Material, in whole or
|
||||||
|
in part; and
|
||||||
|
|
||||||
|
b. produce, reproduce, and Share Adapted Material.
|
||||||
|
|
||||||
|
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||||
|
Exceptions and Limitations apply to Your use, this Public
|
||||||
|
License does not apply, and You do not need to comply with
|
||||||
|
its terms and conditions.
|
||||||
|
|
||||||
|
3. Term. The term of this Public License is specified in Section
|
||||||
|
6(a).
|
||||||
|
|
||||||
|
4. Media and formats; technical modifications allowed. The
|
||||||
|
Licensor authorizes You to exercise the Licensed Rights in
|
||||||
|
all media and formats whether now known or hereafter created,
|
||||||
|
and to make technical modifications necessary to do so. The
|
||||||
|
Licensor waives and/or agrees not to assert any right or
|
||||||
|
authority to forbid You from making technical modifications
|
||||||
|
necessary to exercise the Licensed Rights, including
|
||||||
|
technical modifications necessary to circumvent Effective
|
||||||
|
Technological Measures. For purposes of this Public License,
|
||||||
|
simply making modifications authorized by this Section 2(a)
|
||||||
|
(4) never produces Adapted Material.
|
||||||
|
|
||||||
|
5. Downstream recipients.
|
||||||
|
|
||||||
|
a. Offer from the Licensor -- Licensed Material. Every
|
||||||
|
recipient of the Licensed Material automatically
|
||||||
|
receives an offer from the Licensor to exercise the
|
||||||
|
Licensed Rights under the terms and conditions of this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
b. Additional offer from the Licensor -- Adapted Material.
|
||||||
|
Every recipient of Adapted Material from You
|
||||||
|
automatically receives an offer from the Licensor to
|
||||||
|
exercise the Licensed Rights in the Adapted Material
|
||||||
|
under the conditions of the Adapter's License You apply.
|
||||||
|
|
||||||
|
c. No downstream restrictions. You may not offer or impose
|
||||||
|
any additional or different terms or conditions on, or
|
||||||
|
apply any Effective Technological Measures to, the
|
||||||
|
Licensed Material if doing so restricts exercise of the
|
||||||
|
Licensed Rights by any recipient of the Licensed
|
||||||
|
Material.
|
||||||
|
|
||||||
|
6. No endorsement. Nothing in this Public License constitutes or
|
||||||
|
may be construed as permission to assert or imply that You
|
||||||
|
are, or that Your use of the Licensed Material is, connected
|
||||||
|
with, or sponsored, endorsed, or granted official status by,
|
||||||
|
the Licensor or others designated to receive attribution as
|
||||||
|
provided in Section 3(a)(1)(A)(i).
|
||||||
|
|
||||||
|
b. Other rights.
|
||||||
|
|
||||||
|
1. Moral rights, such as the right of integrity, are not
|
||||||
|
licensed under this Public License, nor are publicity,
|
||||||
|
privacy, and/or other similar personality rights; however, to
|
||||||
|
the extent possible, the Licensor waives and/or agrees not to
|
||||||
|
assert any such rights held by the Licensor to the limited
|
||||||
|
extent necessary to allow You to exercise the Licensed
|
||||||
|
Rights, but not otherwise.
|
||||||
|
|
||||||
|
2. Patent and trademark rights are not licensed under this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
3. To the extent possible, the Licensor waives any right to
|
||||||
|
collect royalties from You for the exercise of the Licensed
|
||||||
|
Rights, whether directly or through a collecting society
|
||||||
|
under any voluntary or waivable statutory or compulsory
|
||||||
|
licensing scheme. In all other cases the Licensor expressly
|
||||||
|
reserves any right to collect such royalties.
|
||||||
|
|
||||||
|
|
||||||
|
Section 3 -- License Conditions.
|
||||||
|
|
||||||
|
Your exercise of the Licensed Rights is expressly made subject to the
|
||||||
|
following conditions.
|
||||||
|
|
||||||
|
a. Attribution.
|
||||||
|
|
||||||
|
1. If You Share the Licensed Material (including in modified
|
||||||
|
form), You must:
|
||||||
|
|
||||||
|
a. retain the following if it is supplied by the Licensor
|
||||||
|
with the Licensed Material:
|
||||||
|
|
||||||
|
i. identification of the creator(s) of the Licensed
|
||||||
|
Material and any others designated to receive
|
||||||
|
attribution, in any reasonable manner requested by
|
||||||
|
the Licensor (including by pseudonym if
|
||||||
|
designated);
|
||||||
|
|
||||||
|
ii. a copyright notice;
|
||||||
|
|
||||||
|
iii. a notice that refers to this Public License;
|
||||||
|
|
||||||
|
iv. a notice that refers to the disclaimer of
|
||||||
|
warranties;
|
||||||
|
|
||||||
|
v. a URI or hyperlink to the Licensed Material to the
|
||||||
|
extent reasonably practicable;
|
||||||
|
|
||||||
|
b. indicate if You modified the Licensed Material and
|
||||||
|
retain an indication of any previous modifications; and
|
||||||
|
|
||||||
|
c. indicate the Licensed Material is licensed under this
|
||||||
|
Public License, and include the text of, or the URI or
|
||||||
|
hyperlink to, this Public License.
|
||||||
|
|
||||||
|
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||||
|
reasonable manner based on the medium, means, and context in
|
||||||
|
which You Share the Licensed Material. For example, it may be
|
||||||
|
reasonable to satisfy the conditions by providing a URI or
|
||||||
|
hyperlink to a resource that includes the required
|
||||||
|
information.
|
||||||
|
|
||||||
|
3. If requested by the Licensor, You must remove any of the
|
||||||
|
information required by Section 3(a)(1)(A) to the extent
|
||||||
|
reasonably practicable.
|
||||||
|
|
||||||
|
b. ShareAlike.
|
||||||
|
|
||||||
|
In addition to the conditions in Section 3(a), if You Share
|
||||||
|
Adapted Material You produce, the following conditions also apply.
|
||||||
|
|
||||||
|
1. The Adapter's License You apply must be a Creative Commons
|
||||||
|
license with the same License Elements, this version or
|
||||||
|
later, or a BY-SA Compatible License.
|
||||||
|
|
||||||
|
2. You must include the text of, or the URI or hyperlink to, the
|
||||||
|
Adapter's License You apply. You may satisfy this condition
|
||||||
|
in any reasonable manner based on the medium, means, and
|
||||||
|
context in which You Share Adapted Material.
|
||||||
|
|
||||||
|
3. You may not offer or impose any additional or different terms
|
||||||
|
or conditions on, or apply any Effective Technological
|
||||||
|
Measures to, Adapted Material that restrict exercise of the
|
||||||
|
rights granted under the Adapter's License You apply.
|
||||||
|
|
||||||
|
|
||||||
|
Section 4 -- Sui Generis Database Rights.
|
||||||
|
|
||||||
|
Where the Licensed Rights include Sui Generis Database Rights that
|
||||||
|
apply to Your use of the Licensed Material:
|
||||||
|
|
||||||
|
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||||
|
to extract, reuse, reproduce, and Share all or a substantial
|
||||||
|
portion of the contents of the database;
|
||||||
|
|
||||||
|
b. if You include all or a substantial portion of the database
|
||||||
|
contents in a database in which You have Sui Generis Database
|
||||||
|
Rights, then the database in which You have Sui Generis Database
|
||||||
|
Rights (but not its individual contents) is Adapted Material,
|
||||||
|
|
||||||
|
including for purposes of Section 3(b); and
|
||||||
|
c. You must comply with the conditions in Section 3(a) if You Share
|
||||||
|
all or a substantial portion of the contents of the database.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 4 supplements and does not
|
||||||
|
replace Your obligations under this Public License where the Licensed
|
||||||
|
Rights include other Copyright and Similar Rights.
|
||||||
|
|
||||||
|
|
||||||
|
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||||
|
|
||||||
|
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||||
|
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||||
|
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||||
|
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||||
|
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||||
|
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||||
|
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||||
|
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||||
|
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||||
|
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||||
|
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||||
|
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||||
|
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||||
|
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||||
|
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||||
|
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
c. The disclaimer of warranties and limitation of liability provided
|
||||||
|
above shall be interpreted in a manner that, to the extent
|
||||||
|
possible, most closely approximates an absolute disclaimer and
|
||||||
|
waiver of all liability.
|
||||||
|
|
||||||
|
|
||||||
|
Section 6 -- Term and Termination.
|
||||||
|
|
||||||
|
a. This Public License applies for the term of the Copyright and
|
||||||
|
Similar Rights licensed here. However, if You fail to comply with
|
||||||
|
this Public License, then Your rights under this Public License
|
||||||
|
terminate automatically.
|
||||||
|
|
||||||
|
b. Where Your right to use the Licensed Material has terminated under
|
||||||
|
Section 6(a), it reinstates:
|
||||||
|
|
||||||
|
1. automatically as of the date the violation is cured, provided
|
||||||
|
it is cured within 30 days of Your discovery of the
|
||||||
|
violation; or
|
||||||
|
|
||||||
|
2. upon express reinstatement by the Licensor.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||||
|
right the Licensor may have to seek remedies for Your violations
|
||||||
|
of this Public License.
|
||||||
|
|
||||||
|
c. For the avoidance of doubt, the Licensor may also offer the
|
||||||
|
Licensed Material under separate terms or conditions or stop
|
||||||
|
distributing the Licensed Material at any time; however, doing so
|
||||||
|
will not terminate this Public License.
|
||||||
|
|
||||||
|
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 7 -- Other Terms and Conditions.
|
||||||
|
|
||||||
|
a. The Licensor shall not be bound by any additional or different
|
||||||
|
terms or conditions communicated by You unless expressly agreed.
|
||||||
|
|
||||||
|
b. Any arrangements, understandings, or agreements regarding the
|
||||||
|
Licensed Material not stated herein are separate from and
|
||||||
|
independent of the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 8 -- Interpretation.
|
||||||
|
|
||||||
|
a. For the avoidance of doubt, this Public License does not, and
|
||||||
|
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||||
|
conditions on any use of the Licensed Material that could lawfully
|
||||||
|
be made without permission under this Public License.
|
||||||
|
|
||||||
|
b. To the extent possible, if any provision of this Public License is
|
||||||
|
deemed unenforceable, it shall be automatically reformed to the
|
||||||
|
minimum extent necessary to make it enforceable. If the provision
|
||||||
|
cannot be reformed, it shall be severed from this Public License
|
||||||
|
without affecting the enforceability of the remaining terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
c. No term or condition of this Public License will be waived and no
|
||||||
|
failure to comply consented to unless expressly agreed to by the
|
||||||
|
Licensor.
|
||||||
|
|
||||||
|
d. Nothing in this Public License constitutes or may be interpreted
|
||||||
|
as a limitation upon, or waiver of, any privileges and immunities
|
||||||
|
that apply to the Licensor or You, including from the legal
|
||||||
|
processes of any jurisdiction or authority.
|
||||||
|
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons is not a party to its public
|
||||||
|
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||||
|
its public licenses to material it publishes and in those instances
|
||||||
|
will be considered the “Licensor.” The text of the Creative Commons
|
||||||
|
public licenses is dedicated to the public domain under the CC0 Public
|
||||||
|
Domain Dedication. Except for the limited purpose of indicating that
|
||||||
|
material is shared under a Creative Commons public license or as
|
||||||
|
otherwise permitted by the Creative Commons policies published at
|
||||||
|
creativecommons.org/policies, Creative Commons does not authorize the
|
||||||
|
use of the trademark "Creative Commons" or any other trademark or logo
|
||||||
|
of Creative Commons without its prior written consent including,
|
||||||
|
without limitation, in connection with any unauthorized modifications
|
||||||
|
to any of its public licenses or any other arrangements,
|
||||||
|
understandings, or agreements concerning use of licensed material. For
|
||||||
|
the avoidance of doubt, this paragraph does not form part of the
|
||||||
|
public licenses.
|
||||||
|
|
||||||
|
Creative Commons may be contacted at creativecommons.org.
|
1
poppy_ergo_jr/ergo_jr.bat
Normal file
1
poppy_ergo_jr/ergo_jr.bat
Normal file
@ -0,0 +1 @@
|
|||||||
|
ergo_jr.exe -con
|
305
poppy_ergo_jr/ergojr.py
Normal file
305
poppy_ergo_jr/ergojr.py
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
import bge # Bibliothèque Blender Game Engine (UPBGE)
|
||||||
|
import twin # Bibliothèque de l'environnement 3D des jumeaux numériques
|
||||||
|
import math
|
||||||
|
import time
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# ergojr.py
|
||||||
|
# @title: Commandes pour le bras robotisé Poppy Ergo Jr
|
||||||
|
# @project: Blender-EduTech
|
||||||
|
# @lang: fr
|
||||||
|
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
|
||||||
|
# @copyright: Copyright (C) 2022 Philippe Roy
|
||||||
|
# @license: GNU GPL
|
||||||
|
#
|
||||||
|
# Commandes déclenchées par/sur le simulateur (sml_*)
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# Récupérer la scène UPBGE
|
||||||
|
scene = bge.logic.getCurrentScene()
|
||||||
|
|
||||||
|
# Couleurs
|
||||||
|
|
||||||
|
couleur_magenta = (0.800, 0.005, 0.315,1) # bouton non activable : magenta
|
||||||
|
couleur_orange = (0.799, 0.130, 0.063,1) # bouton activable : orange
|
||||||
|
couleur_blanc = (0.8, 0.8, 0.8, 1) # bouton focus : blanc
|
||||||
|
couleur_jaune = (0.8, 0.619, 0.021, 1) # bouton activé : jaune
|
||||||
|
|
||||||
|
# Constantes UPBGE
|
||||||
|
|
||||||
|
JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED
|
||||||
|
JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED
|
||||||
|
ACTIVATE = bge.logic.KX_INPUT_ACTIVE
|
||||||
|
# JUST_DEACTIVATED = bge.logic.KX_SENSOR_JUST_DEACTIVATED
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Initialisation de la scène
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
def init(cont):
|
||||||
|
if cont.sensors['Init'].positive == False: # 1 seule fois
|
||||||
|
return False
|
||||||
|
|
||||||
|
twin.manip_init() # Manipulation du modèle 3D
|
||||||
|
twin.cmd_init() # Commandes
|
||||||
|
|
||||||
|
# Mémorisation de la position et orientation des composants du système
|
||||||
|
scene.objects['Portail']['init_lx']=scene.objects['Portail'].worldPosition.x
|
||||||
|
scene.objects['Portail']['init_ly']=scene.objects['Portail'].worldPosition.y
|
||||||
|
scene.objects['Portail']['init_lz']=scene.objects['Portail'].worldPosition.z
|
||||||
|
scene.objects['Engrenage']['init_rx']=scene.objects['Engrenage'].worldOrientation.to_euler().x
|
||||||
|
scene.objects['Engrenage']['init_ry']=scene.objects['Engrenage'].worldOrientation.to_euler().y
|
||||||
|
scene.objects['Engrenage']['init_rz']=scene.objects['Engrenage'].worldOrientation.to_euler().z
|
||||||
|
|
||||||
|
system_init() # Initialisation du système
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Actionneurs
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
##
|
||||||
|
# Action du simulateur pour le clignotant
|
||||||
|
##
|
||||||
|
|
||||||
|
def sml_clignotant (cont):
|
||||||
|
if scene.objects['System']['run']:
|
||||||
|
obj = cont.owner
|
||||||
|
if obj['actif'] and scene.objects['Led allumee'].visible == False:
|
||||||
|
scene.objects['Led allumee'].setVisible(True,False)
|
||||||
|
scene.objects['Led'].setVisible(False,False)
|
||||||
|
# print ("Clignotant allumée")
|
||||||
|
if obj['actif']==False and scene.objects['Led allumee'].visible == True:
|
||||||
|
scene.objects['Led'].setVisible(True,False)
|
||||||
|
scene.objects['Led allumee'].setVisible(False,False)
|
||||||
|
# print ("Clignotant éteint")
|
||||||
|
|
||||||
|
##
|
||||||
|
# Action du simulateur pour le moteur
|
||||||
|
##
|
||||||
|
|
||||||
|
def sml_moteur (cont):
|
||||||
|
if scene.objects['System']['run']:
|
||||||
|
obj = cont.owner
|
||||||
|
pas_rot = math.pi/7 # z = 14
|
||||||
|
pas = 2.35619/0.3 # pas echelle 1:1 = 2.35619 -> pas à l'échelle de la maquette (0,3) : 2.35619/0.3 = 7,85396
|
||||||
|
vitesse = 0.05
|
||||||
|
engrenage_obj = scene.objects['Engrenage']
|
||||||
|
portail_obj = scene.objects['Portail']
|
||||||
|
if obj['actif_ouvrir']:
|
||||||
|
# print (scene.objects['Portail'].worldPosition.x)
|
||||||
|
engrenage_obj.applyRotation((0, 0, -pas_rot*vitesse), True)
|
||||||
|
portail_obj.applyMovement((-pas*vitesse, 0, 0), True)
|
||||||
|
# else:
|
||||||
|
if obj['actif_fermer']:
|
||||||
|
# print (scene.objects['Portail'].worldPosition.x)
|
||||||
|
engrenage_obj.applyRotation((0, 0, pas_rot*vitesse), True)
|
||||||
|
portail_obj.applyMovement((pas*vitesse, 0, 0), True)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Capteurs fin de course
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
##
|
||||||
|
# Etat capteur fin de course portail ouvert
|
||||||
|
##
|
||||||
|
|
||||||
|
def sml_fdc_ouvert (cont):
|
||||||
|
if scene.objects['System']['run'] :
|
||||||
|
obj = cont.owner
|
||||||
|
obj_etat=obj['actif']
|
||||||
|
obj_microrupteur=scene.objects['Microrupteur fdc ouvert']
|
||||||
|
# Etat capteur en fonction de la grille : worldPosition.x : 0 -> 65.5 et localPosition.x : 0 -> 218
|
||||||
|
if scene.objects['Portail'].localPosition.x <= 0 and obj['actif'] == False :
|
||||||
|
obj['actif'] = True
|
||||||
|
if scene.objects['Portail'].localPosition.x > 0 and obj_microrupteur['actif'] == False and obj['actif'] == True :
|
||||||
|
obj['actif'] = False
|
||||||
|
#Forçage
|
||||||
|
if obj_microrupteur['actif'] == True:
|
||||||
|
obj['actif'] = True
|
||||||
|
#Couleurs
|
||||||
|
if obj['actif'] == True and obj_microrupteur.color !=couleur_jaune:
|
||||||
|
obj_microrupteur.color =couleur_jaune
|
||||||
|
if obj['actif'] == False :
|
||||||
|
if obj_microrupteur['MO'] == True and obj_microrupteur.color !=couleur_blanc:
|
||||||
|
obj_microrupteur.color =couleur_blanc
|
||||||
|
if obj_microrupteur['MO'] == False and obj_microrupteur.color !=couleur_orange:
|
||||||
|
obj_microrupteur.color =couleur_orange
|
||||||
|
|
||||||
|
##
|
||||||
|
# Etat capteur fin de course portail fermé
|
||||||
|
##
|
||||||
|
|
||||||
|
def sml_fdc_ferme (cont):
|
||||||
|
if scene.objects['System']['run'] :
|
||||||
|
obj = cont.owner
|
||||||
|
obj_etat=obj['actif']
|
||||||
|
obj_microrupteur=scene.objects['Microrupteur fdc ferme']
|
||||||
|
# Etat capteur en fonction de la grille : worldPosition.x : 0 -> 65.5 et localPosition.x : 0 -> 218
|
||||||
|
if scene.objects['Portail'].localPosition.x >= 218 and obj['actif'] == False :
|
||||||
|
obj['actif'] = True
|
||||||
|
if scene.objects['Portail'].localPosition.x < 218 and obj_microrupteur['actif'] == False and obj['actif'] == True :
|
||||||
|
obj['actif'] = False
|
||||||
|
#Forçage
|
||||||
|
if obj_microrupteur['actif'] == True:
|
||||||
|
obj['actif'] = True
|
||||||
|
#Couleurs
|
||||||
|
if obj['actif'] == True and obj_microrupteur.color !=couleur_jaune:
|
||||||
|
obj_microrupteur.color =couleur_jaune
|
||||||
|
if obj['actif'] == False :
|
||||||
|
if obj_microrupteur['MO'] == True and obj_microrupteur.color !=couleur_blanc:
|
||||||
|
obj_microrupteur.color =couleur_blanc
|
||||||
|
if obj_microrupteur['MO'] == False and obj_microrupteur.color !=couleur_orange:
|
||||||
|
obj_microrupteur.color =couleur_orange
|
||||||
|
|
||||||
|
##
|
||||||
|
# Forçage capteur fin de course avec la souris
|
||||||
|
##
|
||||||
|
|
||||||
|
def sml_microrupteur (cont):
|
||||||
|
if scene.objects['System']['run'] :
|
||||||
|
system_click(cont, cont.owner)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Capteur barrage
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
##
|
||||||
|
# Emetteur IR
|
||||||
|
##
|
||||||
|
|
||||||
|
def sml_emet_ir (cont):
|
||||||
|
if scene.objects['System']['run'] :
|
||||||
|
obj = cont.owner
|
||||||
|
obj_emetteur_ir=scene.objects['Emetteur IR']
|
||||||
|
obj_recepteur_ir=scene.objects['Recepteur IR']
|
||||||
|
if obj['actif'] and scene.objects['Emetteur IR Led allumee'].visible == False:
|
||||||
|
scene.objects['Emetteur IR Led allumee'].setVisible(True,False)
|
||||||
|
scene.objects['Emetteur IR Led'].setVisible(False,False)
|
||||||
|
obj_emetteur_ir.color = couleur_orange
|
||||||
|
obj_recepteur_ir.color = couleur_orange
|
||||||
|
if obj['actif']==False and scene.objects['Emetteur IR Led allumee'].visible == True:
|
||||||
|
scene.objects['Emetteur IR Led'].setVisible(True,False)
|
||||||
|
scene.objects['Emetteur IR Led allumee'].setVisible(False,False)
|
||||||
|
obj_emetteur_ir.color = couleur_magenta
|
||||||
|
obj_recepteur_ir.color = couleur_magenta
|
||||||
|
|
||||||
|
##
|
||||||
|
# Récepteur IR
|
||||||
|
##
|
||||||
|
|
||||||
|
def sml_recep_ir (cont):
|
||||||
|
if scene.objects['System']['run'] and scene.objects['Module emetteur IR']['actif'] :
|
||||||
|
obj = cont.owner
|
||||||
|
system_click(cont, scene.objects['Module recepteur IR'])
|
||||||
|
if scene.objects['Module recepteur IR']['actif']==True :
|
||||||
|
scene.objects['Emetteur IR'].color = couleur_jaune
|
||||||
|
scene.objects['Recepteur IR'].color = couleur_jaune
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Boutons poussoirs
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
##
|
||||||
|
# Bouton pousssoir coté rue
|
||||||
|
##
|
||||||
|
|
||||||
|
def sml_bp_rue (cont):
|
||||||
|
if scene.objects['System']['run'] :
|
||||||
|
system_click(cont, scene.objects['Module bouton cote rue'])
|
||||||
|
|
||||||
|
##
|
||||||
|
# Bouton pousssoir coté cour
|
||||||
|
##
|
||||||
|
|
||||||
|
def sml_bp_cour (cont):
|
||||||
|
if scene.objects['System']['run'] :
|
||||||
|
system_click(cont, scene.objects['Module bouton cote cour'])
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Système
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
##
|
||||||
|
# Initialisation du système
|
||||||
|
# Le moteur est géré en continue.
|
||||||
|
##
|
||||||
|
|
||||||
|
def system_init ():
|
||||||
|
|
||||||
|
# Clignotant
|
||||||
|
scene.objects['Module led']['actif']=False
|
||||||
|
scene.objects['Led allumee'].setVisible(False,False)
|
||||||
|
scene.objects['Led'].setVisible(True,False)
|
||||||
|
|
||||||
|
# Emetteur IR
|
||||||
|
scene.objects['Module emetteur IR']['actif']=False
|
||||||
|
scene.objects['Emetteur IR Led allumee'].setVisible(False,False)
|
||||||
|
scene.objects['Emetteur IR Led'].setVisible(True,False)
|
||||||
|
scene.objects['Emetteur IR'].color = couleur_magenta
|
||||||
|
scene.objects['Recepteur IR'].color = couleur_magenta
|
||||||
|
|
||||||
|
##
|
||||||
|
# Réinitialisation du système
|
||||||
|
##
|
||||||
|
|
||||||
|
def system_reset ():
|
||||||
|
|
||||||
|
# Grille à l'état initial
|
||||||
|
# applyRotationTo(scene.objects['System'], 0, 0, 0)
|
||||||
|
scene.objects['Portail'].worldPosition.x = scene.objects['Portail']['init_lx']
|
||||||
|
scene.objects['Portail'].worldPosition.y = scene.objects['Portail']['init_ly']
|
||||||
|
scene.objects['Portail'].worldPosition.z = scene.objects['Portail']['init_lz']
|
||||||
|
|
||||||
|
# Moteur à l'état initial
|
||||||
|
rres=0.001 # resolution rotation
|
||||||
|
obj1=scene.objects['Engrenage']
|
||||||
|
while (obj1.localOrientation.to_euler().y) > 1.1*rres :
|
||||||
|
obj1.applyRotation((0, 0, -rres), True)
|
||||||
|
while (obj1.localOrientation.to_euler().y) < -1.1*rres :
|
||||||
|
obj1.applyRotation((0, 0, rres), True)
|
||||||
|
|
||||||
|
# Led à l'état initial
|
||||||
|
scene.objects['Led'].setVisible(True,False)
|
||||||
|
scene.objects['Led allumee'].setVisible(False,False)
|
||||||
|
|
||||||
|
# Capteur barrage IR
|
||||||
|
scene.objects['Emetteur IR Led'].setVisible(True,False)
|
||||||
|
scene.objects['Emetteur IR Led allumee'].setVisible(False,False)
|
||||||
|
scene.objects['Emetteur IR'].color = couleur_magenta
|
||||||
|
scene.objects['Recepteur IR'].color = couleur_magenta
|
||||||
|
|
||||||
|
# I/O à l'état initial
|
||||||
|
scene.objects['Module led']['actif']=False
|
||||||
|
scene.objects['Ensemble moteur']['actif_ouvrir']=False
|
||||||
|
scene.objects['Ensemble moteur']['actif_fermer']=False
|
||||||
|
scene.objects['Capteur fdc ouvert']['actif'] =True
|
||||||
|
scene.objects['Capteur fdc ferme']['actif'] =False
|
||||||
|
scene.objects['Module emetteur IR']['actif'] =False
|
||||||
|
scene.objects['Module recepteur IR']['actif'] =False
|
||||||
|
scene.objects['Module bouton cote rue']['actif'] =False
|
||||||
|
scene.objects['Module bouton cote cour']['actif'] =False
|
||||||
|
|
||||||
|
##
|
||||||
|
# Click sur les éléments cliquables du systèmes
|
||||||
|
##
|
||||||
|
|
||||||
|
def system_click(cont, obj_activation):
|
||||||
|
obj = cont.owner
|
||||||
|
if cont.sensors['MO'].status == JUST_ACTIVATED :
|
||||||
|
obj.color = couleur_blanc
|
||||||
|
obj['MO']=True
|
||||||
|
if cont.sensors['Click'].status == JUST_ACTIVATED and scene.objects['System']['manip_mode']==0:
|
||||||
|
if obj['MO']:
|
||||||
|
obj_activation['actif'] = True
|
||||||
|
obj.color = couleur_jaune
|
||||||
|
if cont.sensors['MO'].status == JUST_RELEASED :
|
||||||
|
obj['MO']=False
|
||||||
|
if cont.sensors['Click'].status == ACTIVATE :
|
||||||
|
obj.color = couleur_jaune
|
||||||
|
else:
|
||||||
|
obj.color = couleur_orange
|
||||||
|
if cont.sensors['Click'].status == JUST_RELEASED:
|
||||||
|
obj_activation['actif'] = False
|
||||||
|
obj.color = couleur_blanc
|
||||||
|
if cont.sensors['MO'].status != ACTIVATE :
|
||||||
|
obj.color = couleur_orange
|
59
poppy_ergo_jr/ergojr_cmd.py
Normal file
59
poppy_ergo_jr/ergojr_cmd.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
from ergojr_lib import * # Bibliothèque Poppy Ergo Jr
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# ergojr_cmd.py
|
||||||
|
# @title: Commandes du bras robotisé Poppy Ergo Jr
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Instructions élémentaires du bras robotisé Poppy Ergo Jr
|
||||||
|
#
|
||||||
|
# Actions (ordre = True ou False) :
|
||||||
|
# - Allumer voyant niveau 0 : voy_0 (True|False)
|
||||||
|
# - Allumer voyant niveau 1 : voy_1 (True|False)
|
||||||
|
# - Monter le monte-charge (moteur sens trigo) : mot_m (True|False)
|
||||||
|
# - Descendre le monte-charge (moteur sens horaire) : mot_d (True|False)
|
||||||
|
#
|
||||||
|
# Capteurs (valeur retournée = True ou False) :
|
||||||
|
# - Capteur présence cabine niveau 0 : pc_0()
|
||||||
|
# - Capteur présence cabine niveau 1 : pc_1()
|
||||||
|
#
|
||||||
|
# Pupitre (valeur retournée = True ou False) :
|
||||||
|
# - Bouton poussoir appel niveau 0 : ba_0()
|
||||||
|
# - Bouton poussoir appel niveau 1 : ba_1()
|
||||||
|
#
|
||||||
|
# Gestion du temps :
|
||||||
|
# - Temporisation en seconde : tempo(duree)
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# Brochage du monte-charge
|
||||||
|
brochage={}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Fonctions
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Commandes
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
def commandes():
|
||||||
|
|
||||||
|
# Ecrire votre code ici ...
|
||||||
|
voy_0(True) # Activer le voyant du niveau 0
|
||||||
|
while True:
|
||||||
|
pass
|
||||||
|
|
||||||
|
fin() # A garder
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# En: External call << DONT CHANGE THIS SECTION >>
|
||||||
|
# Fr: Appel externe << NE PAS MODIFIER CETTE SECTION >>
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
if __name__=='start':
|
||||||
|
thread_cmd_start(commandes)
|
||||||
|
if __name__=='stop':
|
||||||
|
thread_cmd_stop()
|
94
poppy_ergo_jr/ergojr_doc.py
Normal file
94
poppy_ergo_jr/ergojr_doc.py
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
###############################################################################
|
||||||
|
# ergojr_doc.py
|
||||||
|
# @title: Documentation du bras robotisé Poppy Ergo Jr
|
||||||
|
# @project: Blender-EduTech
|
||||||
|
# @lang: fr
|
||||||
|
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
|
||||||
|
# @copyright: Copyright (C) 2022 Philippe Roy
|
||||||
|
# @license: GNU GPL
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Documentation du système
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
system_card=["twins-card", "serial-card", "movement-card", "sensor-card", "gyro-card", "board-card", "model-card", "arduino-card"]
|
||||||
|
card_description ={}
|
||||||
|
|
||||||
|
# Jumeau numérique
|
||||||
|
# Message envoyé (asynchrone) : \n avancer : a, reculer : r, droite : d, \n gauche g, marquer : m et forer : f \n\n\n """
|
||||||
|
card_twins_title="Jumeau numérique"
|
||||||
|
card_twins_text=""" jumeau() \n -> Active le jumeau réel.\n
|
||||||
|
jumeau_config(port, vitesse) \n -> Définit la configuration de la liaison \n série.\n
|
||||||
|
Si le port n\"est pas spécifié, il sera \n recherché automatiquement (carte \n Arduino Uno ou Mega). \n
|
||||||
|
La vitesse par défaut est 115200 baud."""
|
||||||
|
card_twins_url=[]
|
||||||
|
card_description.update({"twins-card" : [card_twins_title, card_twins_text, card_twins_url]})
|
||||||
|
|
||||||
|
# Liaison série
|
||||||
|
card_serial_title="Liaison série"
|
||||||
|
card_serial_text=""" serie_msg(texte) \n -> Envoi un message \n
|
||||||
|
texte=serie_rcpt() \n -> Reçoit un message"""
|
||||||
|
card_serial_url=[["Liaison série : pySerial","https://pythonhosted.org/pyserial/"],
|
||||||
|
["Protocole Firmata : pyFirmata","https://github.com/tino/pyFirmata"]]
|
||||||
|
card_description.update({"serial-card" : [card_serial_title, card_serial_text, card_serial_url]})
|
||||||
|
|
||||||
|
# Ouvrir et fermer
|
||||||
|
card_movement_title="Ouvrir et fermer"
|
||||||
|
card_movement_text=""" mot_o (True | False) \n -> Ouvre le portail (moteur sens trigo) \n
|
||||||
|
mot_f (True | False) \n -> Ferme le portail (moteur sens horaire) \n
|
||||||
|
fdc_o() \n -> Capteur fin de course portail ouvert\n Retourne True si le portail est ouvert. \n
|
||||||
|
fdc_f() \n -> Capteur fin de course portail fermé\n Retourne True si le portail est fermé."""
|
||||||
|
card_movement_url=[]
|
||||||
|
card_description.update({"movement-card" : [card_movement_title, card_movement_text, card_movement_url]})
|
||||||
|
|
||||||
|
# Capteurs
|
||||||
|
card_sensor_title="Capteur Infrarouge"
|
||||||
|
card_sensor_text=""" ir_emet(True | False) \n -> Active l\"émetteur infrarouge (IR) \n
|
||||||
|
ir_recep() \n -> Récepteur barrage infrarouge (IR)\n Retourne True s\"il n\"y a pas d\"obstacle."""
|
||||||
|
card_sensor_url=[]
|
||||||
|
card_description.update({"sensor-card" : [card_sensor_title, card_sensor_text, card_sensor_url]})
|
||||||
|
|
||||||
|
# Gyrophare
|
||||||
|
card_gyro_title="Gyrophare"
|
||||||
|
card_gyro_text=""" gyr (True | False) \n -> Active le gyrophare"""
|
||||||
|
card_gyro_url=[]
|
||||||
|
card_description.update({"gyro-card" : [card_gyro_title, card_gyro_text, card_gyro_url]})
|
||||||
|
|
||||||
|
# Pupitre
|
||||||
|
card_board_title="Pupitre"
|
||||||
|
card_board_text= """ bp_ext() \n -> Bouton poussoir coté rue\n Retourne True si le bouton est pressé.\n
|
||||||
|
bp_int() \n -> Bouton poussoir coté cour\n Retourne True si le bouton est pressé."""
|
||||||
|
card_board_url=[]
|
||||||
|
card_description.update({"board-card" : [card_board_title, card_board_text, card_board_url]})
|
||||||
|
|
||||||
|
# Maquette
|
||||||
|
card_model_title="Maquette"
|
||||||
|
card_model_text=""" Le modèle 3D est basé sur la maquette \n développée par l\"entreprise A4 Technologie. \n
|
||||||
|
Les documents techniques et \n pédagogiques signés A4 Technologie \n sont diffusés librement sous licence \n Creative Commons BY-NC-SA. \n
|
||||||
|
Le pilotage de la maquette se fait par une \n carte Arduino (Uno ou Mega) reliée à \n l"ordinateur via la liaison série (USB) et le \n protocole Firmata."""
|
||||||
|
card_model_url=[["A4 Technologie","https://www.a4.fr"],
|
||||||
|
["Maquette A4 Technologie","https://www.a4.fr/wiki/index.php?title=Portail_coulissant_(BE-APORT-COUL)"]]
|
||||||
|
card_description.update({"model-card" : [card_model_title, card_model_text, card_model_url]})
|
||||||
|
|
||||||
|
# Arduino
|
||||||
|
card_arduino_title="Arduino"
|
||||||
|
card_arduino_text=""" Arduino une plateforme open-source de \n développement électronique basée sur \n le microcontrôleur de la famille ATmega.
|
||||||
|
|
||||||
|
Elle est utilisée pour la création d"objets \n électroniques interactifs et connectés : \n IoT, domotique, robotique, ...
|
||||||
|
|
||||||
|
Le langage de programmation est le C. Par \n la bibliothèque Arduino il est particulièrement \n aisé d"accéder aux entrées/sorties de la
|
||||||
|
carte. Les platines permettent l"ajout \n d"extensions : relais, Grove, RFID, GPS, ... """
|
||||||
|
|
||||||
|
card_arduino_url=[["Plateforme Arduino","https://www.arduino.cc/"]]
|
||||||
|
card_description.update({"arduino-card" : [card_arduino_title, card_arduino_text, card_arduino_url]})
|
||||||
|
|
||||||
|
##
|
||||||
|
# Envoi des données
|
||||||
|
##
|
||||||
|
|
||||||
|
def get_system_card():
|
||||||
|
return system_card
|
||||||
|
|
||||||
|
def get_card_description():
|
||||||
|
return card_description
|
406
poppy_ergo_jr/ergojr_lib.py
Normal file
406
poppy_ergo_jr/ergojr_lib.py
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
import bge # Bibliothèque Blender Game Engine (UPBGE)
|
||||||
|
import threading # Multithreading
|
||||||
|
import trace
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
import serial # Liaison série
|
||||||
|
import pyfirmata # Protocole Firmata
|
||||||
|
from serial.tools.list_ports import comports # Détection du port automatique
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# ergojr_lib.py
|
||||||
|
# @title: Bibliothèque utilisateur du bras robotisé Poppy Ergo Jr
|
||||||
|
# @project: Blender-EduTech
|
||||||
|
# @lang: fr
|
||||||
|
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
|
||||||
|
# @copyright: Copyright (C) 2022 Philippe Roy
|
||||||
|
# @license: GNU GPL
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
scene = bge.logic.getCurrentScene()
|
||||||
|
|
||||||
|
# Threads
|
||||||
|
threads_cmd=[]
|
||||||
|
debug_thread = scene.objects['System']['debug_thread']
|
||||||
|
|
||||||
|
# Jumeau numérique
|
||||||
|
board = None
|
||||||
|
board_it = None # Iterator (input)
|
||||||
|
bp_int_pin = None
|
||||||
|
bp_ext_pin = None
|
||||||
|
fdc_o_pin = None
|
||||||
|
fdc_f_pin = None
|
||||||
|
ir_emett_pin = None
|
||||||
|
ir_recept_pin = None
|
||||||
|
mot_o_pin = None
|
||||||
|
mot_f_pin = None
|
||||||
|
gyr_pin = None
|
||||||
|
|
||||||
|
# UPBGE constants
|
||||||
|
JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED
|
||||||
|
JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED
|
||||||
|
ACTIVATE = bge.logic.KX_INPUT_ACTIVE
|
||||||
|
# JUST_DEACTIVATED = bge.logic.KX_SENSOR_JUST_DEACTIVATED
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Méthode kill pour les tâches (threads)
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
class thread_with_trace(threading.Thread):
|
||||||
|
def __init__(self, *args, **keywords):
|
||||||
|
threading.Thread.__init__(self, *args, **keywords)
|
||||||
|
self.killed = False
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self.__run_backup = self.run
|
||||||
|
self.run = self.__run
|
||||||
|
threading.Thread.start(self)
|
||||||
|
|
||||||
|
def __run(self):
|
||||||
|
sys.settrace(self.globaltrace)
|
||||||
|
self.__run_backup()
|
||||||
|
self.run = self.__run_backup
|
||||||
|
|
||||||
|
def globaltrace(self, frame, event, arg):
|
||||||
|
if event == 'call':
|
||||||
|
return self.localtrace
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def localtrace(self, frame, event, arg):
|
||||||
|
if self.killed:
|
||||||
|
if event == 'line':
|
||||||
|
raise SystemExit()
|
||||||
|
return self.localtrace
|
||||||
|
|
||||||
|
def kill(self):
|
||||||
|
self.killed = True
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Start et stop des tâches (threads)
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
def thread_start(threads, type_txt, fct):
|
||||||
|
threads.append(thread_with_trace(target = fct))
|
||||||
|
threads[len(threads)-1].start()
|
||||||
|
if (debug_thread):
|
||||||
|
print ("Thread",type_txt, "#", len(threads)-1, "open.")
|
||||||
|
|
||||||
|
def thread_stop(threads, type_txt):
|
||||||
|
i=0
|
||||||
|
zombie_flag=False
|
||||||
|
for t in threads:
|
||||||
|
if not t.is_alive():
|
||||||
|
if (debug_thread):
|
||||||
|
print ("Thread",type_txt, "#",i,"closed.")
|
||||||
|
else:
|
||||||
|
if (debug_thread):
|
||||||
|
print ("Thread",type_txt, "#",i,"still open ...")
|
||||||
|
t.kill()
|
||||||
|
t.join()
|
||||||
|
if not t.is_alive():
|
||||||
|
if (debug_thread):
|
||||||
|
print ("Thread",type_txt, "#",i,"killed.")
|
||||||
|
else:
|
||||||
|
if (debug_thread):
|
||||||
|
print ("Thread",type_txt, "#",i,"zombie...")
|
||||||
|
zombie_flag=True
|
||||||
|
i +=1
|
||||||
|
if zombie_flag==False:
|
||||||
|
if (debug_thread):
|
||||||
|
print ("All threads",type_txt, "are closed.")
|
||||||
|
scene.objects['System']['thread_cmd']=False
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
if (debug_thread):
|
||||||
|
print ("There are zombies threads",type_txt, ".")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def thread_cmd_start(fct):
|
||||||
|
thread_start(threads_cmd, "commands", fct)
|
||||||
|
|
||||||
|
def thread_cmd_stop():
|
||||||
|
thread_stop(threads_cmd, "commands")
|
||||||
|
|
||||||
|
def end():
|
||||||
|
|
||||||
|
# Jumeau numérique
|
||||||
|
if scene.objects['System']['twins']:
|
||||||
|
# serial_msg = "FI\n"
|
||||||
|
# twins_serial.write(serial_msg.encode()) # Communication série : modele 3d -> carte communication ( arduino | micro:bit )
|
||||||
|
jumeau_close()
|
||||||
|
|
||||||
|
# Thread
|
||||||
|
if (debug_thread):
|
||||||
|
print ("Thread commands is arrived.")
|
||||||
|
time.sleep(0.125)
|
||||||
|
scene.objects['System']['thread_cmd']=False
|
||||||
|
time.sleep(0.125)
|
||||||
|
|
||||||
|
def fin():
|
||||||
|
end()
|
||||||
|
|
||||||
|
def quit():
|
||||||
|
end()
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Actionneurs
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# Ordres utilisateur du clignotant
|
||||||
|
def gyr (ordre):
|
||||||
|
global gyr_pin
|
||||||
|
scene.objects['Module led']['actif']=ordre
|
||||||
|
if scene.objects['System']['twins'] :
|
||||||
|
if ordre :
|
||||||
|
gyr_pin.write(1)
|
||||||
|
else:
|
||||||
|
gyr_pin.write(0)
|
||||||
|
|
||||||
|
# Ordres utilisateur du moteur
|
||||||
|
def mot_o (ordre):
|
||||||
|
scene.objects['Ensemble moteur']['actif_ouvrir']=ordre
|
||||||
|
|
||||||
|
def mot_f (ordre):
|
||||||
|
scene.objects['Ensemble moteur']['actif_fermer']=ordre
|
||||||
|
|
||||||
|
# Ordre utilisateur du capteur barrage IR
|
||||||
|
def ir_emet(ordre):
|
||||||
|
scene.objects['Module emetteur IR']['actif']=ordre
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Capteurs
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# Compte-rendu utilisateur du capteur fin de course portail ouvert
|
||||||
|
def fdc_o ():
|
||||||
|
return scene.objects['Capteur fdc ouvert']['actif']
|
||||||
|
|
||||||
|
# Compte-rendu utilisateur du capteur fin de course portail ouvert
|
||||||
|
def fdc_f ():
|
||||||
|
return scene.objects['Capteur fdc ferme']['actif']
|
||||||
|
|
||||||
|
# Compte-rendu utilisateur du capteur barrage IR
|
||||||
|
def ir_recep ():
|
||||||
|
if scene.objects['Module recepteur IR']['actif'] :
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Boutons poussoirs
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# Compte-rendu utilisateur du bouton pousssoir coté rue
|
||||||
|
def bp_ext ():
|
||||||
|
return scene.objects['Module bouton cote rue']['actif']
|
||||||
|
|
||||||
|
# Compte-rendu utilisateur du bouton pousssoir coté cour
|
||||||
|
def bp_int ():
|
||||||
|
return scene.objects['Module bouton cote cour']['actif']
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Temporisation
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
def tempo (duree):
|
||||||
|
time.sleep(duree)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Jumeau numérique
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
##
|
||||||
|
# Recherche automatique du port
|
||||||
|
##
|
||||||
|
|
||||||
|
def serial_autoget_port():
|
||||||
|
# USB Vendor ID, USB Product ID
|
||||||
|
board_dict={'microbit' :[3368, 516],
|
||||||
|
'uno' :[9025, 67],
|
||||||
|
'mega' :[9025, 66]}
|
||||||
|
for com in comports(): # Arduino Uno
|
||||||
|
if com.vid == board_dict["uno"][0] and com.pid == board_dict["uno"][1]:
|
||||||
|
return [com.device,"Arduino Uno"]
|
||||||
|
for com in comports(): # Arduino Mega
|
||||||
|
if com.vid == board_dict["mega"][0] and com.pid == board_dict["mega"][1]:
|
||||||
|
return [com.device,"Arduino Mega"]
|
||||||
|
return [None,""]
|
||||||
|
|
||||||
|
##
|
||||||
|
# Création de l'objet carte (protocole Firmata)
|
||||||
|
##
|
||||||
|
|
||||||
|
def board_init(port):
|
||||||
|
try:
|
||||||
|
return pyfirmata.Arduino(port)
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
##
|
||||||
|
# Création de l'objet serial (communication série)
|
||||||
|
##
|
||||||
|
|
||||||
|
def serial_init(port,speed):
|
||||||
|
try:
|
||||||
|
return serial.Serial(port,speed)
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
##
|
||||||
|
# Affiche la liste des cartes (communication série)
|
||||||
|
##
|
||||||
|
|
||||||
|
def serial_devices():
|
||||||
|
for com in comports():
|
||||||
|
print ("Name : "+str(com.name)+"\n"
|
||||||
|
+" Device : "+str(com.device)+"\n"
|
||||||
|
+" Hardware ID : "+str(com.hwid)+"\n"
|
||||||
|
+" USB Vendor ID : "+str(com.vid)+"\n"
|
||||||
|
+" USB Product ID : "+str(com.pid)+"\n"
|
||||||
|
+" USB device location : "+str(com.location)+"\n"
|
||||||
|
+" USB manufacturer : "+str(com.manufacturer)+"\n"
|
||||||
|
+" USB product : "+str(com.product)+"\n"
|
||||||
|
+" Interface-specific : "+str(com.interface))
|
||||||
|
|
||||||
|
##
|
||||||
|
# Activation de la communication avec la carte de communication (Arduino, Micro:bit)
|
||||||
|
# Vitesse : 115200 -> 7 fps, 38400 -> 6 fps, 9600 -> 2 fps
|
||||||
|
# pyserial : baudrate=115200
|
||||||
|
# pyfirmata : baudrate=57600
|
||||||
|
##
|
||||||
|
|
||||||
|
def jumeau(pins):
|
||||||
|
global board
|
||||||
|
# global gyr_pin
|
||||||
|
|
||||||
|
# UI : étape 1
|
||||||
|
scene.objects['Twins-icon'].setVisible(True,True)
|
||||||
|
scene.objects['Twins-text']['Text'] = "Connection en cours ..."
|
||||||
|
scene.objects['Twins-text'].setVisible(True,False)
|
||||||
|
|
||||||
|
# Mise en place de la carte
|
||||||
|
speed = 57600
|
||||||
|
[device,board_name] =serial_autoget_port() # Recherche automatique du port
|
||||||
|
if device is None:
|
||||||
|
scene.objects['System']['twins'] = False
|
||||||
|
scene.objects['Twins-text']['Text'] = "Aucune connection disponible : jumeau réel débranché."
|
||||||
|
return False
|
||||||
|
board = board_init(device)
|
||||||
|
if board is None:
|
||||||
|
scene.objects['System']['twins'] = False
|
||||||
|
scene.objects['Twins-text']['Text'] = "Aucune connection disponible : port "+device+" pas prêt"
|
||||||
|
return False
|
||||||
|
scene.objects['System']['twins'] = True
|
||||||
|
# scene.objects['System']['twins_close'] = False
|
||||||
|
scene.objects['System']['twins_port'] = device
|
||||||
|
scene.objects['System']['twins_speed'] = speed
|
||||||
|
# scene.objects['System']['twins_readline'] = ""
|
||||||
|
board_it = pyfirmata.util.Iterator(board) # Itérateur pour les entrées
|
||||||
|
board_it.start()
|
||||||
|
|
||||||
|
# UI : étape 2
|
||||||
|
if board =="":
|
||||||
|
scene.objects['Twins-text']['Text'] = "Connection ouverte : "+device+" - "+str(speed)+" baud"
|
||||||
|
else:
|
||||||
|
scene.objects['Twins-text']['Text'] = "Connection ouverte : "+board_name+" sur "+device+" à "+str(speed)+" baud"
|
||||||
|
tempo (0.1)
|
||||||
|
|
||||||
|
# Déclaration des entrées - sorties
|
||||||
|
for pin in pins:
|
||||||
|
print (pin)
|
||||||
|
# if
|
||||||
|
# bp_ext_pin = board_io('d:'+str(es_dict['bp_ext'])+':i') # Bouton poussoir coté rue
|
||||||
|
# bp_int_pin = board_io('d:'+str(es_dict['bp_int'])+':i') # Bouton poussoir coté cour
|
||||||
|
# fdc_o_pin = board_io('d:'+str(es_dict['fdc_o'])+':i') # Capteur fin de course portail ouvert
|
||||||
|
# fdc_f_pin = board_io('d:'+str(es_dict['fdc_f'])+':i') # Capteur fin de course portail fermé
|
||||||
|
# ir_recept_pin = board_io('d:'+str(es_dict['ir_recept'])+':i') # Recepteur pour le capteur barrage IR
|
||||||
|
|
||||||
|
# gyr_pin = board_io('d:'+str(es_dict['gyr'])+':o') # Gyrophare
|
||||||
|
# mot_o_pin = board_io('d:'+str(es_dict['mot_o'])+':o') # Ouvrir le portail (moteur sens trigo)
|
||||||
|
# mot_f_pin = board_io('d:'+str(es_dict['mot_f'])+':o') # Fermer le portail (moteur sens horaire
|
||||||
|
# ir_emett_pin = board_io('d:'+str(es_dict['ir_emett'])+':o') # Emetteur pour le capteur barrage IR
|
||||||
|
return True
|
||||||
|
|
||||||
|
# def board_io(da,pin,io):
|
||||||
|
# if pin_def is not None:
|
||||||
|
# return board.get_pin(da+':'+pin_def)
|
||||||
|
# else:
|
||||||
|
# print ("Définition entrée-sortie non trouvée : "+pin_def)
|
||||||
|
|
||||||
|
##
|
||||||
|
# Fermeture de la communication série
|
||||||
|
##
|
||||||
|
|
||||||
|
def jumeau_close():
|
||||||
|
global board
|
||||||
|
# twins_serial.close() # Fermer proprement le port série
|
||||||
|
board.exit() # Fermer proprement la communication avec la carte
|
||||||
|
scene.objects['System']['twins'] = False
|
||||||
|
scene.objects['Twins-text']['Text'] = "Connection fermée"
|
||||||
|
|
||||||
|
# Configuration du port
|
||||||
|
# FIXME
|
||||||
|
def jumeau_config(port, speed):
|
||||||
|
# global board
|
||||||
|
pass
|
||||||
|
# global twins_serial
|
||||||
|
# if scene.objects['System']['twins']:
|
||||||
|
# serial_msg1 = "CF\n"
|
||||||
|
# twins_serial.write(serial_msg1.encode())
|
||||||
|
# tempo (1)
|
||||||
|
# serial_msg2 = str(speed)+"\n"
|
||||||
|
# twins_serial.write(serial_msg2.encode())
|
||||||
|
# tempo (1)
|
||||||
|
# serial_msg3 = str(temps_avancer)+"\n"
|
||||||
|
# twins_serial.write(serial_msg3.encode())
|
||||||
|
# tempo (1)
|
||||||
|
# serial_msg4 = str(temps_tourner)+"\n"
|
||||||
|
# twins_serial.write(serial_msg4.encode())
|
||||||
|
# tempo (1)
|
||||||
|
# serial_msg5 = "FC\n"
|
||||||
|
# twins_serial.write(serial_msg5.encode())
|
||||||
|
|
||||||
|
##
|
||||||
|
# Envoi d'un message vers la communication série
|
||||||
|
##
|
||||||
|
|
||||||
|
# def serie_msg(text):
|
||||||
|
# global twins_serial
|
||||||
|
# text2= text+"\n"
|
||||||
|
# scene.objects['Twins-text']['Text'] = "Communication : envoi message : "+text
|
||||||
|
# twins_serial.write(text2.encode())
|
||||||
|
|
||||||
|
##
|
||||||
|
# Mise en écoute de jumeau numérique (figeage de la scène)
|
||||||
|
##
|
||||||
|
|
||||||
|
# def twins_listen(cont):
|
||||||
|
# global twins_serial
|
||||||
|
# if scene.objects['System']['twins']:
|
||||||
|
# if scene.objects['System']['twins_readline'] != "":
|
||||||
|
# scene.objects['Twins-text']['Text'] = "Écoute de la connection figeage de la scène.... Message reçu : "+scene.objects['System']['twins_readline']
|
||||||
|
# else:
|
||||||
|
# scene.objects['Twins-text']['Text'] = "Écoute de la connection figeage de la scène..."
|
||||||
|
# if cont.sensors['Property'].positive:
|
||||||
|
# if scene.objects['System']['twins_listen'] :
|
||||||
|
# serial_msg = twins_serial.readline()
|
||||||
|
# if serial_msg is not None:
|
||||||
|
# scene.objects['System']['twins_readline'] = str(serial_msg)
|
||||||
|
# # scene.objects['Twins-text']['Text'] = "Message reçu : "+str(serial_msg)
|
||||||
|
# scene.objects['System']['twins_listen'] = False
|
||||||
|
|
||||||
|
##
|
||||||
|
# Réception d'un message de la communication série
|
||||||
|
##
|
||||||
|
|
||||||
|
# def serie_rcpt():
|
||||||
|
# # scene.objects['Twins-text']['Text'] = "Écoute de la \nconnection\n figeage de \n la scène"
|
||||||
|
# scene.objects['System']['twins_readline'] = ""
|
||||||
|
# scene.objects['System']['twins_listen'] = True
|
||||||
|
# while scene.objects['System']['twins_readline'] == "":
|
||||||
|
# if scene.objects['System']['twins_readline'] != "":
|
||||||
|
# break
|
||||||
|
# # scene.objects['Twins-text']['Text'] = "Connection\nouverte :\n"+scene.objects['System']['twins_port']+"\n"+str(scene.objects['System']['twins_speed'])+" baud"
|
||||||
|
# return scene.objects['System']['twins_readline']
|
Loading…
Reference in New Issue
Block a user