diff --git a/build/slides.bbl-SAVE-ERROR b/build/slides.bbl-SAVE-ERROR deleted file mode 100644 index ae5727e..0000000 --- a/build/slides.bbl-SAVE-ERROR +++ /dev/null @@ -1,249 +0,0 @@ -% $ biblatex auxiliary file $ -% $ biblatex bbl format version 3.3 $ -% Do not modify the above lines! -% -% This is an auxiliary file used by the 'biblatex' package. -% This file may safely be deleted. It will be recreated by -% biber as required. -% -\begingroup -\makeatletter -\@ifundefined{ver@biblatex.sty} - {\@latex@error - {Missing 'biblatex' package} - {The bibliography requires the 'biblatex' package.} - \aftergroup\endinput} - {} -\endgroup - - -\refsection{0} - \datalist[entry]{nty/global//global/global/global} - \entry{barrProgrammingEmbeddedSystems2006}{book}{}{} - \name{author}{3}{}{% - {{hash=1f590f436d602e75c03b0fa9947edc3c}{% - family={Barr}, - familyi={B\bibinitperiod}, - given={Michael}, - giveni={M\bibinitperiod}}}% - {{hash=bd484e4aca6f877f72c70a316e5125ff}{% - family={Massa}, - familyi={M\bibinitperiod}, - given={Anthony\bibnamedelima J.}, - giveni={A\bibinitperiod\bibinitdelim J\bibinitperiod}}}% - {{hash=1f590f436d602e75c03b0fa9947edc3c}{% - family={Barr}, - familyi={B\bibinitperiod}, - given={Michael}, - giveni={M\bibinitperiod}}}% - } - \list{location}{1}{% - {Beijing ; Sebastopol}% - } - \list{publisher}{1}{% - {O'Reilly}% - } - \strng{namehash}{0a26d209ca1cae7c5ec3bb9d00259019} - \strng{fullhash}{0a26d209ca1cae7c5ec3bb9d00259019} - \strng{fullhashraw}{0a26d209ca1cae7c5ec3bb9d00259019} - \strng{bibnamehash}{0a26d209ca1cae7c5ec3bb9d00259019} - \strng{authorbibnamehash}{0a26d209ca1cae7c5ec3bb9d00259019} - \strng{authornamehash}{0a26d209ca1cae7c5ec3bb9d00259019} - \strng{authorfullhash}{0a26d209ca1cae7c5ec3bb9d00259019} - \strng{authorfullhashraw}{0a26d209ca1cae7c5ec3bb9d00259019} - \field{sortinit}{B} - \field{sortinithash}{d7095fff47cda75ca2589920aae98399} - \field{labelnamesource}{author} - \field{labeltitlesource}{shorttitle} - \field{edition}{2nd ed} - \field{isbn}{978-0-596-00983-0} - \field{shorttitle}{Programming Embedded Systems} - \field{title}{Programming Embedded Systems: With {{C}} and {{GNU}} Development Tools} - \field{year}{2006} - \true{nocite} - \keyw{C (Computer program language),C++ (Computer program language),Embedded computer systems,Programming} - \endentry - \entry{hansonArchitecturalApproachAutonomic2004}{inproceedings}{}{} - \name{author}{4}{}{% - {{hash=4915505c877ffd461c4868a94cb7679e}{% - family={Hanson}, - familyi={H\bibinitperiod}, - given={James\bibnamedelima E.}, - giveni={J\bibinitperiod\bibinitdelim E\bibinitperiod}}}% - {{hash=4147c55dc56de3d11fe3c4fe16cc86b0}{% - family={Whalley}, - familyi={W\bibinitperiod}, - given={Ian}, - giveni={I\bibinitperiod}}}% - {{hash=6abf78bc82939db4b1774c03c8c54df3}{% - family={Chess}, - familyi={C\bibinitperiod}, - given={David\bibnamedelima M.}, - giveni={D\bibinitperiod\bibinitdelim M\bibinitperiod}}}% - {{hash=4561b6ab0ad044c0176daf9d8ad2d79e}{% - family={Kephart}, - familyi={K\bibinitperiod}, - given={Jeffrey\bibnamedelima O.}, - giveni={J\bibinitperiod\bibinitdelim O\bibinitperiod}}}% - } - \list{location}{1}{% - {USA}% - } - \list{publisher}{1}{% - {IEEE Computer Society}% - } - \strng{namehash}{568767d2b19ed559a526df3fd764b238} - \strng{fullhash}{c14defffae113d8c7dc0a82e266e9afb} - \strng{fullhashraw}{c14defffae113d8c7dc0a82e266e9afb} - \strng{bibnamehash}{568767d2b19ed559a526df3fd764b238} - \strng{authorbibnamehash}{568767d2b19ed559a526df3fd764b238} - \strng{authornamehash}{568767d2b19ed559a526df3fd764b238} - \strng{authorfullhash}{c14defffae113d8c7dc0a82e266e9afb} - \strng{authorfullhashraw}{c14defffae113d8c7dc0a82e266e9afb} - \field{sortinit}{H} - \field{sortinithash}{23a3aa7c24e56cfa16945d55545109b5} - \field{labelnamesource}{author} - \field{labeltitlesource}{title} - \field{abstract}{We describe an architectural approach to achieving the goals of autonomic computing. The architecture that we outline describes interfaces and behavioral requirements for individual system components, describes how interactions among components are established, and recommends design patterns that engender the desired system-level properties of self-configuration, self-optimization, self-healing and self-protection. We have validated many of these ideas in two prototype autonomic computing systems.} - \field{booktitle}{Proceedings of the {{First International Conference}} on {{Autonomic Computing}}} - \field{isbn}{978-0-7695-2114-5} - \field{month}{5} - \field{series}{{{ICAC}} '04} - \field{title}{An {{Architectural Approach}} to {{Autonomic Computing}}} - \field{year}{2004} - \true{nocite} - \field{pages}{2\bibrangedash 9} - \range{pages}{8} - \endentry - \entry{inderwildiImpactIntelligentCyberphysical2020}{article}{}{} - \name{author}{4}{}{% - {{hash=9f6e3f6f71503f1109985d3b9d96d734}{% - family={Inderwildi}, - familyi={I\bibinitperiod}, - given={Oliver}, - giveni={O\bibinitperiod}}}% - {{hash=9adff71f7560bbcaebadc85c4427b8d1}{% - family={Zhang}, - familyi={Z\bibinitperiod}, - given={Chuan}, - giveni={C\bibinitperiod}}}% - {{hash=b00c866e674d921261f43701cd63984c}{% - family={Wang}, - familyi={W\bibinitperiod}, - given={Xiaonan}, - giveni={X\bibinitperiod}}}% - {{hash=43f96fef254dc677a8064dd582aff746}{% - family={Kraft}, - familyi={K\bibinitperiod}, - given={Markus}, - giveni={M\bibinitperiod}}}% - } - \strng{namehash}{62281ea0b977bc2465b4b7fde5a39f53} - \strng{fullhash}{7d0447c28dd72887688686ab2fe23bfc} - \strng{fullhashraw}{7d0447c28dd72887688686ab2fe23bfc} - \strng{bibnamehash}{62281ea0b977bc2465b4b7fde5a39f53} - \strng{authorbibnamehash}{62281ea0b977bc2465b4b7fde5a39f53} - \strng{authornamehash}{62281ea0b977bc2465b4b7fde5a39f53} - \strng{authorfullhash}{7d0447c28dd72887688686ab2fe23bfc} - \strng{authorfullhashraw}{7d0447c28dd72887688686ab2fe23bfc} - \field{sortinit}{I} - \field{sortinithash}{8d291c51ee89b6cd86bf5379f0b151d8} - \field{labelnamesource}{author} - \field{labeltitlesource}{title} - \field{abstract}{Assessing the impact of digital technologies and artificial intelligence, so-called intelligent cyber-physical systems, on emission reduction in the critical sector of energy provision. , The decarbonisation of energy provision is key to managing global greenhouse gas emissions and hence mitigating climate change. Digital technologies such as big data, machine learning, and the Internet of Things are receiving more and more attention as they can aid the decarbonisation process while requiring limited investments. The orchestration of these novel technologies, so-called cyber-physical systems (CPS), provides further, synergetic effects that increase efficiency of energy provision and industrial production, thereby optimising economic feasibility and environmental impact. This comprehensive review article assesses the current as well as the potential impact of digital technologies within CPS on the decarbonisation of energy systems. Ad hoc calculation for selected applications of CPS and its subsystems estimates not only the economic impact but also the emission reduction potential. This assessment clearly shows that digitalisation of energy systems using CPS completely alters the marginal abatement cost curve (MACC) and creates novel pathways for the transition to a low-carbon energy system. Moreover, the assessment concludes that when CPS are combined with artificial intelligence (AI), decarbonisation could potentially progress at an unforeseeable pace while introducing unpredictable and potentially existential risks. Therefore, the impact of intelligent CPS on systemic resilience and energy security is discussed and policy recommendations are deducted. The assessment shows that the potential benefits clearly outweigh the latent risks as long as these are managed by policy makers.} - \field{issn}{1754-5692, 1754-5706} - \field{journaltitle}{Energy \& Environmental Science} - \field{langid}{english} - \field{number}{3} - \field{title}{The Impact of Intelligent Cyber-Physical Systems on the Decarbonization of Energy} - \field{volume}{13} - \field{year}{2020} - \field{pages}{744\bibrangedash 771} - \range{pages}{28} - \verb{doi} - \verb 10.1039/C9EE01919G - \endverb - \endentry - \entry{kephartVisionAutonomicComputing2003}{article}{}{} - \name{author}{2}{}{% - {{hash=d604375423e0bb20b33301ed78f4c146}{% - family={Kephart}, - familyi={K\bibinitperiod}, - given={J.O.}, - giveni={J\bibinitperiod}}}% - {{hash=30f63ace2b2fae54c0b9aaed0e027fb2}{% - family={Chess}, - familyi={C\bibinitperiod}, - given={D.M.}, - giveni={D\bibinitperiod}}}% - } - \strng{namehash}{28f3790346016b9a23df8d5373dc3fe7} - \strng{fullhash}{28f3790346016b9a23df8d5373dc3fe7} - \strng{fullhashraw}{28f3790346016b9a23df8d5373dc3fe7} - \strng{bibnamehash}{28f3790346016b9a23df8d5373dc3fe7} - \strng{authorbibnamehash}{28f3790346016b9a23df8d5373dc3fe7} - \strng{authornamehash}{28f3790346016b9a23df8d5373dc3fe7} - \strng{authorfullhash}{28f3790346016b9a23df8d5373dc3fe7} - \strng{authorfullhashraw}{28f3790346016b9a23df8d5373dc3fe7} - \field{sortinit}{K} - \field{sortinithash}{c02bf6bff1c488450c352b40f5d853ab} - \field{labelnamesource}{author} - \field{labeltitlesource}{title} - \field{issn}{0018-9162} - \field{journaltitle}{Computer} - \field{langid}{english} - \field{month}{1} - \field{number}{1} - \field{title}{The Vision of Autonomic Computing} - \field{volume}{36} - \field{year}{2003} - \field{pages}{41\bibrangedash 50} - \range{pages}{10} - \verb{doi} - \verb 10.1109/MC.2003.1160055 - \endverb - \endentry - \entry{leeCyberPhysicalSystems2008}{inproceedings}{}{} - \name{author}{1}{}{% - {{hash=d1baa52f3f6acfd703019b45d0b77985}{% - family={Lee}, - familyi={L\bibinitperiod}, - given={Edward\bibnamedelima A.}, - giveni={E\bibinitperiod\bibinitdelim A\bibinitperiod}}}% - } - \list{location}{1}{% - {Orlando, FL, USA}% - } - \list{publisher}{1}{% - {IEEE}% - } - \strng{namehash}{d1baa52f3f6acfd703019b45d0b77985} - \strng{fullhash}{d1baa52f3f6acfd703019b45d0b77985} - \strng{fullhashraw}{d1baa52f3f6acfd703019b45d0b77985} - \strng{bibnamehash}{d1baa52f3f6acfd703019b45d0b77985} - \strng{authorbibnamehash}{d1baa52f3f6acfd703019b45d0b77985} - \strng{authornamehash}{d1baa52f3f6acfd703019b45d0b77985} - \strng{authorfullhash}{d1baa52f3f6acfd703019b45d0b77985} - \strng{authorfullhashraw}{d1baa52f3f6acfd703019b45d0b77985} - \field{sortinit}{L} - \field{sortinithash}{7c47d417cecb1f4bd38d1825c427a61a} - \field{labelnamesource}{author} - \field{labeltitlesource}{shorttitle} - \field{abstract}{Cyber-Physical Systems (CPS) are integrations of computation and physical processes. Embedded computers and networks monitor and control the physical processes, usually with feedback loops where physical processes affect computations and vice versa. The economic and societal potential of such systems is vastly greater than what has been realized, and major investments are being made worldwide to develop the technology. There are considerable challenges, particularly because the physical components of such systems introduce safety and reliability requirements qualitatively different from those in generalpurpose computing. Moreover, physical components are qualitatively different from object-oriented software components. Standard abstractions based on method calls and threads do not work. This paper examines the challenges in designing such systems, and in particular raises the question of whether today's computing and networking technologies provide an adequate foundation for CPS. It concludes that it will not be sufficient to improve design processes, raise the level of abstraction, or verify (formally or otherwise) designs that are built on today's abstractions. To realize the full potential of CPS, we will have to rebuild computing and networking abstractions. These abstractions will have to embrace physical dynamics and computation in a unified way.} - \field{booktitle}{2008 11th {{IEEE International Symposium}} on {{Object}} and {{Component-Oriented Real-Time Distributed Computing}} ({{ISORC}})} - \field{isbn}{978-0-7695-3132-8} - \field{langid}{english} - \field{month}{5} - \field{shorttitle}{Cyber {{Physical Systems}}} - \field{title}{Cyber {{Physical Systems}}: {{Design Challenges}}} - \field{year}{2008} - \field{pages}{363\bibrangedash 369} - \range{pages}{7} - \verb{doi} - \verb 10.1109/ISORC.2008.25 - \endverb - \endentry - \enddatalist -\endrefsection -\endinput - diff --git a/build/slides.pdf b/build/slides.pdf deleted file mode 100644 index eb58f4d..0000000 Binary files a/build/slides.pdf and /dev/null differ diff --git a/packages/README.md b/packages/README.md new file mode 100644 index 0000000..e1147c0 --- /dev/null +++ b/packages/README.md @@ -0,0 +1,89 @@ +# Slides + +Compile `main.tex` with LuaLaTeX (and Biber for references). + +## Footer + +Set the names shown in the footer in the preamble: + +```latex +\title[Short title]{Long title} +\author[Short name]{Full author block} +``` + +1. The left zone holds about 70 pt of text and the middle zone about 280 pt. Longer text is scaled down. +2. The middle zone shows the section and its dots from the first `\section` onwards. Above 20 frames in a section, the dots become a count such as `3/25`. +3. Plain frames have no footer: the title page, section pages and `standout` frames. +4. Compile twice after adding frames, so that the dots are complete. + +## Partner and funding logos + +Enable partners in the preamble, in the desired display order: + +```latex +\partner{labsticc}\partner{ubo}\partner{aid}\partner{ifremer} +``` + +Logos for the following partners are included in `packages/partners/`: + +| Identifier | Partner | +| --- | --- | +| `labsticc` | Lab-STICC | +| `ubo` | Université de Bretagne Occidentale | +| `ensta` | ENSTA, Institut Polytechnique de Paris | +| `aid` | Agence de l'innovation de défense | +| `ifremer` | Ifremer | +| `lip6` | Laboratoire d'informatique de Sorbonne Université | +| `sorbonne` | Sorbonne Université | +| `academia-sinica` | Academia Sinica | +| `taipei` | University of Taipei | +| `ubo-open-factory` | UBO Open Factory | + +For example, enable the additional four with: + +```latex +\partner{lip6}\partner{sorbonne}\partner{academia-sinica}\partner{taipei} +``` + +Enable ENSTA with `\partner{ensta}`. + +Asset sources are recorded in [`partners/README.md`](partners/README.md). + +To add a logo to the bundled set, add it to `packages/partners/` in the template +repository, named after its identifier (for example `packages/partners/my-funder.png`). +In a project, leave `packages/` untouched and register the logo as shown below, so +that it survives a template update. + +PNG, PDF, JPG and JPEG are supported, searched in that order. All ten bundled +assets are transparent PNGs. Prefer high-resolution transparent PNGs or vector +PDFs, tightly cropped to the artwork; +embedded white space counts towards a logo's dimensions. SVGs should first be +exported to PDF. The existing `img/logos.png` is a combined UBO/Lab-STICC image, +not two independently selectable logos. + +For a project-specific logo, register a path (with or without its extension) and +then enable the partner: + +```latex +\declarepartner{my-funder}{img/custom-funder.pdf} +\partner{my-funder} +``` + +The title page places the logos at the bottom right, inside the theme's margins. +Column count, logo sizes, cell sizes, spacing and row wrapping are computed from +the number of available logos, their aspect ratios, the column width and the +slide height. Logos have equal bounding-box area for comparable visual weight: +wide wordmarks are shorter than square seals, rather than dominating the block. +Aspect ratios are preserved; logos are centred within evenly spaced grid cells. +The final row is right-aligned and stays within a bounded title-page area. +Repeated selections are ignored. Missing files produce warnings and are skipped, +without inserting placeholder logos. Partners do not appear on ordinary slides. + +With no partners selected, the existing `\titlegraphic{...}` is still used. +When partners are selected, they replace the legacy title graphic. + +### Additional information + +No additional logo files are needed for the ten included partners. If a funder +requires a specific logo variant, minimum size, ordering or acknowledgement text, +provide those project-specific requirements. No manual layout dimensions are needed. diff --git a/packages/VERSION b/packages/VERSION new file mode 100644 index 0000000..8cb5679 --- /dev/null +++ b/packages/VERSION @@ -0,0 +1 @@ +2026.11 diff --git a/packages/lab-common.sty b/packages/lab-common.sty new file mode 100644 index 0000000..55315fa --- /dev/null +++ b/packages/lab-common.sty @@ -0,0 +1,63 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{packages/lab-common}[2026/11/02 Macros shared by all templates] + +% This file is byte-identical in every template. Edit one copy in the template +% repository, then copy it to the others (see the root README.md). +% +% Load order: after babel, and after minted where minted is used. Load xcolor +% with its options before this package, or pass them with \PassOptionsToPackage. + +% engine: every template compiles with LuaLaTeX +\ExplSyntaxOn +\msg_new:nnn { lab-common } { require-luatex } + { This~template~requires~LuaLaTeX.~Set~the~compiler~to~LuaLaTeX~ + (on~Overleaf:~Menu,~then~Compiler). } +\sys_if_engine_luatex:F { \msg_fatal:nn { lab-common } { require-luatex } } +\ExplSyntaxOff + +% quotes +\RequirePackage[autostyle]{csquotes} +\MakeOuterQuote{"} + +% colours, from the cmyk values in dvipsnam.def, so that the macros below work +% whichever options xcolor was loaded with +\RequirePackage{xcolor} +\definecolor{labDone}{cmyk}{0.50,0,1,0} % LimeGreen +\definecolor{labTodo}{cmyk}{0,0.10,0.84,0} % Goldenrod +\definecolor{labFixme}{cmyk}{0,1,1,0} % Red +\definecolor{labYes}{cmyk}{0.44,0,0.74,0} % YellowGreen +\definecolor{labNo}{cmyk}{0,0.89,0.94,0.28}% BrickRed +\definecolor{labMaybe}{cmyk}{0,0.61,0.87,0}% Orange + +% circles +\RequirePackage{circledsteps} +\pgfkeys{/csteps/inner color=white} +\pgfkeys{/csteps/fill color=black} + +% markers +\RequirePackage{pifont} +\newcommand{\cmark}{{\color{labYes}\ding{51}}} +\newcommand{\xmark}{{\color{labNo}\ding{55}}} +\newcommand{\imark}{{\color{labMaybe}\ding{109}}} + +% status pills: \TODO, \TODO{text}, likewise \FIXME and \DONE +\RequirePackage{xparse} % for the optional {text} argument +\RequirePackage{xspace} +\NewDocumentCommand{\pill}{m m m g}{% + \CircledParamOpts{inner color=#1, outer color=#2, fill color=#2}{1}{% + \textbf{#3}\IfValueT{#4}{ \textbf{--} #4}% + }% + \IfNoValueT{#4}{\xspace}% keep the space in "\TODO bla" +} +\newcommand{\DONE}{\pill{black}{labDone}{DONE}} +\newcommand{\TODO}{\pill{black}{labTodo}{TODO}} +\newcommand{\FIXME}{\pill{white}{labFixme}{FIXME}} + +% table columns: L{width}, C{width} and R{width} wrap text, F fills the line +\RequirePackage{array} +\newcolumntype{F}{>{\arraybackslash}m{\linewidth}} +\newcolumntype{L}[1]{>{\raggedright\arraybackslash}m{#1}} +\newcolumntype{C}[1]{>{\centering\arraybackslash}m{#1}} +\newcolumntype{R}[1]{>{\raggedleft\arraybackslash}m{#1}} + +\endinput diff --git a/packages/partners/README.md b/packages/partners/README.md new file mode 100644 index 0000000..d6c9e8f --- /dev/null +++ b/packages/partners/README.md @@ -0,0 +1,31 @@ +# Partner logo sources + +Downloaded from official institutional websites on 2026-10-11. Logos remain the +property of their respective institutions; availability here does not grant +unrestricted use or imply endorsement. Follow the applicable branding rules. + +| File | Official asset source | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `labsticc.png` | [IMT Atlantique / Lab-STICC](https://www.imt-atlantique.fr/sites/default/files/users/user1867/logo-lab-sticc.png) | +| `ubo.png` | Official inline SVG labelled `Logo UBO` on [UBO's branding page](https://www.univ-brest.fr/fr/page/charte-graphique-ubo-et-logos-disposition-des-partenaires), rendered to a transparent 3,161 × 1,299 PNG at 600 DPI | +| `ensta.png` | Official blue vertical ENSTA / IP Paris transparent PNG (`Ensta-logotype-05-bleu-rvb.png`) from the [ENSTA RGB logo archive](https://www.ensta.fr/sites/default/files/content/article/pdf/LogoENSTA_RVB.zip), linked from [ENSTA's branding page](https://www.ensta.fr/logo-et-charte-graphique); cropped to 3,638 × 2,286 pixels | +| `aid.png` | [Ministère des Armées / AID](https://www.defense.gouv.fr/sites/default/files/aid/logo.png), displayed on [AID's RAPID page](https://www.defense.gouv.fr/aid/deposez-votre-projet/rapid-regime-dappui-linnovation-duale) | +| `ifremer.png` | Inline `logo-ifremer` SVG from [Ifremer](https://www.ifremer.fr/fr); rendered using the site's brand colour `#0032c6` | +| `lip6.png` | Inline `LIP6` SVG from [LIP6](https://www.lip6.fr/); rendered using `--LIP6_logo_color: #25314F` from the site's `css/common.css` | +| `sorbonne.png` | [Sorbonne Université SVG](https://www.sorbonne-universite.fr/sites/default/files/media/2019-10/logo_4.svg), rendered to PNG | +| `academia-sinica.png` | [Academia Sinica](https://www.sinica.edu.tw/images/AS_logo_2.png), referenced by its [official website](https://www.sinica.edu.tw/en) | +| `taipei.png` | [University of Taipei masthead](https://www.utaipei.edu.tw/var/file/0/1000/img/1583/366369593.jpg), linked from its [official website](https://www.utaipei.edu.tw/) | +| `ubo-open-factory.png` | [UBO Open Factory logo](https://www.univ-brest.fr/ubo-open-factory/sites/ubo-open-factory.www.univ-brest.fr/files/2023-10/logo-ubo-open-factory.png), linked from its [official website](https://www.univ-brest.fr/ubo-open-factory/fr) | + +All ten files are tightly cropped RGBA PNGs with actual transparent pixels, +not just an alpha channel containing an opaque white background. Existing alpha +was preserved. For opaque sources, only white background connected to the outer +edge was removed; white artwork inside the Academia Sinica seal was retained, +and antialiased contour pixels were unmatted to avoid white fringes. + +The SVG-derived assets were rendered at high resolution (at least 1,900 pixels +wide). UBO was re-rendered from vector paths, not upscaled from the old 489-pixel +PNG; its SVG viewport was extended to preserve the descender in “Bretagne”. +LIP6's white circular website backdrop was omitted, keeping the plain +logotype; glyph paths, proportions and lettering were not changed. Compilation +needs no SVG converter, network access or additional shell commands. diff --git a/packages/partners/academia-sinica.png b/packages/partners/academia-sinica.png new file mode 100644 index 0000000..ba5f5b9 Binary files /dev/null and b/packages/partners/academia-sinica.png differ diff --git a/packages/partners/aid.png b/packages/partners/aid.png new file mode 100644 index 0000000..c0c5209 Binary files /dev/null and b/packages/partners/aid.png differ diff --git a/packages/partners/ensta.png b/packages/partners/ensta.png new file mode 100644 index 0000000..9eef4aa Binary files /dev/null and b/packages/partners/ensta.png differ diff --git a/packages/partners/ifremer.png b/packages/partners/ifremer.png new file mode 100644 index 0000000..bbd12d9 Binary files /dev/null and b/packages/partners/ifremer.png differ diff --git a/packages/partners/labsticc.png b/packages/partners/labsticc.png new file mode 100644 index 0000000..ca8cbd6 Binary files /dev/null and b/packages/partners/labsticc.png differ diff --git a/packages/partners/lip6.png b/packages/partners/lip6.png new file mode 100644 index 0000000..057f886 Binary files /dev/null and b/packages/partners/lip6.png differ diff --git a/packages/partners/sorbonne.png b/packages/partners/sorbonne.png new file mode 100644 index 0000000..d519c78 Binary files /dev/null and b/packages/partners/sorbonne.png differ diff --git a/packages/partners/taipei.png b/packages/partners/taipei.png new file mode 100644 index 0000000..7ea3c1a Binary files /dev/null and b/packages/partners/taipei.png differ diff --git a/packages/partners/ubo-open-factory.png b/packages/partners/ubo-open-factory.png new file mode 100644 index 0000000..3f8a681 Binary files /dev/null and b/packages/partners/ubo-open-factory.png differ diff --git a/packages/partners/ubo.png b/packages/partners/ubo.png new file mode 100644 index 0000000..8db58dc Binary files /dev/null and b/packages/partners/ubo.png differ diff --git a/packages/slides-partners.sty b/packages/slides-partners.sty new file mode 100644 index 0000000..76df9a4 --- /dev/null +++ b/packages/slides-partners.sty @@ -0,0 +1,203 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{packages/slides-partners}[2026/10/11 Automatic title-page partner logos] +\RequirePackage{graphicx} +\RequirePackage{expl3} +\RequirePackage{xparse} + +\ExplSyntaxOn +\seq_new:N \g__slides_partners_seq +\prop_new:N \g__slides_partner_files_prop +\seq_new:N \l__slides_partner_files_seq +\seq_new:N \l__slides_partner_ratios_seq +\box_new:N \l__slides_partner_box +\tl_new:N \l__slides_partner_file_tl +\tl_new:N \l__slides_partner_resolved_tl +\int_new:N \l__slides_partner_count_int +\int_new:N \l__slides_partner_columns_int +\int_new:N \l__slides_partner_rows_int +\fp_new:N \l__slides_partner_minratio_fp +\fp_new:N \l__slides_partner_maxratio_fp +\fp_new:N \l__slides_partner_candidate_fp +\fp_new:N \l__slides_partner_scale_fp +\dim_new:N \l__slides_partner_width_dim +\dim_new:N \l__slides_partner_maxheight_dim +\dim_new:N \l__slides_partner_xgap_dim +\dim_new:N \l__slides_partner_ygap_dim +\dim_new:N \l__slides_partner_cellwidth_dim +\dim_new:N \l__slides_partner_cellheight_dim + +% Selection is ordered and idempotent. File lookup is delayed until rendering, +% so a declaration can appear before or after its corresponding selection. +\NewDocumentCommand{\partner}{m} + { + \seq_if_in:NnF \g__slides_partners_seq {#1} + { \seq_gput_right:Nn \g__slides_partners_seq {#1} } + } +\NewDocumentCommand{\declarepartner}{mm} + { \prop_gput:Nnn \g__slides_partner_files_prop {#1} {#2} } + +\cs_new_protected:Npn \__slides_partners_collect: + { + \seq_clear:N \l__slides_partner_files_seq + \seq_clear:N \l__slides_partner_ratios_seq + \seq_map_inline:Nn \g__slides_partners_seq + { + \prop_get:NnNF \g__slides_partner_files_prop {##1} + \l__slides_partner_file_tl + { \tl_set:Nn \l__slides_partner_file_tl {packages/partners/##1} } + \tl_clear:N \l__slides_partner_resolved_tl + \file_if_exist:VTF \l__slides_partner_file_tl + { \tl_set_eq:NN \l__slides_partner_resolved_tl \l__slides_partner_file_tl } + { + \clist_map_inline:nn {png,pdf,jpg,jpeg} + { + \file_if_exist:nT {\l__slides_partner_file_tl .####1} + { + \tl_set:Nx \l__slides_partner_resolved_tl + {\l__slides_partner_file_tl .####1} + \clist_map_break: + } + } + } + \tl_if_empty:NTF \l__slides_partner_resolved_tl + { + \PackageWarning{slides-partners} + {Logo~for~partner~`##1'~not~found~at~ + `\tl_use:N \l__slides_partner_file_tl'.~Skipping~it} + } + { + \seq_put_right:NV \l__slides_partner_files_seq + \l__slides_partner_resolved_tl + \hbox_set:Nn \l__slides_partner_box + { \includegraphics{\tl_use:N \l__slides_partner_resolved_tl} } + \seq_put_right:Nx \l__slides_partner_ratios_seq + { + \fp_eval:n + { \dim_to_fp:n {\box_wd:N \l__slides_partner_box} / + \dim_to_fp:n {\box_ht:N \l__slides_partner_box + + \box_dp:N \l__slides_partner_box} } + } + } + } + } + +% Equal-area logos in equal-width cells give seals and wide wordmarks comparable +% visual weight. Try every column count, maximizing the common area scale while +% fitting the tallest and widest logos into the available title-page rectangle. +\cs_new_protected:Npn \__slides_partners_layout: + { + \int_set:Nn \l__slides_partner_count_int + { \seq_count:N \l__slides_partner_files_seq } + % Keep a margin on the left so a full grid stays clear of the affiliations. + \dim_set:Nn \l__slides_partner_width_dim {.82\linewidth} + \dim_set:Nn \l__slides_partner_maxheight_dim {.24\paperheight} + \dim_set:Nn \l__slides_partner_xgap_dim + { \fp_to_dim:n {min(.04 * \dim_to_fp:n {\linewidth}, + .25 * \dim_to_fp:n {\linewidth} / max(1,\l__slides_partner_count_int-1))} } + \dim_set:Nn \l__slides_partner_ygap_dim + { \fp_to_dim:n {min(.015 * \dim_to_fp:n {\paperheight}, + .25 * \dim_to_fp:n {\l__slides_partner_maxheight_dim} / + max(1,\l__slides_partner_count_int-1))} } + \fp_set:Nn \l__slides_partner_minratio_fp {inf} + \fp_zero:N \l__slides_partner_maxratio_fp + \seq_map_inline:Nn \l__slides_partner_ratios_seq + { + \fp_set:Nn \l__slides_partner_minratio_fp + {min(\l__slides_partner_minratio_fp,##1)} + \fp_set:Nn \l__slides_partner_maxratio_fp + {max(\l__slides_partner_maxratio_fp,##1)} + } + \fp_zero:N \l__slides_partner_scale_fp + \int_set:Nn \l__slides_partner_columns_int {1} + \int_step_inline:nnnn {\l__slides_partner_count_int} {-1} {1} + { + \int_set:Nn \l__slides_partner_rows_int + { \fp_eval:n {ceil(\l__slides_partner_count_int / ##1)} } + \fp_set:Nn \l__slides_partner_candidate_fp + { min(.14 * \dim_to_fp:n {\paperheight}, + (\dim_to_fp:n {\l__slides_partner_maxheight_dim} - + (\l__slides_partner_rows_int-1) * + \dim_to_fp:n {\l__slides_partner_ygap_dim}) / + \l__slides_partner_rows_int * sqrt(\l__slides_partner_minratio_fp), + (\dim_to_fp:n {\l__slides_partner_width_dim} - + (##1-1) * \dim_to_fp:n {\l__slides_partner_xgap_dim}) / + ##1 / sqrt(\l__slides_partner_maxratio_fp)) } + % Break equal-size ties by minimizing unused cells in the final row. + \fp_compare:nT + { \l__slides_partner_candidate_fp > \l__slides_partner_scale_fp + .0001 || + (abs(\l__slides_partner_candidate_fp - \l__slides_partner_scale_fp) <= .0001 && + ##1 * \l__slides_partner_rows_int < + \l__slides_partner_columns_int * + ceil(\l__slides_partner_count_int / \l__slides_partner_columns_int)) } + { + \fp_set_eq:NN \l__slides_partner_scale_fp \l__slides_partner_candidate_fp + \int_set:Nn \l__slides_partner_columns_int {##1} + } + } + % Size cells to the widest rendered logo, not the entire available column. + % The enclosing row still right-aligns the compact grid in the title footer. + \dim_set:Nn \l__slides_partner_cellwidth_dim + { \fp_to_dim:n {\l__slides_partner_scale_fp * sqrt(\l__slides_partner_maxratio_fp)} } + \dim_set:Nn \l__slides_partner_cellheight_dim + { \fp_to_dim:n {\l__slides_partner_scale_fp / sqrt(\l__slides_partner_minratio_fp)} } + } + +\cs_new_protected:Npn \__slides_partners_typeset: + { + \vbox + { + \offinterlineskip + \int_step_inline:nn {\l__slides_partner_count_int} + { + \int_compare:nNnT + {\int_mod:nn {##1-1} {\l__slides_partner_columns_int}} = {0} + { + \int_compare:nNnT {##1} > {1} + { \vskip \l__slides_partner_ygap_dim } + \hbox_to_wd:nn {\linewidth} + { + \hfil + \int_step_inline:nnn {##1} + {\int_min:nn {##1+\l__slides_partner_columns_int-1} + {\l__slides_partner_count_int}} + { + \int_compare:nNnT {####1} > {##1} + { \hskip \l__slides_partner_xgap_dim } + \vbox_to_ht:nn {\l__slides_partner_cellheight_dim} + { + \vfil + \hbox_to_wd:nn {\l__slides_partner_cellwidth_dim} + { + \hfil + \includegraphics[height=\fp_to_dim:n + {\l__slides_partner_scale_fp / sqrt( + \seq_item:Nn \l__slides_partner_ratios_seq {####1})}] + {\seq_item:Nn \l__slides_partner_files_seq {####1}} + \hfil + } + \vfil + } + } + } + } + } + } + } + +\NewDocumentCommand{\insertpartnerlogos}{} + { + \group_begin: + \seq_if_empty:NTF \g__slides_partners_seq + { \inserttitlegraphic } % Backwards compatibility with existing slides. + { + \__slides_partners_collect: + \seq_if_empty:NF \l__slides_partner_files_seq + { + \__slides_partners_layout: + \__slides_partners_typeset: + } + } + \group_end: + } +\ExplSyntaxOff +\endinput diff --git a/packages/slides.cls b/packages/slides.cls new file mode 100644 index 0000000..d1483cd --- /dev/null +++ b/packages/slides.cls @@ -0,0 +1,328 @@ +\ProvidesClass{packages/slides}[2025/01/27 v1] + +\PassOptionsToPackage{dvipsnames, table}{xcolor} +\PassOptionsToPackage{unicode}{hyperref} +\PassOptionsToPackage{naturalnames}{hyperref} +\LoadClass[aspectratio=169,10pt]{beamer} + +% speaker notes +% open pdf in dual screen using pympress (https://github.com/Cimbali/pympress) +% \setbeameroption{show notes on second screen=right} + +% listings (should be loaded before csquotes) +\RequirePackage{minted} +\setmintedinline{breaklines, breakanywhere, breakanywheresymbolpre={}} + +% language and encoding +\RequirePackage[french]{babel} +\RequirePackage{packages/lab-common} + +% biblatex for references on slides +\RequirePackage[backend=biber]{biblatex} +% clean, short citations in footnotes (cf. https://tex.stackexchange.com/a/587604) +\renewbibmacro{in:}{} +% \AtEveryCitekey{\clearfield{journaltitle}} +\AtEveryCitekey{\clearfield{volume}} +\AtEveryCitekey{\clearfield{number}} +% \AtEveryCitekey{\clearfield{booktitle}} +% \AtEveryCitekey{\clearfield{series}} +\AtEveryCitekey{\clearfield{pages}} +\AtEveryCitekey{\clearfield{month}} +\AtEveryCitekey{\clearlist{publisher}} +\AtEveryCitekey{\clearname{editor}} +\AtEveryCitekey{\clearlist{location}} +\AtEveryCitekey{\clearfield{doi}} +\AtEveryCitekey{\clearfield{isbn}} +\AtEveryCitekey{\clearfield{issn}} +\AtEveryCitekey{\clearfield{eprint}} +\AtEveryCitekey{\clearfield{url}} +\AtEveryCitekey{\clearfield{urlyear}} +\AtEveryCitekey{\clearfield{urlmonth}} +\AtEveryCitekey{\clearfield{urlday}} +% include reference number in citations (cf. https://tex.stackexchange.com/a/176295) +\DeclareCiteCommand{\fullcite} + {\usebibmacro{prenote}} + {{\printtext[labelnumberwidth]{% + \printfield{prefixnumber}% + \printfield{labelnumber}}} % + \usedriver + {\DeclareNameAlias{sortname}{default}} + {\thefield{entrytype}}} + {\multicitedelim} + {\usebibmacro{postnote}} + +% captions +\RequirePackage{caption} +\captionsetup{font=scriptsize,labelfont=scriptsize} +% do not prepend "Figure X:" in captions +\captionsetup[figure]{labelformat=empty} + +% beamer theme +\usetheme{moloch} +\RequirePackage{appendixnumberbeamer} +\RequirePackage{fontspec} +\setsansfont[ + Extension=.otf, + UprightFont=*-Regular, + ItalicFont=*-Italic, + BoldFont=*-SemiBold, + BoldItalicFont=*-SemiBoldItalic +]{IBMPlexSans} +\setmonofont[ + Extension=.otf, + UprightFont=*-Regular, + ItalicFont=*-Italic, + BoldFont=*-SemiBold, + BoldItalicFont=*-SemiBoldItalic +]{IBMPlexMono} +% \setmonofont{Fantasque Sans Mono} +\AtBeginEnvironment{tabular}{% + \addfontfeature{Numbers={Monospaced}} +} +% https://steeven9.github.io/USI-LaTeX/html/packages_hyperref_babel_xcolor3.html +% Section 3.2 of: +% https://mirror.ibcp.fr/pub/CTAN/macros/latex/contrib/beamer-contrib/themes/moloch/moloch.pdf +\definecolor{ubo}{HTML}{5e548e} +\setbeamercolor{progress bar}{fg=ubo} +\setbeamercolor{title separator}{fg=ubo} +\setbeamercolor{frametitle}{bg=ubo} +% \setbeamercolor{progress bar}{fg=BrickRed} +% \setbeamercolor{title separator}{fg=BrickRed} +% footnote font size +\setbeamerfont{footnote}{size=\tiny} +% footer bar: author | short title, section and dots | frame count +% Set the short names with \author[short]{...} and \title[short]{...}. +\setbeamerfont{footline}{size=\fontsize{6}{7.5}\selectfont} +\setbeamercolor{footline}{ + use=normal text, + fg=normal text.fg!80!normal text.bg, + bg=ubo!10!normal text.bg +} +\setbeamercolor{footline frame count}{fg=white, bg=ubo} +% The left inset matches the frame title. The depth centres the capitals. +\newcommand*{\slides@footinset}{7.7pt} +\newcommand*{\slides@footheight}{7.6pt} +\newcommand*{\slides@footdepth}{3.4pt} +\newcommand*{\slides@footmaxdots}{20} +% Count the frames of each section as they are typeset. The totals come from +% the aux file, so the dots are complete from the second compilation onwards. +% The template runs several times per frame, hence the comparison with the +% previous frame. It also runs for plain frames, such as section pages, which +% have no footer and do not count. \part and \appendix restart the section numbers. +\newcount\slides@footframe +\gdef\slides@footlastsection{} +\gdef\slides@footlastframe{} +\newcommand*{\slides@sectionframes}[2]{\global\@namedef{slides@frames@#1}{#2}} +\newcommand*{\slides@footcount}{% + \ifbeamer@plainframe\else\slides@footcountframe\fi +} +\newcommand*{\slides@footcountframe}{% + \edef\slides@footcurrent{\the\c@part-\the\c@section}% + \ifx\slides@footcurrent\slides@footlastsection\else + \global\let\slides@footlastsection\slides@footcurrent + \global\slides@footframe=0\relax + \gdef\slides@footlastframe{}% + \fi + \edef\slides@footcurrent{\the\c@framenumber}% + \ifx\slides@footcurrent\slides@footlastframe\else + \global\let\slides@footlastframe\slides@footcurrent + \global\advance\slides@footframe by 1\relax + \if@filesw + \immediate\write\@auxout{\string\slides@sectionframes + {\slides@footlastsection}{\the\slides@footframe}}% + \fi + \fi +} +% Dots for the frames of the section, with a count when there are too many. +\newcommand*{\slides@footdots}{% + \edef\slides@foottotal{% + \ifcsname slides@frames@\slides@footlastsection\endcsname + \csname slides@frames@\slides@footlastsection\endcsname + \else + \the\slides@footframe + \fi + }% + \ifnum\slides@foottotal>\slides@footmaxdots\relax + \the\slides@footframe/\slides@foottotal + \else + \tikzexternaldisable + \begin{tikzpicture}[baseline=-1.55pt, x=4.4pt] + \mmzUnmemoizable + \foreach \slides@dot in {1,...,\slides@foottotal}{ + \ifnum\slides@dot=\slides@footframe\relax + \fill (\slides@dot,0) circle[radius=1.5pt]; + \else + \draw[line width=.35pt] (\slides@dot,0) circle[radius=1.3pt]; + \fi + } + \end{tikzpicture}% + \tikzexternalenable + \fi +} +% Typeset #2, scaled down if it is wider than #1. +\newsavebox{\slides@footbox} +\newcommand*{\slides@footfit}[2]{% + \sbox{\slides@footbox}{#2}% + \ifdim\wd\slides@footbox>#1\relax + \resizebox{#1}{!}{\usebox{\slides@footbox}}% + \else + \usebox{\slides@footbox}% + \fi +} +% A long author block is too tall for the bar: leave it out and warn once. +\newif\ifslides@footauthorwarned +\newcommand*{\slides@footauthor}{% + \sbox{\slides@footbox}{\insertshortauthor}% + \ifdim\dimexpr\ht\slides@footbox+\dp\slides@footbox\relax>1.5\baselineskip + \ifslides@footauthorwarned\else + \global\slides@footauthorwarnedtrue + \ClassWarningNoLine{slides}{The author is too tall for the footer. + Set a short name with \string\author[short]{...}}% + \fi + \else + \slides@footfit{\dimexpr.19\paperwidth-2\dimexpr\slides@footinset\relax\relax} + {\insertshortauthor}% + \fi +} +\newcommand*{\slides@footmiddle}{% + \insertshorttitle + \ifnum\c@section>0\relax + \enspace\textbullet\enspace\insertsectionhead\enspace\slides@footdots + \fi +} +% One rule for the whole bar: adjacent boxes can leave a seam in PDF viewers. +\setbeamertemplate{footline}{% + \slides@footcount + \usebeamerfont{footline}% + \hbox to\paperwidth{% + \vrule width0pt height\dimexpr\slides@footheight+3pt\relax % clear footnotes + \rlap{% + \usebeamercolor[bg]{footline}% + \vrule width\paperwidth height\slides@footheight depth\slides@footdepth + }% + \usebeamercolor[fg]{footline}% + \hbox to.19\paperwidth{\hskip\slides@footinset\slides@footauthor\hss}% + \hbox to.62\paperwidth{% + \hss\slides@footfit{.62\paperwidth}{\slides@footmiddle}\hss + }% + \hskip.11\paperwidth + \hbox to.08\paperwidth{% + \usebeamercolor[bg]{footline frame count}% + \rlap{\vrule width.08\paperwidth height\slides@footheight depth\slides@footdepth}% + \usebeamercolor[fg]{footline frame count}% + \hss\insertframenumber\,/\,\inserttotalframenumber\hss + }% + }% +} +% denser title bar. The bottom margin starts at the baseline and the top margin +% starts above the capitals, so the bottom one is larger to centre the text. +\setbeamerfont{frametitle}{size=\fontsize{11}{13}\selectfont} +\molochset{ + frametitle margin top=5.5pt, + frametitle margin bottom=7pt +} +% solid background for blocks +\molochset{block=fill} +% remove section frames +% \molochset{sectionpage=none} +% enable subsection frames +\molochset{subsectionpage=progressbar} +% table of contents +\setbeamertemplate{section in toc}[sections numbered] +\makeatletter +\patchcmd{\beamer@sectionintoc}{\vskip1.5em}{\vskip0.3em}{} + {\ClassWarning{slides}{Could not tighten section spacing in the table of contents}} +\makeatother +% smaller first-level bullet points +\setbeamertemplate{itemize item}{\textbullet} +% smaller bibliography entries +\renewcommand*{\bibfont}{\scriptsize} + +% figures uncover animation (cf. https://tex.stackexchange.com/a/354033/95423) +\setbeamercovered{transparent} +\newcommand<>{\uncovergraphics}[2][{}]{ + \begin{tikzpicture} + \node[anchor=south west,inner sep=0] (B) at (4,0) + {\includegraphics[#1]{#2}}; + \alt#3{}{% + \fill [draw=none, fill=bg, fill opacity=0.9] (B.north west) -- (B.north east) -- (B.south east) -- (B.south west) -- (B.north west) -- cycle; + } + \end{tikzpicture} +} + +% fonts and symbols +\RequirePackage{emoji} +% custom font size for a slide (cf. https://tex.stackexchange.com/a/401409) +\newcommand{\customframefont}[1]{ + \setbeamertemplate{itemize/enumerate body begin}{#1} + \setbeamertemplate{itemize/enumerate subbody begin}{#1} +} +\NewDocumentEnvironment{framefont}{m +b}{ + \customframefont{#1} % for itemize/enumerate + {#1 % For the text outside itemize/enumerate + #2 + } + \customframefont{\normalsize} +}{} +% tikz +\usetikzlibrary{arrows.meta} +% math +\RequirePackage{amsmath,amssymb} +% resizebox +\RequirePackage{graphicx} +\RequirePackage{packages/slides-partners} +\RequirePackage{subcaption} +% tables +\RequirePackage{array} +\RequirePackage{tabularx} +\RequirePackage{booktabs} +% avoid spacing between rules and row background +\setlength{\abovetopsep}{0pt} +\setlength{\belowrulesep}{0pt} +\setlength{\aboverulesep}{0pt} +\setlength{\belowbottomsep}{0pt} +% vertical row padding +\renewcommand{\arraystretch}{1.5} % scales vertical row spacing +% vertical centering of text in all tabularx columns +\renewcommand\tabularxcolumn[1]{m{#1}} +% alternate row color +\definecolor{rowgray}{gray}{0.94} +% links +\RequirePackage{hyperref} +\hypersetup{ + colorlinks, + anchorcolor=ubo, + citecolor=ubo, + linkcolor=, + urlcolor=ubo +} + +% redefine title page +% https://tex.stackexchange.com/a/396409 +% Section 6.2.3 of: +% https://ctan.math.illinois.edu/macros/latex/contrib/beamer-contrib/themes/moloch/moloch.pdf +\makeatletter +\setbeamertemplate{title page}{ + % Use the theme's margins rather than a full-paper-height box, which placed + % the footer almost on the page edge. Stretch only the space above the footer. + % If the content is too tall, shrink the top space so the footer keeps its + % bottom margin and the title moves up instead. + \begin{minipage}[t][\dimexpr\paperheight-2\beamer@leftmargin\relax][s]{\textwidth} + \vspace*{\dimexpr .04\paperheight\relax minus 1fill} + \ifx\inserttitle\@empty\else\usebeamertemplate*{title}\fi + \ifx\insertsubtitle\@empty\else\usebeamertemplate*{subtitle}\fi + \vspace{.2cm} + \ifx\insertdate\@empty\else\usebeamertemplate*{date}\fi + \usebeamertemplate*{title separator} + \ifx\beamer@shortauthor\@empty\else\usebeamertemplate*{author}\fi + \vfill + \begin{columns}[b,onlytextwidth] + \column{0.52\linewidth} + \ifx\insertinstitute\@empty\else\usebeamertemplate*{institute}\fi + \column{0.44\linewidth} + \insertpartnerlogos + \end{columns} + \vspace*{0pt} + \end{minipage} +} +\makeatother diff --git a/slides.cls b/slides.cls deleted file mode 100644 index 362b5bb..0000000 --- a/slides.cls +++ /dev/null @@ -1,232 +0,0 @@ -\ProvidesClass{slides}[27/01/2025 v1] - -\PassOptionsToPackage{dvipsnames, table}{xcolor} -\PassOptionsToPackage{unicode}{hyperref} -\PassOptionsToPackage{naturalnames}{hyperref} -\LoadClass[aspectratio=169,10pt]{beamer} - -% speaker notes -% open pdf in dual screen using pympress (https://github.com/Cimbali/pympress) -% \setbeameroption{show notes on second screen=right} - -% listings (should be loaded before csquotes) -\RequirePackage{minted} -\setmintedinline{ - breaklines, - breakanywhere, - breakanywheresymbolpre={} -} - -% language and encoding -\RequirePackage[french]{babel} -\RequirePackage[T1]{fontenc} -\RequirePackage[autostyle]{csquotes} -\MakeOuterQuote{"} - -% biblatex for references on slides -\RequirePackage[backend=biber]{biblatex} -% clean, short citations in footnotes (cf. https://tex.stackexchange.com/a/587604) -\renewbibmacro{in:}{} -% \AtEveryCitekey{\clearfield{journaltitle}} -\AtEveryCitekey{\clearfield{volume}} -\AtEveryCitekey{\clearfield{number}} -% \AtEveryCitekey{\clearfield{booktitle}} -% \AtEveryCitekey{\clearfield{series}} -\AtEveryCitekey{\clearfield{pages}} -\AtEveryCitekey{\clearfield{month}} -\AtEveryCitekey{\clearlist{publisher}} -\AtEveryCitekey{\clearname{editor}} -\AtEveryCitekey{\clearlist{location}} -\AtEveryCitekey{\clearfield{doi}} -\AtEveryCitekey{\clearfield{isbn}} -\AtEveryCitekey{\clearfield{issn}} -\AtEveryCitekey{\clearfield{eprint}} -\AtEveryCitekey{\clearfield{url}} -\AtEveryCitekey{\clearfield{urlyear}} -\AtEveryCitekey{\clearfield{urlmonth}} -\AtEveryCitekey{\clearfield{urlday}} -% include reference number in citations (cf. https://tex.stackexchange.com/a/176295) -\DeclareCiteCommand{\fullcite} - {\usebibmacro{prenote}} - {{\printtext[labelnumberwidth]{% - \printfield{prefixnumber}% - \printfield{labelnumber}}} % - \usedriver - {\DeclareNameAlias{sortname}{default}} - {\thefield{entrytype}}} - {\multicitedelim} - {\usebibmacro{postnote}} - -% captions -\RequirePackage{caption} -\captionsetup{font=scriptsize,labelfont=scriptsize} -% do not prepend "Figure X:" in captions -\captionsetup[figure]{labelformat=empty} - -% beamer theme -\usetheme{moloch} -\RequirePackage{appendixnumberbeamer} -\RequirePackage{fontspec} -\setsansfont[ - ItalicFont={Fira Sans Light Italic}, - BoldFont={Fira Sans}, - BoldItalicFont={Fira Sans Italic} -]{Fira Sans Light} -\setmonofont[BoldFont={Fira Mono Medium}]{Fira Mono} -% \setmonofont{Fantasque Sans Mono} -\AtBeginEnvironment{tabular}{% - \addfontfeature{Numbers={Monospaced}} -} -% https://steeven9.github.io/USI-LaTeX/html/packages_hyperref_babel_xcolor3.html -% Section 3.2 of: -% https://mirror.ibcp.fr/pub/CTAN/macros/latex/contrib/beamer-contrib/themes/moloch/moloch.pdf -\definecolor{ubo}{HTML}{5e548e} -\definecolor{rowgray}{gray}{0.94} -\setbeamercolor{progress bar}{fg=ubo} -\setbeamercolor{title separator}{fg=ubo} -\setbeamercolor{frametitle}{bg=ubo} -% \setbeamercolor{progress bar}{fg=BrickRed} -% \setbeamercolor{title separator}{fg=BrickRed} -% footnote font size -\setbeamerfont{footnote}{size=\tiny} -% frame numbering font size -\setbeamerfont{footline}{size=\footnotesize} -% solid background for blocks -\molochset{block=fill} -% remove section frames -% \molochset{sectionpage=none} -% enable subsection frames -\molochset{subsectionpage=progressbar} -% table of contents -\setbeamertemplate{section in toc}[sections numbered] -\makeatletter -\patchcmd{\beamer@sectionintoc}{\vskip1.5em}{\vskip0.3em}{}{} -\patchcmd{\beamer@subsectionintoc}{\vskip0.75em}{\vskip0.15em}{}{} -\makeatother -% smaller first-level bullet points -\setbeamertemplate{itemize item}{\textbullet} -% smaller bibliography entries -\renewcommand*{\bibfont}{\scriptsize} - -% figures uncover animation (cf. https://tex.stackexchange.com/a/354033/95423) -\setbeamercovered{transparent} -\newcommand<>{\uncovergraphics}[2][{}]{ - \begin{tikzpicture} - \node[anchor=south west,inner sep=0] (B) at (4,0) - {\includegraphics[#1]{#2}}; - \alt#3{}{% - \fill [draw=none, fill=palette primary.fg, fill opacity=0.9] (B.north west) -- (B.north east) -- (B.south east) -- (B.south west) -- (B.north west) -- cycle; - } - \end{tikzpicture} -} - -% tikz -\usetikzlibrary{arrows.meta} -% fonts and symbols -\RequirePackage{textcomp} -\RequirePackage{emoji} -% circles -\RequirePackage{circledsteps} -\pgfkeys{/csteps/inner color=white} -\pgfkeys{/csteps/fill color=black} -% markers -\RequirePackage{pifont} -\newcommand{\cmark}{{\color{YellowGreen}\ding{51}}} -\newcommand{\xmark}{{\color{BrickRed}\ding{55}}} -\newcommand{\imark}{{\color{Orange}\ding{109}}} -% pills -\RequirePackage{xparse} -\NewDocumentCommand{\DONE}{g}{% - \IfNoValueTF{#1}{% - \CircledParamOpts{inner color=black, outer color=LimeGreen, fill color=LimeGreen} - {1}{\textbf{DONE}}% - }{% - \CircledParamOpts{inner color=black, outer color=LimeGreen, fill color=LimeGreen} - {1}{\textbf{DONE --} #1}% - }% -} -\NewDocumentCommand{\TODO}{g}{% - \IfNoValueTF{#1}{% - \CircledParamOpts{inner color=black, outer color=Goldenrod, fill color=Goldenrod} - {1}{\textbf{TODO}}% - }{% - \CircledParamOpts{inner color=black, outer color=Goldenrod, fill color=Goldenrod} - {1}{\textbf{TODO --} #1}% - }% -} -\NewDocumentCommand{\FIXME}{g}{% - \IfNoValueTF{#1}{% - \CircledParamOpts{inner color=white, outer color=Red, fill color=Red} - {1}{\textbf{FIXME}}% - }{% - \CircledParamOpts{inner color=white, outer color=Red, fill color=Red} - {1}{\textbf{FIXME --} #1}% - }% -} -% custom font size for a slide (cf. https://tex.stackexchange.com/a/401409) -\RequirePackage{environ} -\newcommand{\customframefont}[1]{ - \setbeamertemplate{itemize/enumerate body begin}{#1} - \setbeamertemplate{itemize/enumerate subbody begin}{#1} -} -\NewEnviron{framefont}[1]{ - \customframefont{#1} % for itemize/enumerate - {#1 % For the text outside itemize/enumerate - \BODY - } - \customframefont{\normalsize} -} -% math -\RequirePackage{amsmath,amssymb,amsfonts} -% resizebox -\RequirePackage{graphicx} -\RequirePackage{subcaption} -% tables -\RequirePackage{array} -\RequirePackage{tabularx} -\RequirePackage{booktabs} -% various tabular columns with text wrapping -\newcolumntype{F}{>{\arraybackslash}m{\linewidth}} -\newcolumntype{L}[1]{>{\raggedright\arraybackslash}m{#1}} -\newcolumntype{C}[1]{>{\centering\arraybackslash}m{#1}} -\newcolumntype{R}[1]{>{\raggedleft\arraybackslash}m{#1}} -% avoid spacing between rules and row background -\setlength{\abovetopsep}{0pt} -\setlength{\belowrulesep}{0pt} -\setlength{\aboverulesep}{0pt} -\setlength{\belowbottomsep}{0pt} -% vertical row padding -\renewcommand{\arraystretch}{1.5} % scales vertical row spacing -% links -\RequirePackage{hyperref} - -% redefine title page -% https://tex.stackexchange.com/a/396409 -% Section 6.2.3 of: -% https://ctan.math.illinois.edu/macros/latex/contrib/beamer-contrib/themes/moloch/moloch.pdf -\makeatletter -\setbeamertemplate{title page}{ - \begin{minipage}[b][\paperheight]{\textwidth} - % \vfill% - \ifx\inserttitle\@empty\else\usebeamertemplate*{title}\fi - \ifx\insertsubtitle\@empty\else\usebeamertemplate*{subtitle}\fi - \vspace{.2cm} - \ifx\insertdate\@empty\else\usebeamertemplate*{date}\fi - \usebeamertemplate*{title separator} - \vspace{-.2cm} - \begin{columns}[] - \column{0.4\linewidth} - \ifx\beamer@shortauthor\@empty\else\usebeamertemplate*{author}\fi - \column{0.4\linewidth} - \end{columns} - \begin{columns}[b] - \column{0.4\linewidth} - \ifx\insertinstitute\@empty\else\usebeamertemplate*{institute}\fi - \column{0.5\linewidth} - \vspace{-2cm} - \ifx\inserttitlegraphic\@empty\else\inserttitlegraphic\fi - \end{columns} - \vspace*{.2cm} - \end{minipage} -} -\makeatother diff --git a/slides.pdf b/slides.pdf index eb58f4d..8c498ea 100644 Binary files a/slides.pdf and b/slides.pdf differ diff --git a/slides.tex b/slides.tex index 8d043de..feb37b2 100644 --- a/slides.tex +++ b/slides.tex @@ -1,21 +1,19 @@ -\documentclass{slides} +\documentclass{packages/slides} \addbibresource{slides.bib} \title{Objets connectés et robotique} \subtitle{L3 IFA, S5} \date{Octobre 2026} -\titlegraphic{\flushright\includegraphics[height=1.3cm]{img/logos.png}\vspace{.5cm}} +% \titlegraphic{\flushright\includegraphics[height=1.3cm]{img/logos.png}\vspace{.5cm}} +\partner{labsticc} +\partner{ubo} -\author{ +\author[Vincent Lannurien]{ \texorpdfstring{ - \begin{table}[] - \begin{flushleft} - \begin{tabular}{ll} - & Vincent Lannurien~\inst{1} \\ - & \href{mailto:vincent.lannurien@univ-brest.fr}{\texttt{vincent.lannurien@univ-brest.fr}} - \end{tabular} - \end{flushleft} - \end{table} + \begin{tabular}{ll} + & Vincent Lannurien~\inst{1} \\ + & \href{mailto:vincent.lannurien@univ-brest.fr}{\texttt{vincent.lannurien@univ-brest.fr}} + \end{tabular} } { Vincent Lannurien @@ -24,17 +22,11 @@ \institute{ \texorpdfstring{ - \begin{table}[] - \centering - \begin{flushleft} - \begin{tabular}{F} - \inst{1}~Lab-STICC, CNRS UMR 6285, Université de Bretagne Occidentale, Brest - \end{tabular} - \end{flushleft} - \end{table} + \raggedright + \inst{1}~Lab-STICC, CNRS, UMR 6285, Université de Bretagne Occidentale, Brest } { - Lab-STICC, CNRS UMR 6285, Université de Bretagne Occidentale, Brest + Lab-STICC, CNRS, UMR 6285, Université de Bretagne Occidentale, Brest } } @@ -45,379 +37,379 @@ \section{Introduction} \begin{frame}{Quelques systèmes embarqués...} - \begin{figure} - \begin{subfigure}{.3\textwidth} - \centering - \includegraphics[width=\linewidth]{img/exemples/Mars_Climate_Orbiter_2.jpg} - \end{subfigure} - \begin{subfigure}{.2\textwidth} - \centering - \includegraphics[width=\linewidth]{img/exemples/Ariane_5_V88_pillars.jpg} - \end{subfigure} - \begin{subfigure}{.35\textwidth} - \centering - \includegraphics[width=\linewidth]{img/exemples/Patriot20missile202520Aug202016.jpg} - \end{subfigure} - \end{figure} - \begin{figure} - \begin{subfigure}{.18\textwidth} - \centering - \includegraphics[width=\linewidth]{img/exemples/therac-25.jpg} - \end{subfigure} - \begin{subfigure}{.3\textwidth} - \centering - \includegraphics[width=\linewidth]{img/exemples/uber-arizona.jpg} - \end{subfigure} - \begin{subfigure}{.36\textwidth} - \centering - \includegraphics[width=\linewidth]{img/exemples/titan-submersible.jpg} - \end{subfigure} - \end{figure} + \begin{figure} + \begin{subfigure}{.3\textwidth} + \centering + \includegraphics[width=\linewidth]{img/exemples/Mars_Climate_Orbiter_2.jpg} + \end{subfigure} + \begin{subfigure}{.2\textwidth} + \centering + \includegraphics[width=\linewidth]{img/exemples/Ariane_5_V88_pillars.jpg} + \end{subfigure} + \begin{subfigure}{.35\textwidth} + \centering + \includegraphics[width=\linewidth]{img/exemples/Patriot20missile202520Aug202016.jpg} + \end{subfigure} + \end{figure} + \begin{figure} + \begin{subfigure}{.18\textwidth} + \centering + \includegraphics[width=\linewidth]{img/exemples/therac-25.jpg} + \end{subfigure} + \begin{subfigure}{.3\textwidth} + \centering + \includegraphics[width=\linewidth]{img/exemples/uber-arizona.jpg} + \end{subfigure} + \begin{subfigure}{.36\textwidth} + \centering + \includegraphics[width=\linewidth]{img/exemples/titan-submersible.jpg} + \end{subfigure} + \end{figure} \end{frame} \begin{frame}{... devenus tristement célèbres} - \begin{itemize} - \item \url{https://en.wikipedia.org/wiki/Mars_Climate_Orbiter} - \begin{itemize} - \item problème d'unités (système métrique vs système impérial) - \end{itemize} - \item \url{https://en.wikipedia.org/wiki/Ariane_flight_V88} - \begin{itemize} - \item erreur de conversion (\textit{overflow}) - \end{itemize} - \item \url{https://en.wikipedia.org/wiki/14th_Quartermaster_Detachment} - \begin{itemize} - \item bug d'arrondi (\textit{overflow}) - \end{itemize} - \item \url{https://en.wikipedia.org/wiki/Therac-25} - \begin{itemize} - \item erreur de programmation concurrente (\textit{race condition}) - \end{itemize} - \item \url{https://en.wikipedia.org/wiki/Death_of_Elaine_Herzberg} - \begin{itemize} - \item détection d'obstacle inopérante - \end{itemize} - \item \url{https://en.wikipedia.org/wiki/Titan_submersible_implosion} - \begin{itemize} - \item certifications de sécurité insuffisantes - \end{itemize} - \end{itemize} + \begin{itemize} + \item \url{https://en.wikipedia.org/wiki/Mars_Climate_Orbiter} + \begin{itemize} + \item problème d'unités (système métrique vs système impérial) + \end{itemize} + \item \url{https://en.wikipedia.org/wiki/Ariane_flight_V88} + \begin{itemize} + \item erreur de conversion (\textit{overflow}) + \end{itemize} + \item \url{https://en.wikipedia.org/wiki/14th_Quartermaster_Detachment} + \begin{itemize} + \item bug d'arrondi (\textit{overflow}) + \end{itemize} + \item \url{https://en.wikipedia.org/wiki/Therac-25} + \begin{itemize} + \item erreur de programmation concurrente (\textit{race condition}) + \end{itemize} + \item \url{https://en.wikipedia.org/wiki/Death_of_Elaine_Herzberg} + \begin{itemize} + \item détection d'obstacle inopérante + \end{itemize} + \item \url{https://en.wikipedia.org/wiki/Titan_submersible_implosion} + \begin{itemize} + \item certifications de sécurité insuffisantes + \end{itemize} + \end{itemize} \end{frame} \begin{frame}{Commençons par un test...} - \begin{itemize} - \item \textit{Trolley problem} (\url{https://en.wikipedia.org/wiki/Trolley_problem}) : le dilemme du tramway - \end{itemize} + \begin{itemize} + \item \textit{Trolley problem} (\url{https://en.wikipedia.org/wiki/Trolley_problem}) : le dilemme du tramway + \end{itemize} + \begin{center} + \includegraphics[width=0.5\linewidth]{img/dilemma.png} + \end{center} + + \begin{alertblock}{\centering \emoji{thinking}} \begin{center} - \includegraphics[width=0.5\linewidth]{img/dilemma.png} + Que feriez-vous ? + $\rightarrow$ \url{https://www.moralmachine.net/hl/fr} \end{center} - - \begin{alertblock}{\centering \emoji{thinking}} - \begin{center} - Que feriez-vous ? - $\rightarrow$ \url{https://www.moralmachine.net/hl/fr} - \end{center} - \end{alertblock} + \end{alertblock} \end{frame} \begin{framefont}{\small} - \begin{frame}[t]{Plan du cours} - \begin{columns} - \column{0.5\textwidth} - \tableofcontents%[hideallsubsections] + \begin{frame}[t]{Plan du cours} + \begin{columns} + \column{0.5\textwidth} + \tableofcontents%[hideallsubsections] - \column{0.5\textwidth} - \begin{center} - \includegraphics[width=.7\columnwidth]{img/rubo-1.png} - \end{center} - \end{columns} - \end{frame} + \column{0.5\textwidth} + \begin{center} + \includegraphics[width=.7\columnwidth]{img/rubo-1.png} + \end{center} + \end{columns} + \end{frame} \end{framefont} \section{Organisation de l'UE} \begin{frame}{Organisation de l'UE -- Contenu} - \begin{itemize} - \item Objectifs : - \begin{itemize} - \item Savoir concevoir des systèmes cyberphysiques simples, autonomes - \item Comprendre les compromis entre performance (latence, débit) et consommation (énergie, mémoire) - \end{itemize} - \item Méthode : - \begin{itemize} - \item Le plus de \textbf{manipulations} possible ! - \item Dimension \textbf{matérielle} (un peu d'électronique, un peu de mécanique) - \item Dimension \textbf{logicielle} (de l'informatique !) - \end{itemize} - \end{itemize} + \begin{itemize} + \item Objectifs : + \begin{itemize} + \item Savoir concevoir des systèmes cyberphysiques simples, autonomes + \item Comprendre les compromis entre performance (latence, débit) et consommation (énergie, mémoire) + \end{itemize} + \item Méthode : + \begin{itemize} + \item Le plus de \textbf{manipulations} possible ! + \item Dimension \textbf{matérielle} (un peu d'électronique, un peu de mécanique) + \item Dimension \textbf{logicielle} (de l'informatique !) + \end{itemize} + \end{itemize} \end{frame} \begin{frame}{Organisation de l'UE -- Logistique} - \begin{itemize} - \item Volume horaire : - \begin{itemize} - \item CM : 8h - \item TP : 14h - \end{itemize} - \item Travail en groupes : - \begin{itemize} - \item Un robot par personne - \item Binômes possibles dans les groupes de TP - \end{itemize} - \item Examen : - \begin{itemize} - \item Démo \textbf{individuelle} lors des TP - \item Rendu de projet sur \href{https://moodlesciences.univ-brest.fr/moodle/course/view.php?id=867}{Moodle} - \end{itemize} - \item Intervenants : - \begin{itemize} - \item Vincent Lannurien -- \href{mailto:vincent.lannurien@univ-brest.fr}{\texttt{vincent.lannurien@univ-brest.fr}} - \item Kilian Le Gall -- \href{mailto:kilian.legall@univ-brest.fr}{\texttt{kilian.legall@univ-brest.fr}} - \end{itemize} - \end{itemize} + \begin{itemize} + \item Volume horaire : + \begin{itemize} + \item CM : 8h + \item TP : 14h + \end{itemize} + \item Travail en groupes : + \begin{itemize} + \item Un robot par personne + \item Binômes possibles dans les groupes de TP + \end{itemize} + \item Examen : + \begin{itemize} + \item Démo \textbf{individuelle} lors des TP + \item Rendu de projet sur \href{https://moodlesciences.univ-brest.fr/moodle/course/view.php?id=867}{Moodle} + \end{itemize} + \item Intervenants : + \begin{itemize} + \item Vincent Lannurien -- \href{mailto:vincent.lannurien@univ-brest.fr}{\texttt{vincent.lannurien@univ-brest.fr}} + \item Kilian Le Gall -- \href{mailto:kilian.legall@univ-brest.fr}{\texttt{kilian.legall@univ-brest.fr}} + \end{itemize} + \end{itemize} \end{frame} \section{Projet à réaliser} \begin{frame}{Portée du projet} - \textbf{Objectifs :} + \textbf{Objectifs :} - \begin{itemize} - \item Prise en main de l'environnement de développement - \item Implantation d'algorithmes simples sur le robot - \item Étude des compromis performances/ressources - \end{itemize} + \begin{itemize} + \item Prise en main de l'environnement de développement + \item Implantation d'algorithmes simples sur le robot + \item Étude des compromis performances/ressources + \end{itemize} - \vspace{24px} - \pause + \vspace{24px} + \pause - Tout ce que l'on ne va pas faire : + Tout ce que l'on ne va pas faire : - \begin{itemize} - \item Électronique : montages complexes, conception de carte... - \item Traitement du signal : radio, interférences... - \item Sécurité : authentification, détection d'intrusion... - \end{itemize} + \begin{itemize} + \item Électronique : montages complexes, conception de carte... + \item Traitement du signal : radio, interférences... + \item Sécurité : authentification, détection d'intrusion... + \end{itemize} \end{frame} \begin{frame}{Étapes du projet} - \begin{itemize} - \item Commande : Fonctionnement de base d'un robot - \begin{itemize} - \item Envoi de messages : avancer, reculer, tourner, etc. - \item Communications : filaire (série), sans-fil (radio) - \item Interface web de commande : Node.js, JavaScript - \end{itemize} - \item Environnement : capteurs et actionneurs - \begin{itemize} - \item Utilisation d'un capteur de distance - \item Fonctionnement des moteurs - \end{itemize} - \item Contrôle : Programmation de missions simples - \begin{itemize} - \item Comportement autonome : - \begin{itemize} - \item Avancer jusqu'à trouver un obstacle - \item Avancer jusqu'à trouver une ouverture - \item Faire un quart de tour - \item Contourner un objet - \end{itemize} - \end{itemize} - \item En option : - \begin{itemize} - \item Plus de capteurs (second capteur de distance, caméra monochrome...) - \item Plus de cartes (calcul déporté, communication entre robots...) - \end{itemize} - \end{itemize} + \begin{itemize} + \item Commande : Fonctionnement de base d'un robot + \begin{itemize} + \item Envoi de messages : avancer, reculer, tourner, etc. + \item Communications : filaire (série), sans-fil (radio) + \item Interface web de commande : Node.js, JavaScript + \end{itemize} + \item Environnement : capteurs et actionneurs + \begin{itemize} + \item Utilisation d'un capteur de distance + \item Fonctionnement des moteurs + \end{itemize} + \item Contrôle : Programmation de missions simples + \begin{itemize} + \item Comportement autonome : + \begin{itemize} + \item Avancer jusqu'à trouver un obstacle + \item Avancer jusqu'à trouver une ouverture + \item Faire un quart de tour + \item Contourner un objet + \end{itemize} + \end{itemize} + \item En option : + \begin{itemize} + \item Plus de capteurs (second capteur de distance, caméra monochrome...) + \item Plus de cartes (calcul déporté, communication entre robots...) + \end{itemize} + \end{itemize} \end{frame} \section{Contexte} \begin{frame}{Histoire de la robotique -- Automates [\href{https://educ.arte.tv/program/faire-l-histoire-le-canard-de-vaucanson-l-automate-disparu}{réf.}]} - \begin{figure} - \centering - \includegraphics[width=0.5\linewidth]{img/vaucanson-duck.png} - \caption{Canard digérant (Jacques de Vaucanson, 1739)} - \end{figure} + \begin{figure} + \centering + \includegraphics[width=0.5\linewidth]{img/vaucanson-duck.png} + \caption{Canard digérant (Jacques de Vaucanson, 1739)} + \end{figure} \end{frame} \begin{frame}{Histoire de la robotique -- Automates} - \begin{figure} - \centering - \includegraphics[width=0.3\linewidth]{img/serinette.png} - \caption{Serinette de Jacotel (famille Husson-Jacotel, début du XIX\textsuperscript{e})} - \end{figure} + \begin{figure} + \centering + \includegraphics[width=0.3\linewidth]{img/serinette.png} + \caption{Serinette de Jacotel (famille Husson-Jacotel, début du XIX\textsuperscript{e})} + \end{figure} \end{frame} \begin{frame}{Histoire de la robotique -- Automates [\href{https://ingeniumcanada.org/fr/le-reseau/articles/les-chiens-electriques-revent-ils-de-gateries-a-haute-tension-henry-joseph}{réf.}]} - \begin{figure} - \centering - \includegraphics[width=0.7\linewidth]{img/hammond-electric-dog.png} - \caption{Chien électrique (John Hammond et Benjamin Miessner, 1915)} - \end{figure} + \begin{figure} + \centering + \includegraphics[width=0.7\linewidth]{img/hammond-electric-dog.png} + \caption{Chien électrique (John Hammond et Benjamin Miessner, 1915)} + \end{figure} \end{frame} \begin{frame}{Histoire de la robotique -- Automates} + \begin{figure} + \centering + \includegraphics[width=0.8\linewidth]{img/defenseur-du-temps-1.png} + \caption{\textit{Le Défenseur du Temps} (Jacques Monestier, 1979)} + \end{figure} +\end{frame} + +\begin{frame}{Histoire de la robotique -- Robots} + \begin{figure} + \centering + \includegraphics[width=0.6\linewidth]{img/goliath.png} + \caption{Goliath, mine filoguidée activable à distance (Normandie, 1944)} + \end{figure} +\end{frame} + +\begin{frame}{Histoire de la robotique -- Robots} + \begin{columns} + \column{0.5\linewidth} + \begin{itemize} + \item Accident de Tchernobyl (1986) : + \begin{itemize} + \item \textbf{Liquidateurs} : personnel civil et militaire intervenu immédiatement sur les lieux de la catastrophe nucléaire + \item 600 000 personnes ont reçu des doses équivalentes à Hiroshima ou Nagazaki + \begin{itemize} + \item Reconnaissance, détection de la radioactivité + \item Démantèlement des débris du réacteur + \item Documentation (photographie) + \item Échantillonnage des matériaux + \item Enfouissement des déchets + \end{itemize} + \end{itemize} + \end{itemize} + + \column{0.5\linewidth} \begin{figure} - \centering - \includegraphics[width=0.8\linewidth]{img/defenseur-du-temps-1.png} - \caption{\textit{Le Défenseur du Temps} (Jacques Monestier, 1979)} + \centering + \includegraphics[width=0.8\linewidth]{img/stele-liquidateurs-kharkiv.png} + \caption{Stèle à la mémoire des liquidateurs (Kharkiv, Ukraine)} \end{figure} + \end{columns} \end{frame} \begin{frame}{Histoire de la robotique -- Robots} + \begin{columns} + \column{0.4\linewidth} + \begin{itemize} + \item Développement de robots télécommandés pour l'inspection et le nettoyage \textbf{à distance} + \begin{itemize} + \item \textbf{Télédétection} : caméra, capteurs de radiation + \item \textbf{Télémétrie} : transmission des données vers un poste de contrôle + \item \textbf{Télémanipulation} : bras robotique pour manipuler les débris + \end{itemize} + \end{itemize} + + \column{0.6\linewidth} \begin{figure} - \centering - \includegraphics[width=0.6\linewidth]{img/goliath.png} - \caption{Goliath, mine filoguidée activable à distance (Normandie, 1944)} + \centering + \includegraphics[width=\linewidth]{img/robot-joker.png} + \caption{Robot \textbf{Joker} (1986)} \end{figure} + \end{columns} \end{frame} \begin{frame}{Histoire de la robotique -- Robots} - \begin{columns} - \column{0.5\linewidth} - \begin{itemize} - \item Accident de Tchernobyl (1986) : - \begin{itemize} - \item \textbf{Liquidateurs} : personnel civil et militaire intervenu immédiatement sur les lieux de la catastrophe nucléaire - \item 600 000 personnes ont reçu des doses équivalentes à Hiroshima ou Nagazaki - \begin{itemize} - \item Reconnaissance, détection de la radioactivité - \item Démantèlement des débris du réacteur - \item Documentation (photographie) - \item Échantillonnage des matériaux - \item Enfouissement des déchets - \end{itemize} - \end{itemize} - \end{itemize} - - \column{0.5\linewidth} - \begin{figure} - \centering - \includegraphics[width=0.8\linewidth]{img/stele-liquidateurs-kharkiv.png} - \caption{Stèle à la mémoire des liquidateurs (Kharkiv, Ukraine)} - \end{figure} - \end{columns} -\end{frame} - -\begin{frame}{Histoire de la robotique -- Robots} - \begin{columns} - \column{0.4\linewidth} - \begin{itemize} - \item Développement de robots télécommandés pour l'inspection et le nettoyage \textbf{à distance} - \begin{itemize} - \item \textbf{Télédétection} : caméra, capteurs de radiation - \item \textbf{Télémétrie} : transmission des données vers un poste de contrôle - \item \textbf{Télémanipulation} : bras robotique pour manipuler les débris - \end{itemize} - \end{itemize} - - \column{0.6\linewidth} - \begin{figure} - \centering - \includegraphics[width=\linewidth]{img/robot-joker.png} - \caption{Robot \textbf{Joker} (1986)} - \end{figure} - \end{columns} -\end{frame} - -\begin{frame}{Histoire de la robotique -- Robots} - \begin{figure} - \centering - \includegraphics[width=0.7\linewidth]{img/metro-paris.png} - \caption{Ligne 14 du métro de Paris} - \end{figure} + \begin{figure} + \centering + \includegraphics[width=0.7\linewidth]{img/metro-paris.png} + \caption{Ligne 14 du métro de Paris} + \end{figure} \end{frame} \begin{frame}{Automates ou robots ?} - \begin{itemize} - \item \textbf{Automate} : - \begin{itemize} - \item répète une séquence fixe de mouvements mécaniques - \item ne s'adapte pas à son environnement - \end{itemize} - \item \textbf{Robot} : - \begin{itemize} - \item possède des capacités de \textit{perception} - \item peut \textit{interagir} avec son environnement - \item peut prendre des décisions \textit{autonomes} - \end{itemize} - \end{itemize} + \begin{itemize} + \item \textbf{Automate} : + \begin{itemize} + \item répète une séquence fixe de mouvements mécaniques + \item ne s'adapte pas à son environnement + \end{itemize} + \item \textbf{Robot} : + \begin{itemize} + \item possède des capacités de \textit{perception} + \item peut \textit{interagir} avec son environnement + \item peut prendre des décisions \textit{autonomes} + \end{itemize} + \end{itemize} \end{frame} \begin{frame}{Définitions -- Systèmes cyberphysiques} - \begin{definition} - \textit{Cyber-Physical Systems (CPS) are integrations of computation with physical processes.}~\footfullcite{leeCyberPhysicalSystems2008} - \end{definition} + \begin{definition} + \textit{Cyber-Physical Systems (CPS) are integrations of computation with physical processes.}~\footfullcite{leeCyberPhysicalSystems2008} + \end{definition} - \begin{itemize} - \item Énergie : \textit{smart grids} - \item Transport : systèmes ferroviaires, aviation civile, automobile autonome... - \item Santé : dispositifs médicaux "connectés" - \item Industrie : usines automatisées, robots industriels - \item Ville "intelligente" - \end{itemize} + \begin{itemize} + \item Énergie : \textit{smart grids} + \item Transport : systèmes ferroviaires, aviation civile, automobile autonome... + \item Santé : dispositifs médicaux "connectés" + \item Industrie : usines automatisées, robots industriels + \item Ville "intelligente" + \end{itemize} \end{frame} \begin{frame}{Définitions -- Systèmes cyberphysiques} - \begin{definition} - \textit{Cyber-Physical Systems (CPS) are integrations of computation with physical processes.}~\footfullcite{leeCyberPhysicalSystems2008} - \end{definition} + \begin{definition} + \textit{Cyber-Physical Systems (CPS) are integrations of computation with physical processes.}~\footfullcite{leeCyberPhysicalSystems2008} + \end{definition} - \begin{center} - \includegraphics[width=0.6\linewidth]{img/cps.png} - \end{center} + \begin{center} + \includegraphics[width=0.6\linewidth]{img/cps.png} + \end{center} - \addtocounter{footnote}{1} - \footnotetext{\fullcite{inderwildiImpactIntelligentCyberphysical2020}} + \addtocounter{footnote}{1} + \footnotetext{\fullcite{inderwildiImpactIntelligentCyberphysical2020}} \end{frame} \begin{frame}{Quelques tendances [\href{https://digital-strategy.ec.europa.eu/fr/policies/next-generation-internet-things}{réf.}]} - \begin{itemize} - \item 41 milliards d'appareils \textit{IoT} déployés en 2025 - \item Intelligence artificielle de plus en plus déployée en périphérie de réseau (Apple Intelligence, Google AI Edge) - \item Défis : interopérabilité, durabilité - \end{itemize} + \begin{itemize} + \item 41 milliards d'appareils \textit{IoT} déployés en 2025 + \item Intelligence artificielle de plus en plus déployée en périphérie de réseau (Apple Intelligence, Google AI Edge) + \item Défis : interopérabilité, durabilité + \end{itemize} - \begin{center} - \includegraphics[width=0.5\linewidth]{img/cloud-edge.png} - \end{center} + \begin{center} + \includegraphics[width=0.5\linewidth]{img/cloud-edge.png} + \end{center} \end{frame} \begin{frame}{Numérique -- Quels impacts ? (2022) [\href{https://infos.ademe.fr/magazine-avril-2022/faits-et-chiffres/numerique-quel-impact-environnemental/}{réf.}]} - \begin{columns} - \column{0.5\linewidth} - Pour chaque Français, le numérique représente : + \begin{columns} + \column{0.5\linewidth} + Pour chaque Français, le numérique représente : - \begin{itemize} - \item \textbf{Consommation électrique} : 10\% - \item \textbf{Empreinte carbone} : 2.5\% - \item \textbf{Déchets} : 299 kg/habitant/an - \item \textbf{Fabrication} : 78\% de l'impact - \item \textbf{Utilisation} : 21\% de l'impact - \end{itemize} + \begin{itemize} + \item \textbf{Consommation électrique} : 10\% + \item \textbf{Empreinte carbone} : 2.5\% + \item \textbf{Déchets} : 299 kg/habitant/an + \item \textbf{Fabrication} : 78\% de l'impact + \item \textbf{Utilisation} : 21\% de l'impact + \end{itemize} - \column{0.5\linewidth} - \includegraphics[width=\columnwidth]{img/ademe-impacts.jpg} - \end{columns} + \column{0.5\linewidth} + \includegraphics[width=\columnwidth]{img/ademe-impacts.jpg} + \end{columns} \end{frame} \begin{frame}{Numérique -- Quels impacts ? (2025) [\href{https://infos.ademe.fr/magazine-janvier-2025/numerique-quel-impact-environnemental-en-2022/}{réf.}]} - \begin{columns} - \column{0.7\linewidth} - \begin{center} - \includegraphics[width=0.4\columnwidth]{img/ademe-impacts-2025.png} - \includegraphics[width=0.4\columnwidth]{img/ademe-impacts-2025-3.png} - \end{center} + \begin{columns} + \column{0.7\linewidth} + \begin{center} + \includegraphics[width=0.4\columnwidth]{img/ademe-impacts-2025.png} + \includegraphics[width=0.4\columnwidth]{img/ademe-impacts-2025-3.png} + \end{center} - \begin{itemize} - \item Hausse de l'impact des \textbf{centres de données} : 46\% de l'empreinte carbone du numérique - \end{itemize} + \begin{itemize} + \item Hausse de l'impact des \textbf{centres de données} : 46\% de l'empreinte carbone du numérique + \end{itemize} - \column{0.3\linewidth} - \includegraphics[width=\columnwidth]{img/ademe-impacts-2025-2.png} - \end{columns} + \column{0.3\linewidth} + \includegraphics[width=\columnwidth]{img/ademe-impacts-2025-2.png} + \end{columns} \end{frame} \section{Informatique embarquée} @@ -425,391 +417,391 @@ \subsection{Microcontrôleurs} \begin{frame}{Microcontrôleurs : Utilisations et limites} - \begin{columns} - \column{0.7\linewidth} - \begin{center} - \includegraphics[width=0.145\columnwidth]{img/coffee-maker.png} - \includegraphics[width=0.22\columnwidth]{img/shutter.png} - \includegraphics[width=0.21\columnwidth]{img/electric-car.png} - \end{center} + \begin{columns} + \column{0.7\linewidth} + \begin{center} + \includegraphics[width=0.145\columnwidth]{img/coffee-maker.png} + \includegraphics[width=0.22\columnwidth]{img/shutter.png} + \includegraphics[width=0.21\columnwidth]{img/electric-car.png} + \end{center} - \begin{itemize} - \item \textbf{Circuit intégré} : calcul (processeur), mémoire (mémoire vive et non-volatile), interfaces d'Entrées/Sorties - \item \textbf{Non-programmable} : son comportement est gravé dans le silicium - \item \textbf{Utilisation} : partout où un processeur généraliste n'est pas nécessaire - \begin{itemize} - \item + : Plus simple à comprendre, à vérifier - \item + : Consommation d'énergie minimale - \item - : Peu flexible - \end{itemize} - \item \textbf{Coût} : en 2018, en moyenne, \$0.03 pour un µc 8-bit, \$1 pour un µc 32-bit $\rightarrow$ ratio $\frac{1}{100}$ par rapport à un PC grand public - \end{itemize} + \begin{itemize} + \item \textbf{Circuit intégré} : calcul (processeur), mémoire (mémoire vive et non-volatile), interfaces d'Entrées/Sorties + \item \textbf{Non-programmable} : son comportement est gravé dans le silicium + \item \textbf{Utilisation} : partout où un processeur généraliste n'est pas nécessaire + \begin{itemize} + \item + : Plus simple à comprendre, à vérifier + \item + : Consommation d'énergie minimale + \item - : Peu flexible + \end{itemize} + \item \textbf{Coût} : en 2018, en moyenne, \$0.03 pour un µc 8-bit, \$1 pour un µc 32-bit $\rightarrow$ ratio $\frac{1}{100}$ par rapport à un PC grand public + \end{itemize} - \column{0.3\linewidth} - \includegraphics[width=\columnwidth]{img/brain.png} - \end{columns} + \column{0.3\linewidth} + \includegraphics[width=\columnwidth]{img/brain.png} + \end{columns} \end{frame} \begin{frame}{Microcontrôleurs : Cartes électroniques} - \begin{itemize} - \item \textbf{Énergie} (VCC, GND, tension d'alimentation) - \item \textbf{Architecture} (horloge, mémoire) - \item \textbf{Signal} et \textbf{interfaces} (GPIO, ADC, PWM) - \item \textbf{Capteurs} (communications série, UART, I²C, SPI) - \item \textbf{Actionneurs} (étage de puissance, moteurs, servomoteurs) - \item \textbf{Mécanique} (moteur + réducteur, roues, châssis) - \end{itemize} + \begin{itemize} + \item \textbf{Énergie} (VCC, GND, tension d'alimentation) + \item \textbf{Architecture} (horloge, mémoire) + \item \textbf{Signal} et \textbf{interfaces} (GPIO, ADC, PWM) + \item \textbf{Capteurs} (communications série, UART, I²C, SPI) + \item \textbf{Actionneurs} (étage de puissance, moteurs, servomoteurs) + \item \textbf{Mécanique} (moteur + réducteur, roues, châssis) + \end{itemize} \end{frame} \begin{frame}{Principes de câblage} - % \FIXME{} exemples... pas pédago là + % \FIXME{} exemples... pas pédago là - \begin{itemize} - \item Tensions, masse et référence commune - \item Différence entre \textbf{tension d'alimentation} et \textbf{tension logique} - \item Transporter l'\textbf{énergie} : une différence de tension provoque la circulation d'un courant lorsque le circuit électrique est fermé (exemple : LED branchée entre $3.3V$ et $GND$) - \item Transporter l'\textbf{information} : la tension n'est pas forcément constante ; le microcontrôleur peut la faire varier pour transmettre un signal (tension proche de $0V$ = niveau logique à 0, tension proche de $3.3V$ = niveau logique à 1) - \end{itemize} + \begin{itemize} + \item Tensions, masse et référence commune + \item Différence entre \textbf{tension d'alimentation} et \textbf{tension logique} + \item Transporter l'\textbf{énergie} : une différence de tension provoque la circulation d'un courant lorsque le circuit électrique est fermé (exemple : LED branchée entre $3.3V$ et $GND$) + \item Transporter l'\textbf{information} : la tension n'est pas forcément constante ; le microcontrôleur peut la faire varier pour transmettre un signal (tension proche de $0V$ = niveau logique à 0, tension proche de $3.3V$ = niveau logique à 1) + \end{itemize} \end{frame} \begin{frame}{Principes de câblage} - % \FIXME{} exemples... pas pédago là + % \FIXME{} exemples... pas pédago là - \begin{itemize} - \item Commander l'allumage d'une LED, le démarrage d'un moteur, lire l'état d'un bouton, envoyer des données sur un bus de communication, etc. - \item \textbf{ADC} (\textit{Analog to Digital Converter}) : mesure la tension et la transforme en valeur numérique utilisable par le programme - \item Tension = différence de potentiel entre deux points - \begin{itemize} - \item $U_{AB} = V_{A} - V_{B}$ - \end{itemize} - \item Il faut donc toujours une \textbf{référence} - \begin{itemize} - \item On choisit un point comme $0V$ : $GND$ - \item $GND$ sert également de chemin de retour au courant du signal - \end{itemize} - \item GPIO à $3.3V$ signifie "GPIO à $3.3V$ au-dessus de $GND$" - \end{itemize} + \begin{itemize} + \item Commander l'allumage d'une LED, le démarrage d'un moteur, lire l'état d'un bouton, envoyer des données sur un bus de communication, etc. + \item \textbf{ADC} (\textit{Analog to Digital Converter}) : mesure la tension et la transforme en valeur numérique utilisable par le programme + \item Tension = différence de potentiel entre deux points + \begin{itemize} + \item $U_{AB} = V_{A} - V_{B}$ + \end{itemize} + \item Il faut donc toujours une \textbf{référence} + \begin{itemize} + \item On choisit un point comme $0V$ : $GND$ + \item $GND$ sert également de chemin de retour au courant du signal + \end{itemize} + \item GPIO à $3.3V$ signifie "GPIO à $3.3V$ au-dessus de $GND$" + \end{itemize} \end{frame} \begin{frame}{Principes de câblage} - % \FIXME{} exemples... pas pédago là + % \FIXME{} exemples... pas pédago là - \begin{itemize} - \item Pull-up et pull-down : résistance de rappel pour forcer un état logique par défaut - \item Exemple : bouton poussoir connecté entre $GND$ et un GPIO configuré en entrée avec pull-up - \begin{itemize} - \item Bouton relâché : GPIO = $3.3V$ (niveau logique à 1) - \item Bouton appuyé : GPIO = $0V$ (niveau logique à 0) - \end{itemize} - \item Nécessaire lorsque le circuit n'est pas fermé (bouton relâché) pour éviter que le GPIO "flotte" et prenne des valeurs aléatoires - \end{itemize} + \begin{itemize} + \item Pull-up et pull-down : résistance de rappel pour forcer un état logique par défaut + \item Exemple : bouton poussoir connecté entre $GND$ et un GPIO configuré en entrée avec pull-up + \begin{itemize} + \item Bouton relâché : GPIO = $3.3V$ (niveau logique à 1) + \item Bouton appuyé : GPIO = $0V$ (niveau logique à 0) + \end{itemize} + \item Nécessaire lorsque le circuit n'est pas fermé (bouton relâché) pour éviter que le GPIO "flotte" et prenne des valeurs aléatoires + \end{itemize} \end{frame} \begin{frame}{Architecture} - \begin{columns} - \column{.5\textwidth} - \begin{figure} - \includegraphics[width=\textwidth]{img/architecture.png} - \end{figure} + \begin{columns} + \column{.5\textwidth} + \begin{figure} + \includegraphics[width=\textwidth]{img/architecture.png} + \end{figure} - \column{.5\textwidth} - \begin{alertblock}{Architecture des ordinateurs} - Le \textit{programme} est stocké en \textbf{flash} ; le \textbf{processeur} en exécute les \textit{instructions} ; l'\textbf{horloge} \textit{cadence} son fonctionnement ; la \textbf{RAM} conserve les \textit{données} nécessaires à l'exécution. - \end{alertblock} + \column{.5\textwidth} + \begin{alertblock}{Architecture des ordinateurs} + Le \textit{programme} est stocké en \textbf{flash} ; le \textbf{processeur} en exécute les \textit{instructions} ; l'\textbf{horloge} \textit{cadence} son fonctionnement ; la \textbf{RAM} conserve les \textit{données} nécessaires à l'exécution. + \end{alertblock} - Quelle différence entre un ordinateur et un microcontrôleur ? - \end{columns} + Quelle différence entre un ordinateur et un microcontrôleur ? + \end{columns} \end{frame} \subsection{Raspberry Pi Pico et écosystème} \begin{frame} - \begin{center} - \includegraphics[width=0.5\textwidth]{img/rubo-1.png} - \end{center} + \begin{center} + \includegraphics[width=0.5\textwidth]{img/rubo-1.png} + \end{center} \end{frame} \begin{frame}{Raspberry Pi Pico WH : caractéristiques (RP2040)} - \begin{columns} - \column{0.4\linewidth} - \begin{alertblock}{Plateforme de \emph{prototypage}} - Permet de reprogrammer le système ! - \end{alertblock} + \begin{columns} + \column{0.4\linewidth} + \begin{alertblock}{Plateforme de \emph{prototypage}} + Permet de reprogrammer le système ! + \end{alertblock} - \begin{itemize} - \item Microcontrôleur RP2040 - \item CPU bicœur Arm Cortex-M0+ @ 133 MHz - \item 264 kB SRAM - \item 2 MB flash - \item Wi-Fi 2.4GHz 802.11n - \item Bluetooth 5.2 - \item 26 broches GPIO - \item 2x UART, 2x SPI, 2x I²C, 16x PWM - \item Tension supportée : $1.8$ à $5.5V$ - \end{itemize} + \begin{itemize} + \item Microcontrôleur RP2040 + \item CPU bicœur Arm Cortex-M0+ @ 133 MHz + \item 264 kB SRAM + \item 2 MB flash + \item Wi-Fi 2.4GHz 802.11n + \item Bluetooth 5.2 + \item 26 broches GPIO + \item 2x UART, 2x SPI, 2x I²C, 16x PWM + \item Tension supportée : $1.8$ à $5.5V$ + \end{itemize} - \column{0.6\linewidth} - \begin{figure} - \centering - \includegraphics[width=\textwidth]{img/raspberry-pi-pico-wh.png} - \end{figure} - \end{columns} + \column{0.6\linewidth} + \begin{figure} + \centering + \includegraphics[width=\textwidth]{img/raspberry-pi-pico-wh.png} + \end{figure} + \end{columns} \end{frame} \begin{frame}{\textit{Shield} générique} - \begin{columns} - \column{0.4\linewidth} - \begin{itemize} - \item Simplifie le câblage des capteurs et actionneurs - \begin{itemize} - \item Redistribue les broches (GPIO, VCC, GND) du Raspberry Pi Pico sur des connecteurs standards à 4 fils : $GND$, $VCC$, $signal_2$, $signal_1$ - \end{itemize} - \item Fournit une masse commune sur les connecteurs (I²C, SPI...) - \item Fournit une tension d'alimentation régulée - \end{itemize} + \begin{columns} + \column{0.4\linewidth} + \begin{itemize} + \item Simplifie le câblage des capteurs et actionneurs + \begin{itemize} + \item Redistribue les broches (GPIO, VCC, GND) du Raspberry Pi Pico sur des connecteurs standards à 4 fils : $GND$, $VCC$, $signal_2$, $signal_1$ + \end{itemize} + \item Fournit une masse commune sur les connecteurs (I²C, SPI...) + \item Fournit une tension d'alimentation régulée + \end{itemize} - \column{0.6\linewidth} - \begin{figure} - \centering - \includegraphics[width=\textwidth]{img/grove-shield.png} - \end{figure} - \end{columns} + \column{0.6\linewidth} + \begin{figure} + \centering + \includegraphics[width=\textwidth]{img/grove-shield.png} + \end{figure} + \end{columns} \end{frame} \begin{frame}{\textit{Breadboard} et abaisseur de tension} - \begin{columns} - \column{0.5\linewidth} - \begin{itemize} - \item \textit{Breadboard} : permet de réaliser des montages électroniques sans soudure - \item Abaisseur de tension : permet d'alimenter le robot en $5V$ à partir d'une source à une tension plus haute - \begin{itemize} - \item \textit{e.g.}, une pile $9V$ - \end{itemize} - \end{itemize} + \begin{columns} + \column{0.5\linewidth} + \begin{itemize} + \item \textit{Breadboard} : permet de réaliser des montages électroniques sans soudure + \item Abaisseur de tension : permet d'alimenter le robot en $5V$ à partir d'une source à une tension plus haute + \begin{itemize} + \item \textit{e.g.}, une pile $9V$ + \end{itemize} + \end{itemize} - \column{0.5\linewidth} - \begin{figure} - \centering - \includegraphics[width=\textwidth]{img/breadboard-power.png} - \end{figure} - \end{columns} + \column{0.5\linewidth} + \begin{figure} + \centering + \includegraphics[width=\textwidth]{img/breadboard-power.png} + \end{figure} + \end{columns} \end{frame} \begin{frame}{Afficheur LCD} - \begin{columns} - \column{0.5\linewidth} - \begin{itemize} - \item Afficheur LCD 16x2 caractères - \item Interface I²C - \item Permet d'afficher des informations sur le robot - \end{itemize} + \begin{columns} + \column{0.5\linewidth} + \begin{itemize} + \item Afficheur LCD 16x2 caractères + \item Interface I²C + \item Permet d'afficher des informations sur le robot + \end{itemize} - \column{0.5\linewidth} - \begin{figure} - \centering - \includegraphics[width=\textwidth]{img/grove-lcd.png} - \end{figure} - \end{columns} + \column{0.5\linewidth} + \begin{figure} + \centering + \includegraphics[width=\textwidth]{img/grove-lcd.png} + \end{figure} + \end{columns} \end{frame} \begin{frame}{\textit{Shield} de commande de moteurs} - \begin{columns} - \column{0.5\linewidth} - \begin{itemize} - \item L298N : 2x "Pont en H" - \item Interface numérique sur quatre broches de signal - \begin{itemize} - \item IN1, IN2 : commande des deux moteurs gauches - \item IN3, IN4 : commande des deux moteurs droits - \end{itemize} - \item Applique une quantité réglable de puissance à une charge - \item Permet de commander deux moteurs à courant continu - \item Permet de faire varier la vitesse et le sens de rotation des moteurs - \end{itemize} + \begin{columns} + \column{0.5\linewidth} + \begin{itemize} + \item L298N : 2x "Pont en H" + \item Interface numérique sur quatre broches de signal + \begin{itemize} + \item IN1, IN2 : commande des deux moteurs gauches + \item IN3, IN4 : commande des deux moteurs droits + \end{itemize} + \item Applique une quantité réglable de puissance à une charge + \item Permet de commander deux moteurs à courant continu + \item Permet de faire varier la vitesse et le sens de rotation des moteurs + \end{itemize} - \column{0.5\linewidth} - \begin{figure} - \centering - \includegraphics[width=\textwidth]{img/joy-it-sbc-motodriver2.png} - \end{figure} - \end{columns} + \column{0.5\linewidth} + \begin{figure} + \centering + \includegraphics[width=\textwidth]{img/joy-it-sbc-motodriver2.png} + \end{figure} + \end{columns} \end{frame} \begin{frame}{Télémètre à ultrasons} - \begin{columns} - \column{0.5\linewidth} - \begin{itemize} - \item Capteur de distance à ultrasons - \item Interface numérique sur une broche - \begin{itemize} - \item 3 fils : \textbf{SIG} (signal numérique bidirectionnel) + VCC + GND - \end{itemize} - \item Permet de mesurer la distance entre le robot et un obstacle - \item Principe : émettre une impulsion sonore et mesurer le temps de retour de l'écho - \begin{itemize} - \item Distance = $\frac{v_{son} \times t_{echo}}{2}$, avec $v_{son} \approx 343 m/s$ à $20°C$ - \end{itemize} - \item Précision : 1 mm, portée : 30 mm à 700 mm - \end{itemize} + \begin{columns} + \column{0.5\linewidth} + \begin{itemize} + \item Capteur de distance à ultrasons + \item Interface numérique sur une broche + \begin{itemize} + \item 3 fils : \textbf{SIG} (signal numérique bidirectionnel) + VCC + GND + \end{itemize} + \item Permet de mesurer la distance entre le robot et un obstacle + \item Principe : émettre une impulsion sonore et mesurer le temps de retour de l'écho + \begin{itemize} + \item Distance = $\frac{v_{son} \times t_{echo}}{2}$, avec $v_{son} \approx 343 m/s$ à $20°C$ + \end{itemize} + \item Précision : 1 mm, portée : 30 mm à 700 mm + \end{itemize} - \column{0.5\linewidth} - \begin{figure} - \centering - \includegraphics[width=\textwidth]{img/grove-ultrasonic.png} - \end{figure} - \end{columns} + \column{0.5\linewidth} + \begin{figure} + \centering + \includegraphics[width=\textwidth]{img/grove-ultrasonic.png} + \end{figure} + \end{columns} \end{frame} \begin{frame}{Télémètre à infrarouges} - \begin{columns} - \column{0.5\linewidth} - \begin{itemize} - \item Capteur de distance à infrarouges - \item Interface I²C - \item Permet de mesurer la distance entre le robot et un obstacle - \item Principe : émettre une impulsion lumineuse et mesurer le temps de retour de l'écho - \begin{itemize} - \item Distance = $\frac{v_{lumiere} \times t_{echo}}{2}$, avec $v_{lumiere} \approx 3\times10^8 m/s$ - \end{itemize} - \item Précision : 1 mm, portée : environ 2500 mm - \end{itemize} + \begin{columns} + \column{0.5\linewidth} + \begin{itemize} + \item Capteur de distance à infrarouges + \item Interface I²C + \item Permet de mesurer la distance entre le robot et un obstacle + \item Principe : émettre une impulsion lumineuse et mesurer le temps de retour de l'écho + \begin{itemize} + \item Distance = $\frac{v_{lumiere} \times t_{echo}}{2}$, avec $v_{lumiere} \approx 3\times10^8 m/s$ + \end{itemize} + \item Précision : 1 mm, portée : environ 2500 mm + \end{itemize} - \column{0.5\linewidth} - \begin{figure} - \centering - \includegraphics[width=\textwidth]{img/vl53l1x-tof.png} - \end{figure} - \end{columns} + \column{0.5\linewidth} + \begin{figure} + \centering + \includegraphics[width=\textwidth]{img/vl53l1x-tof.png} + \end{figure} + \end{columns} \end{frame} \begin{frame}{Caméra monochrome} - \begin{columns} - \column{0.5\linewidth} - \begin{itemize} - \item Caméra monochrome, focus fixe, angle de vision à 60° - \item Interface I²C - \item Permet de capturer des images et de les transmettre au microcontrôleur - \item Résolution : QVGA (320x240 pixels), format : RAW6/RAW8, taille : 76 800 octets (75 KB) - \item Débit : 30 fps $\times$ 76 800 octets = 2250 KB/s - \item Consommation d'énergie : $\lesssim$ 2 mW - \end{itemize} + \begin{columns} + \column{0.5\linewidth} + \begin{itemize} + \item Caméra monochrome, focus fixe, angle de vision à 60° + \item Interface I²C + \item Permet de capturer des images et de les transmettre au microcontrôleur + \item Résolution : QVGA (320x240 pixels), format : RAW6/RAW8, taille : 76 800 octets (75 KB) + \item Débit : 30 fps $\times$ 76 800 octets = 2250 KB/s + \item Consommation d'énergie : $\lesssim$ 2 mW + \end{itemize} - \column{0.5\linewidth} - \begin{figure} - \centering - \includegraphics[width=\textwidth]{img/arducam.png} - \end{figure} - \end{columns} + \column{0.5\linewidth} + \begin{figure} + \centering + \includegraphics[width=\textwidth]{img/arducam.png} + \end{figure} + \end{columns} \end{frame} \subsection{Programmation et gestion des Entrées/Sorties} \begin{frame}{Rôle d'un système d'exploitation} - \begin{alertblock}{Quizz} - Qu'est-ce que fournit un système d'exploitation ? - \end{alertblock} + \begin{alertblock}{Quizz} + Qu'est-ce que fournit un système d'exploitation ? + \end{alertblock} - \begin{center} - \includegraphics[width=0.1\linewidth]{img/os-question.png} - \end{center} + \begin{center} + \includegraphics[width=0.1\linewidth]{img/os-question.png} + \end{center} \end{frame} \begin{frame}{Rôle d'un système d'exploitation} - \begin{center} - \includegraphics[width=0.5\linewidth]{img/os-answer.png} - \end{center} + \begin{center} + \includegraphics[width=0.5\linewidth]{img/os-answer.png} + \end{center} \end{frame} \begin{frame}[fragile]{Programmation d'un microcontrôleur} - \begin{itemize} - \item \textbf{Pas de système d'exploitation !} - \item Le programme est exécuté directement par le microcontrôleur - \item Pas de gestion de la mémoire, pas de processus - \item Accès direct aux ressources matérielles - \item Programmation en langage C/C++ ou MicroPython - \end{itemize} + \begin{itemize} + \item \textbf{Pas de système d'exploitation !} + \item Le programme est exécuté directement par le microcontrôleur + \item Pas de gestion de la mémoire, pas de processus + \item Accès direct aux ressources matérielles + \item Programmation en langage C/C++ ou MicroPython + \end{itemize} \end{frame} \begin{frame}{Programmation d'un microcontrôleur -- Lectures, écritures} - \begin{columns} - \column{0.5\linewidth} - \begin{itemize} - \item \textbf{GPIO} : \textit{General-Purpose Input Output} - \item Lecture \textbf{analogique} : mesure d'une \textit{tension} sur certaines broches - \begin{itemize} - \item Conversion analogique vers numérique (\textit{ADC}) - \item $[0.0, 3.3]\,V \rightarrow \texttt{int}\ [0,4095]$ - \item Précision : 12 bits, résolution théorique : $\approx 0.81$ mV/valeur - \end{itemize} - \item Lecture/Écriture \textbf{numérique} : états \textit{logiques} (binaires) - \begin{itemize} - \item $0$ (\texttt{LOW}, 0V) - \item $1$ (\texttt{HIGH}, 3.3V ou 5V) - \end{itemize} - \end{itemize} + \begin{columns} + \column{0.5\linewidth} + \begin{itemize} + \item \textbf{GPIO} : \textit{General-Purpose Input Output} + \item Lecture \textbf{analogique} : mesure d'une \textit{tension} sur certaines broches + \begin{itemize} + \item Conversion analogique vers numérique (\textit{ADC}) + \item $[0.0, 3.3]\,V \rightarrow \texttt{int}\ [0,4095]$ + \item Précision : 12 bits, résolution théorique : $\approx 0.81$ mV/valeur + \end{itemize} + \item Lecture/Écriture \textbf{numérique} : états \textit{logiques} (binaires) + \begin{itemize} + \item $0$ (\texttt{LOW}, 0V) + \item $1$ (\texttt{HIGH}, 3.3V ou 5V) + \end{itemize} + \end{itemize} - \column{0.5\linewidth} - \begin{figure} - \centering - \includegraphics[width=0.8\columnwidth]{img/rpi-pico-pinout.png} - \caption{Raspberry Pi Pico WH : broches GPIO\textbf{26}, GPIO\textbf{27} et GPIO\textbf{28} en entrées ADC (peuvent lire la tension en sortie d'un périphérique).} - \end{figure} - \end{columns} + \column{0.5\linewidth} + \begin{figure} + \centering + \includegraphics[width=0.8\columnwidth]{img/rpi-pico-pinout.png} + \caption{Raspberry Pi Pico WH : broches GPIO\textbf{26}, GPIO\textbf{27} et GPIO\textbf{28} en entrées ADC (peuvent lire la tension en sortie d'un périphérique).} + \end{figure} + \end{columns} \end{frame} \begin{frame}{Raspberry Pi Pico -- \textit{Pinout} (brochage)} - \begin{figure} - \centering - \includegraphics[width=0.8\columnwidth]{img/rpi-pico-pinout.png} - \end{figure} + \begin{figure} + \centering + \includegraphics[width=0.8\columnwidth]{img/rpi-pico-pinout.png} + \end{figure} \end{frame} \begin{frame}{Programmation Raspberry Pi Pico -- Comparatif des interfaces} - \begin{table}[ht] - \centering + \begin{table}[ht] + \centering - \begin{tabular}{L{2cm} C{2.2cm} C{3.8cm} C{3.8cm}} - \toprule - \textbf{Interface} & - \textbf{Niveau d'abstraction} & - \textbf{\Circled{+}} & - \textbf{\Circled{-}} \\ - \midrule + \begin{tabular}{L{2cm} C{2.2cm} C{3.8cm} C{3.8cm}} + \toprule + \textbf{Interface} & + \textbf{Niveau d'abstraction} & + \textbf{\Circled{+}} & + \textbf{\Circled{-}} \\ + \midrule - \rowcolor{rowgray} - \textbf{MicroPython} (Python) - & Haut - & Simple, interactif - & Performance, déterminisme \\ + \rowcolor{rowgray} + \textbf{MicroPython} (Python) + & Haut + & Simple, interactif + & Performance, déterminisme \\ - \textbf{Pico SDK} (C/C++) - & Bas à moyen - & Contrôle, performances - & Lisibilité, compilation \\ + \textbf{Pico SDK} (C/C++) + & Bas à moyen + & Contrôle, performances + & Lisibilité, compilation \\ - \rowcolor{rowgray} - \textbf{Arduino} (C++) - & Haut - & Portabilité, écosystème - & Contrôle, performances \\ - \bottomrule - \end{tabular} - \end{table} + \rowcolor{rowgray} + \textbf{Arduino} (C++) + & Haut + & Portabilité, écosystème + & Contrôle, performances \\ + \bottomrule + \end{tabular} + \end{table} \end{frame} \begin{frame}{Programmation Raspberry Pi Pico -- Comparatif des interfaces} - \begin{alertblock}{Une même tache dans différent paradigmes} - Configurer GP15 en sortie et faire clignoter une LED. - \end{alertblock} + \begin{alertblock}{Une même tache dans différent paradigmes} + Configurer GP15 en sortie et faire clignoter une LED. + \end{alertblock} - \begin{figure} - \centering - \includegraphics[width=0.7\linewidth]{img/fritzing-led.png} - \end{figure} + \begin{figure} + \centering + \includegraphics[width=0.7\linewidth]{img/fritzing-led.png} + \end{figure} \end{frame} \begin{frame}[fragile]{Programmation Raspberry Pi Pico -- MicroPython} - \begin{minted}[fontsize=\small]{python} + \begin{minted}[fontsize=\small]{python} from machine import Pin from time import sleep @@ -822,7 +814,7 @@ while True: \end{frame} \begin{frame}[fragile]{Programmation Raspberry Pi Pico -- C++ Pico SDK} - \begin{minted}[fontsize=\small]{c} + \begin{minted}[fontsize=\small]{c} #include "pico/stdlib.h" int main() { @@ -841,7 +833,7 @@ int main() { \end{frame} \begin{frame}[fragile]{Programmation Raspberry Pi Pico -- Arduino API} - \begin{minted}[fontsize=\small]{cpp} + \begin{minted}[fontsize=\small]{cpp} void setup() { pinMode(15, OUTPUT); } @@ -856,43 +848,43 @@ void loop() { \end{frame} \begin{frame}{Quizz} - \begin{alertblock}{Quizz} - Comment faire varier l'intensité de la LED pour produire un effet de fondu, en boucle ? - \end{alertblock} + \begin{alertblock}{Quizz} + Comment faire varier l'intensité de la LED pour produire un effet de fondu, en boucle ? + \end{alertblock} \end{frame} \begin{frame}{PWM} - \begin{columns} - \column{0.5\linewidth} - \begin{itemize} - \item Écriture analogique ? - \begin{itemize} - \item Le microcontrôleur ne peut pas générer une tension arbitraire... - \end{itemize} - \item Décrire un phénomène continu par des modulations - \item Technique : \textit{PWM} (\textit{Pulse Width Modulation}) - \begin{itemize} - \item Générer un signal carré de fréquence fixe - \item Faire varier le rapport cyclique (durée du niveau haut / période) - \item La valeur moyenne du signal est proportionnelle au rapport cyclique - \end{itemize} - \end{itemize} + \begin{columns} + \column{0.5\linewidth} + \begin{itemize} + \item Écriture analogique ? + \begin{itemize} + \item Le microcontrôleur ne peut pas générer une tension arbitraire... + \end{itemize} + \item Décrire un phénomène continu par des modulations + \item Technique : \textit{PWM} (\textit{Pulse Width Modulation}) + \begin{itemize} + \item Générer un signal carré de fréquence fixe + \item Faire varier le rapport cyclique (durée du niveau haut / période) + \item La valeur moyenne du signal est proportionnelle au rapport cyclique + \end{itemize} + \end{itemize} - \column{0.5\linewidth} - \begin{center} - \includegraphics[width=0.8\columnwidth]{img/pwm.png} - \end{center} + \column{0.5\linewidth} + \begin{center} + \includegraphics[width=0.8\columnwidth]{img/pwm.png} + \end{center} - \begin{itemize} - \item Assuré par un composant matériel dédié pour ne pas monopoliser le processeur - \end{itemize} - \end{columns} + \begin{itemize} + \item Assuré par un composant matériel dédié pour ne pas monopoliser le processeur + \end{itemize} + \end{columns} \end{frame} \begin{frame}[fragile]{Mesurer le temps} - Dans le but d'évaluer les performances, mesurer la durée d'une action, etc. + Dans le but d'évaluer les performances, mesurer la durée d'une action, etc. - \begin{minted}{cpp} + \begin{minted}{cpp} #include "pico/stdlib.h" #include @@ -912,22 +904,22 @@ int main() { \subsection{Communications} \begin{frame}{Communications série : UART [\href{http://bts2m.free.fr/TP_Arduino/01_UART.html}{réf.}]} - \begin{itemize} - \item \textbf{UART} : \textit{Universal Asynchronous Receiver Transmitter} - \item Convertit des données \textit{parallèles} (un octet en mémoire) en données \textit{série} (des bits sur un fil) - \item Liaison avec 3 fils : \textbf{Tx} (\textit{transmit} de l'émetteur), \textbf{Rx} (\textit{receive} du récepteur), \textbf{GND} (masse) - \item \textit{Full duplex} : émission et réception simultanées ; point à point : 2 éléments - \item Vitesse : en général 9600 bauds (bits/seconde), au maximum 115200 bauds (environ 14 kB/seconde...) - \item "Masqué" derrière le port USB du Raspberry ! - \end{itemize} + \begin{itemize} + \item \textbf{UART} : \textit{Universal Asynchronous Receiver Transmitter} + \item Convertit des données \textit{parallèles} (un octet en mémoire) en données \textit{série} (des bits sur un fil) + \item Liaison avec 3 fils : \textbf{Tx} (\textit{transmit} de l'émetteur), \textbf{Rx} (\textit{receive} du récepteur), \textbf{GND} (masse) + \item \textit{Full duplex} : émission et réception simultanées ; point à point : 2 éléments + \item Vitesse : en général 9600 bauds (bits/seconde), au maximum 115200 bauds (environ 14 kB/seconde...) + \item "Masqué" derrière le port USB du Raspberry ! + \end{itemize} - \begin{center} - \includegraphics[width=0.6\linewidth]{img/uart.png} - \end{center} + \begin{center} + \includegraphics[width=0.6\linewidth]{img/uart.png} + \end{center} \end{frame} \begin{frame}[fragile]{Communications série : UART -- Exemple : écriture} - \begin{minted}{cpp} + \begin{minted}{cpp} #include #include "pico/stdlib.h" @@ -945,7 +937,7 @@ int main() { \end{frame} \begin{frame}[fragile]{Communications série : UART -- Exemple : lecture} - \begin{minted}{cpp} + \begin{minted}{cpp} #include #include "pico/stdlib.h" @@ -966,17 +958,17 @@ int main() { \end{frame} \begin{frame}{Communications série : I²C [\href{https://passionelectronique.fr/liaisons-series-uart-i2c-spi/}{réf.}]} - \begin{itemize} - \item \textbf{I²C} : \textit{Inter-Integrated Circuit} - \item Topologie "maître-esclave", adresses uniques, bits de lecture/écriture - \item Liaison avec trois fils : \textbf{SDA} (signal de données), \textbf{SCL} (signal d'horloge), \textbf{GND} (masse) - \item \textit{Semi duplex} : communications bidirectionnelles, mais pas simultanées ; multi-points - \item Vitesse : en général 100 kbps (10x plus rapide que l'UART), au maximum 3.4 Mbps (environ 425 kB/seconde) - \end{itemize} + \begin{itemize} + \item \textbf{I²C} : \textit{Inter-Integrated Circuit} + \item Topologie "maître-esclave", adresses uniques, bits de lecture/écriture + \item Liaison avec trois fils : \textbf{SDA} (signal de données), \textbf{SCL} (signal d'horloge), \textbf{GND} (masse) + \item \textit{Semi duplex} : communications bidirectionnelles, mais pas simultanées ; multi-points + \item Vitesse : en général 100 kbps (10x plus rapide que l'UART), au maximum 3.4 Mbps (environ 425 kB/seconde) + \end{itemize} - \begin{center} - \includegraphics[width=0.6\linewidth]{img/i2c.jpg} - \end{center} + \begin{center} + \includegraphics[width=0.6\linewidth]{img/i2c.jpg} + \end{center} \end{frame} % \begin{frame}[fragile]{Communications série : I²C -- Exemple} @@ -986,17 +978,17 @@ int main() { % \end{frame} \begin{frame}{Communications série : SPI [\href{https://passionelectronique.fr/liaisons-series-uart-i2c-spi/}{réf.}]} - \begin{itemize} - \item \textbf{SPI} : \textit{Serial Peripheral Interface} - \item Topologie "maître-esclave", pas d'adresses, bits de lecture/écriture - \item Liaison avec quatre fils : \textbf{MOSI} (signal de données maître vers esclave), \textbf{MISO} (signal de données esclave vers maître), \textbf{SCK} (signal d'horloge), \textbf{CS} (sélection de l'esclave) - \item \textit{Full duplex} : communications bidirectionnelles simultanées ; multi-points - \item Vitesse : en général 1 Mbps, au maximum 10 Mbps (environ 1.25 MB/seconde) - \end{itemize} + \begin{itemize} + \item \textbf{SPI} : \textit{Serial Peripheral Interface} + \item Topologie "maître-esclave", pas d'adresses, bits de lecture/écriture + \item Liaison avec quatre fils : \textbf{MOSI} (signal de données maître vers esclave), \textbf{MISO} (signal de données esclave vers maître), \textbf{SCK} (signal d'horloge), \textbf{CS} (sélection de l'esclave) + \item \textit{Full duplex} : communications bidirectionnelles simultanées ; multi-points + \item Vitesse : en général 1 Mbps, au maximum 10 Mbps (environ 1.25 MB/seconde) + \end{itemize} - \begin{center} - \includegraphics[width=0.6\linewidth]{img/spi.png} - \end{center} + \begin{center} + \includegraphics[width=0.6\linewidth]{img/spi.png} + \end{center} \end{frame} % \begin{frame}[fragile]{Communications série : SPI -- Exemple} @@ -1006,56 +998,56 @@ int main() { % \end{frame} \begin{frame}{Communications sans-fil : Wi-Fi} - \begin{itemize} - \item \textbf{Wi-Fi} : norme IEEE 802.11, réseau local sans-fil - \item Topologie "point d'accès" (AP) ou "ad-hoc" - \item Vitesse : de quelques MB/s à environ 1 GB/s selon la norme (802.11a/b/g/n/ac/ax) - \item Portée : de quelques mètres à quelques dizaines de mètres selon l'environnement - \end{itemize} + \begin{itemize} + \item \textbf{Wi-Fi} : norme IEEE 802.11, réseau local sans-fil + \item Topologie "point d'accès" (AP) ou "ad-hoc" + \item Vitesse : de quelques MB/s à environ 1 GB/s selon la norme (802.11a/b/g/n/ac/ax) + \item Portée : de quelques mètres à quelques dizaines de mètres selon l'environnement + \end{itemize} - \begin{center} - \includegraphics[width=0.6\linewidth]{img/zigbee-chart.png} - \end{center} + \begin{center} + \includegraphics[width=0.6\linewidth]{img/zigbee-chart.png} + \end{center} \end{frame} \begin{frame}{Communications sans-fil : comparaison} - \begin{center} - \includegraphics[width=0.9\linewidth]{img/zigbee-table.png} - \end{center} + \begin{center} + \includegraphics[width=0.9\linewidth]{img/zigbee-table.png} + \end{center} \end{frame} \subsection{Chaîne de compilation} \begin{frame}{Chaîne de compilation croisée} - \begin{figure} - \centering - \includegraphics[width=\linewidth]{img/compilation.png} - \end{figure} + \begin{figure} + \centering + \includegraphics[width=\linewidth]{img/compilation.png} + \end{figure} \end{frame} \begin{frame}{Flasher le Pico : chargeur de démarrage} - \begin{columns} - \column{0.6\linewidth} - \begin{enumerate} - \item Brancher le Pico en USB en maintenant le bouton \texttt{BOOTSEL} - \item Le Pico apparaît comme un disque USB nommé \texttt{RPI-RP2} - \item Copier le firmware compilé (fichier \texttt{.uf2}) - \item Le Pico redémarre et le nouveau programme s'exécute. - \end{enumerate} + \begin{columns} + \column{0.6\linewidth} + \begin{enumerate} + \item Brancher le Pico en USB en maintenant le bouton \texttt{BOOTSEL} + \item Le Pico apparaît comme un disque USB nommé \texttt{RPI-RP2} + \item Copier le firmware compilé (fichier \texttt{.uf2}) + \item Le Pico redémarre et le nouveau programme s'exécute. + \end{enumerate} - \column{0.4\linewidth} - \begin{figure} - \centering - \includegraphics[width=\columnwidth]{img/pico-bootsel.png} - \end{figure} - \end{columns} + \column{0.4\linewidth} + \begin{figure} + \centering + \includegraphics[width=\columnwidth]{img/pico-bootsel.png} + \end{figure} + \end{columns} - \medskip - \begin{alertblock}{En pratique} - Le programme fonctionne : on peut demander l'entrée en mode BOOTSEL par USB. + \medskip + \begin{alertblock}{En pratique} + Le programme fonctionne : on peut demander l'entrée en mode BOOTSEL par USB. - S'il ne répond plus : maintenir \textbf{BOOTSEL} en rebranchant le câble, puis charger le même fichier UF2. - \end{alertblock} + S'il ne répond plus : maintenir \textbf{BOOTSEL} en rebranchant le câble, puis charger le même fichier UF2. + \end{alertblock} \end{frame} \section{Robotique} @@ -1063,103 +1055,103 @@ int main() { \subsection{Généralités} \begin{frame}{Qu'est-ce qu'un robot ?} - \begin{center} - \includegraphics[width=0.5\linewidth]{img/sojourner-mars.jpg} + \begin{center} + \includegraphics[width=0.5\linewidth]{img/sojourner-mars.jpg} - \footnotesize \textit{Sojourner} sur la surface de Mars, décembre 1997 [\href{https://science.nasa.gov/photojournal/sojourner-rover-near-the-dice/}{réf.}] - \end{center} + \footnotesize \textit{Sojourner} sur la surface de Mars, décembre 1997 [\href{https://science.nasa.gov/photojournal/sojourner-rover-near-the-dice/}{réf.}] + \end{center} \end{frame} \begin{frame}{Qu'est-ce qu'un robot ?} - \textbf{Robot = système de systèmes} + \textbf{Robot = système de systèmes} - \begin{itemize} - \item \textbf{Mobilité} : énergie, déplacement (propulsion), orientation (direction) - \item \textbf{Charge utile} : capteurs, informations, matériels, etc. - \item \textbf{Intelligence} : contrôle, commande, communication, décision - \end{itemize} + \begin{itemize} + \item \textbf{Mobilité} : énergie, déplacement (propulsion), orientation (direction) + \item \textbf{Charge utile} : capteurs, informations, matériels, etc. + \item \textbf{Intelligence} : contrôle, commande, communication, décision + \end{itemize} \end{frame} \begin{frame}{Qu'est-ce qu'un robot ? -- Mobilité} - \begin{figure} - \begin{subfigure}{.48\textwidth} - \centering - \includegraphics[width=.8\linewidth]{img/china-humanoid-robots.png} - \end{subfigure} - \begin{subfigure}{.48\textwidth} - \centering - \includegraphics[width=.6\linewidth]{img/boston-dynamics-spot.png} - \end{subfigure} - \end{figure} - \begin{figure} - \begin{subfigure}[t]{.48\textwidth} - \vspace{0pt} - \centering - \includegraphics[width=.8\linewidth]{img/drones-ukraine.png} - \end{subfigure} - \begin{subfigure}[t]{.48\textwidth} - \vspace{0pt} - \centering - \includegraphics[width=.8\linewidth]{img/usv-ifremer.png} - \end{subfigure} - \end{figure} + \begin{figure} + \begin{subfigure}{.48\textwidth} + \centering + \includegraphics[width=.8\linewidth]{img/china-humanoid-robots.png} + \end{subfigure} + \begin{subfigure}{.48\textwidth} + \centering + \includegraphics[width=.6\linewidth]{img/boston-dynamics-spot.png} + \end{subfigure} + \end{figure} + \begin{figure} + \begin{subfigure}[t]{.48\textwidth} + \vspace{0pt} + \centering + \includegraphics[width=.8\linewidth]{img/drones-ukraine.png} + \end{subfigure} + \begin{subfigure}[t]{.48\textwidth} + \vspace{0pt} + \centering + \includegraphics[width=.8\linewidth]{img/usv-ifremer.png} + \end{subfigure} + \end{figure} \end{frame} \begin{frame}{Qu'est-ce qu'un robot ? -- Charge utile [\href{https://www.thespacereview.com/article/4951/1}{réf.}]} - \begin{figure} - \centering - \includegraphics[width=0.8\linewidth]{img/farrah-satellites.png} - \end{figure} + \begin{figure} + \centering + \includegraphics[width=0.8\linewidth]{img/farrah-satellites.png} + \end{figure} \end{frame} \begin{frame}{Qu'est-ce qu'un robot ? -- Charge utile} - \begin{figure} - \begin{subfigure}{.48\textwidth} - \centering - \includegraphics[width=\linewidth]{img/boston-dynamics-weapon.png} - \end{subfigure} - \begin{subfigure}{.48\textwidth} - \centering - \includegraphics[width=\linewidth]{img/robot-industriel.png} - \end{subfigure} - \end{figure} + \begin{figure} + \begin{subfigure}{.48\textwidth} + \centering + \includegraphics[width=\linewidth]{img/boston-dynamics-weapon.png} + \end{subfigure} + \begin{subfigure}{.48\textwidth} + \centering + \includegraphics[width=\linewidth]{img/robot-industriel.png} + \end{subfigure} + \end{figure} \end{frame} \begin{frame}{Qu'est-ce qu'un robot ? -- Intelligence} - \begin{figure} - \begin{subfigure}{.48\textwidth} - \centering - \includegraphics[width=0.8\linewidth]{img/microcontrollers.png} - \end{subfigure} - \begin{subfigure}{.48\textwidth} - \centering - \includegraphics[width=0.8\linewidth]{img/jetson-orin-nano.png} - \end{subfigure} - \end{figure} + \begin{figure} + \begin{subfigure}{.48\textwidth} + \centering + \includegraphics[width=0.8\linewidth]{img/microcontrollers.png} + \end{subfigure} + \begin{subfigure}{.48\textwidth} + \centering + \includegraphics[width=0.8\linewidth]{img/jetson-orin-nano.png} + \end{subfigure} + \end{figure} \end{frame} \begin{frame}{Définitions -- Systèmes autonomes} - \begin{columns} - \column{0.5\linewidth} - \begin{itemize} - \item Robotique, systèmes autonomes~\footnote[frame]{\fullcite{kephartVisionAutonomicComputing2003}} : - \begin{itemize} - \item \textbf{Capteurs} : produisent une vue de l'environnement du système - \item \textbf{Actionneurs} : commandent le système selon son état et sa consigne - \end{itemize} - \item Objets connectés, \textit{Internet of Things} (\textit{IoT}) : contrôle, commande à distance - \end{itemize} + \begin{columns} + \column{0.5\linewidth} + \begin{itemize} + \item Robotique, systèmes autonomes~\footnote[frame]{\fullcite{kephartVisionAutonomicComputing2003}} : + \begin{itemize} + \item \textbf{Capteurs} : produisent une vue de l'environnement du système + \item \textbf{Actionneurs} : commandent le système selon son état et sa consigne + \end{itemize} + \item Objets connectés, \textit{Internet of Things} (\textit{IoT}) : contrôle, commande à distance + \end{itemize} - \column{0.5\linewidth} - \includegraphics[width=\columnwidth]{img/mape-k.png} - \end{columns} + \column{0.5\linewidth} + \includegraphics[width=\columnwidth]{img/mape-k.png} + \end{columns} \end{frame} \begin{frame}{Intelligence -- Chaîne de l'information} - \begin{figure} - \centering - \includegraphics[width=0.7\linewidth]{img/chaine-traitement.png} - \end{figure} + \begin{figure} + \centering + \includegraphics[width=0.7\linewidth]{img/chaine-traitement.png} + \end{figure} \end{frame} % \begin{frame}{Capteurs -- Classes} @@ -1186,29 +1178,29 @@ int main() { % \end{frame} \begin{frame}{Intelligence -- Capteurs [\href{https://spe-lavoisier.fr/1SI/Cours/Chapitre4.php}{réf.}]} - \begin{columns} - \column{0.5\linewidth} - Caractéristiques d'un capteur : - \begin{itemize} - \item Temps de réponse - \item Fréquence d'échantillonnage - \item Précision, finesse, résolution, stabilité - \item Coût - \item Taux d'erreur (dispersion, aberrations, etc.) - \item Robustesse (environnement) - \item Charge de calcul induite - \item Poids, consommation d'énergie, dimensions, etc. - \end{itemize} + \begin{columns} + \column{0.5\linewidth} + Caractéristiques d'un capteur : + \begin{itemize} + \item Temps de réponse + \item Fréquence d'échantillonnage + \item Précision, finesse, résolution, stabilité + \item Coût + \item Taux d'erreur (dispersion, aberrations, etc.) + \item Robustesse (environnement) + \item Charge de calcul induite + \item Poids, consommation d'énergie, dimensions, etc. + \end{itemize} - \column{0.5\linewidth} - \includegraphics[width=\columnwidth]{img/sensor-error.png} + \column{0.5\linewidth} + \includegraphics[width=\columnwidth]{img/sensor-error.png} - \begin{exampleblock}{Exemple : capteur de distance à ultrasons} - distance $\rightarrow$ temps de vol d'une onde ultrasonore - $\rightarrow$ durée d'une impulsion électrique $\rightarrow$ - mesure du temps par le Pico $\rightarrow$ $d = v \times t / 2$ - \end{exampleblock} - \end{columns} + \begin{exampleblock}{Exemple : capteur de distance à ultrasons} + distance $\rightarrow$ temps de vol d'une onde ultrasonore + $\rightarrow$ durée d'une impulsion électrique $\rightarrow$ + mesure du temps par le Pico $\rightarrow$ $d = v \times t / 2$ + \end{exampleblock} + \end{columns} \end{frame} % \begin{frame}{Intelligence -- Actionneurs} @@ -1225,718 +1217,724 @@ int main() { % \end{frame} \begin{frame}{Intelligence -- Contrôle, commandes, asservissement} - \begin{itemize} - \item Éléments contrôlés en boucle fermée : \textbf{asservissements} - \item Système automatique qui ajuste son comportement en fonction de \textbf{consignes} et de \textbf{mesures} - \item Exemple : + \begin{itemize} + \item Éléments contrôlés en boucle fermée : \textbf{asservissements} + \item Système automatique qui ajuste son comportement en fonction de \textbf{consignes} et de \textbf{mesures} + \item Exemple : - \begin{exampleblock}{\emoji{repeat} Boucle d'asservissement} - \begin{enumerate} - \item \emoji{dart} \textbf{Consigne} : objectif à atteindre (ex : avancer à 10 cm du mur) - \item \emoji{bar-chart} \textbf{Mesure} : capteur qui lit la position (GPS), la distance réelle (LiDAR), etc. - \item \emoji{cross-mark} \textbf{Erreur} : différence entre consigne et mesure - \item \emoji{brain} \textbf{Contrôleur} : calcule la \textbf{commande} à partir de l'erreur - \item \emoji{robot} \textbf{Commande} : signal envoyé au système (ex : augmenter la vitesse des moteurs) - \end{enumerate} - \end{exampleblock} - \end{itemize} + \begin{exampleblock}{\emoji{repeat} Boucle d'asservissement} + \begin{enumerate} + \item \emoji{dart} \textbf{Consigne} : objectif à atteindre (ex : avancer à 10 cm du mur) + \item \emoji{bar-chart} \textbf{Mesure} : capteur qui lit la position (GPS), la distance réelle (LiDAR), etc. + \item \emoji{cross-mark} \textbf{Erreur} : différence entre consigne et mesure + \item \emoji{brain} \textbf{Contrôleur} : calcule la \textbf{commande} à partir de l'erreur + \item \emoji{robot} \textbf{Commande} : signal envoyé au système (ex : augmenter la vitesse des moteurs) + \end{enumerate} + \end{exampleblock} + \end{itemize} \end{frame} \begin{frame}{Problème : le positionnement} - \begin{columns} - \column{0.6\linewidth} - \begin{itemize} - \item \textbf{Cap} = \textbf{consigne} + \textbf{erreur} - \begin{itemize} - \item Comment savoir où se trouve le robot ? - \item Comment savoir où se dirige le robot ? - \item Comment savoir où se trouve un obstacle ? - \end{itemize} - \end{itemize} + \begin{columns} + \column{0.6\linewidth} + \begin{itemize} + \item \textbf{Cap} = \textbf{consigne} + \textbf{erreur} + \begin{itemize} + \item Comment savoir où se trouve le robot ? + \item Comment savoir où se dirige le robot ? + \item Comment savoir où se trouve un obstacle ? + \end{itemize} + \end{itemize} - \column{0.4\linewidth} - \begin{figure} - \centering - \includegraphics[width=.8\linewidth]{img/missile.png} - \end{figure} - \end{columns} + \column{0.4\linewidth} + \begin{figure} + \centering + \includegraphics[width=.8\linewidth]{img/missile.png} + \end{figure} + \end{columns} - \begin{exampleblock}{The Missile Knows Where It Is [\href{https://knowyourmeme.com/memes/the-missile-knows-where-it-is}{réf.}]} - \textit{The missile knows where it is at all times. It knows this because it knows where it isn't. By subtracting where it is from where it isn't, or where it isn't from where it is (whichever is greater), it obtains a difference, or deviation. The guidance subsystem uses deviations to generate corrective commands to drive the missile from a position where it is to a position where it isn't, and arriving at a position where it wasn't, it now is. Consequently, the position where it is, is now the position that it wasn't, and it follows that the position that it was, is now the position that it isn't.} - \end{exampleblock} + \begin{exampleblock}{The Missile Knows Where It Is [\href{https://knowyourmeme.com/memes/the-missile-knows-where-it-is}{réf.}]} + \textit{The missile knows where it is at all times. It knows this because it knows where it isn't. By subtracting where it is from where it isn't, or where it isn't from where it is (whichever is greater), it obtains a difference, or deviation. The guidance subsystem uses deviations to generate corrective commands to drive the missile from a position where it is to a position where it isn't, and arriving at a position where it wasn't, it now is. Consequently, the position where it is, is now the position that it wasn't, and it follows that the position that it was, is now the position that it isn't.} + \end{exampleblock} \end{frame} \begin{frame}{Systèmes de positionnement -- Principes} - \begin{itemize} - \item \textbf{Positionnement global} : localisation dans un référentiel géographique - \begin{itemize} - \item \textbf{GNSS} (GPS, Galileo, etc.) : triangulation (trilatération) à partir de signaux satellites - \end{itemize} + \begin{itemize} + \item \textbf{Positionnement global} : localisation dans un référentiel géographique + \begin{itemize} + \item \textbf{GNSS} (GPS, Galileo, etc.) : triangulation (trilatération) à partir de signaux satellites + \end{itemize} - \vspace{0.4cm} + \vspace{0.4cm} - \item \textbf{Positionnement local} : estimation de la position par rapport à l'environnement - \begin{itemize} - \item \textbf{Odométrie} : mesure des déplacements à partir de capteurs (ex : roues, inertie) - \item \textbf{LiDAR} : mesure des distances par laser - \item \textbf{Radar} : mesure des distances et vitesses par ondes radio - \item \textbf{Caméras} : analyse des images par vision par ordinateur - \end{itemize} + \item \textbf{Positionnement local} : estimation de la position par rapport à l'environnement + \begin{itemize} + \item \textbf{Odométrie} : mesure des déplacements à partir de capteurs (ex : roues, inertie) + \item \textbf{LiDAR} : mesure des distances par laser + \item \textbf{Radar} : mesure des distances et vitesses par ondes radio + \item \textbf{Caméras} : analyse des images par vision par ordinateur + \end{itemize} - \vspace{0.4cm} + \vspace{0.4cm} - \item \textbf{Localisation} : exploitation des mesures pour estimer la position - \begin{itemize} - \item SLAM (\textit{Simultaneous Localization and Mapping}) : estimer les déplacements et la position dans un environnement local - \end{itemize} - \end{itemize} + \item \textbf{Localisation} : exploitation des mesures pour estimer la position + \begin{itemize} + \item SLAM (\textit{Simultaneous Localization and Mapping}) : estimer les déplacements et la position dans un environnement local + \end{itemize} + \end{itemize} \end{frame} \begin{frame}{Systèmes de positionnement -- Comparaison} - \begin{table} - \centering - \small - \begin{tabular}{L{2cm} L{4.2cm} L{5cm}} - \toprule - \textbf{Technologie} & \textbf{Avantages} & \textbf{Limites} \\ - \midrule + \begin{table} + \centering + \small + \begin{tabular}{L{2cm} L{4.2cm} L{5cm}} + \toprule + \textbf{Technologie} & \textbf{Avantages} & \textbf{Limites} \\ + \midrule - \rowcolor{rowgray} - \textbf{GPS/GNSS} - & Position absolue, couverture mondiale - & Peu fiable en intérieur, précision variable \\ + \rowcolor{rowgray} + \textbf{GPS/GNSS} + & Position absolue, couverture mondiale + & Peu fiable en intérieur, précision variable \\ - \textbf{LiDAR} - & Mesures précises, cartographie 2D/3D - & Coût, sensibilité aux conditions météo \\ + \textbf{LiDAR} + & Mesures précises, cartographie 2D/3D + & Coût, sensibilité aux conditions météo \\ - \rowcolor{rowgray} - \textbf{Radar} - & Robuste aux intempéries, mesure des vitesses - & Résolution spatiale souvent inférieure au LiDAR \\ + \rowcolor{rowgray} + \textbf{Radar} + & Robuste aux intempéries, mesure des vitesses + & Résolution spatiale souvent inférieure au LiDAR \\ - \textbf{Caméras} - & Faible coût, information visuelle riche - & Sensibilité à l'éclairage, calcul intensif \\ + \textbf{Caméras} + & Faible coût, information visuelle riche + & Sensibilité à l'éclairage, calcul intensif \\ - \bottomrule - \end{tabular} - \end{table} + \bottomrule + \end{tabular} + \end{table} - $\rightarrow$ \textbf{Fusion de capteurs} : combiner plusieurs technologies pour compenser leurs limites. + $\rightarrow$ \textbf{Fusion de capteurs} : combiner plusieurs technologies pour compenser leurs limites. \end{frame} \subsection{Commande à distance} \begin{frame}[fragile]{Commande -- Communications} - \begin{itemize} - \item Architecture : - \begin{itemize} - \item PC : Envoi de commandes filaire $\rightarrow$ USB $\rightarrow$ Robot - \item Téléphone : Envoi de commandes sans fil $\rightarrow$ Wi-Fi $\rightarrow$ Robot - \end{itemize} - \item Peu importe le type de liaison, le même programme s'exécute sur le microcontrôleur - \item $\rightarrow$ Il faut programmer le Raspberry pour \textbf{recevoir}, \textbf{décoder} et \textbf{exécuter} des lignes de commande. - \end{itemize} + \begin{itemize} + \item Architecture : + \begin{itemize} + \item PC : Envoi de commandes filaire $\rightarrow$ USB $\rightarrow$ Robot + \item Téléphone : Envoi de commandes sans fil $\rightarrow$ Wi-Fi $\rightarrow$ Robot + \end{itemize} + \item Peu importe le type de liaison, le même programme s'exécute sur le microcontrôleur + \item $\rightarrow$ Il faut programmer le Raspberry pour \textbf{recevoir}, \textbf{décoder} et \textbf{exécuter} des lignes de commande. + \end{itemize} \end{frame} \begin{frame}[fragile]{Commande -- Communications} - \begin{alertblock}{Communications avec le robot} - \begin{itemize} - \item Objectifs : avancer, reculer, tourner... - \item Quels éléments va-t-on commander ? - \item Sur la base de quelles informations ? - \item $\rightarrow$ De quelles \textbf{protocole} avons-nous besoin ? - \end{itemize} - \end{alertblock} + \begin{alertblock}{Communications avec le robot} + \begin{itemize} + \item Objectifs : avancer, reculer, tourner... + \item Quels éléments va-t-on commander ? + \item Sur la base de quelles informations ? + \item $\rightarrow$ De quelles \textbf{protocole} avons-nous besoin ? + \end{itemize} + \end{alertblock} \end{frame} \begin{frame}[fragile]{Commande -- Communications -- Syntaxe des commandes (JSON)} - \begin{center} - \resizebox{0.9\textwidth}{!}{% - \footnotesize - \begin{tabular}{p{0.42\textwidth}p{0.53\textwidth}} - \toprule - \textbf{Commande} & \textbf{Effet} \\ - \midrule + \begin{center} + \resizebox{0.9\textwidth}{!}{% + \footnotesize + \begin{tabular}{p{0.42\textwidth}p{0.53\textwidth}} + \toprule + \textbf{Commande} & \textbf{Effet} \\ + \midrule - \rowcolor{rowgray} - \mintinline{json}|{"left":200,"right":200}| - & Avancer des deux côtés pendant une seconde par défaut \\ + \rowcolor{rowgray} + \mintinline{json}|{"left":200,"right":200}| + & Avancer des deux côtés pendant une seconde par défaut \\ - \mintinline{json}|{"left":200,"right":-200,"duration":3000}| - & Tourner sur place pendant trois secondes \\ + \mintinline{json}|{"left":200,"right":-200,"duration":3000}| + & Tourner sur place pendant trois secondes \\ - \rowcolor{rowgray} - \mintinline{json}|{"stop":true}| - & Arrêter immédiatement les roues et annuler la mission du robot \\ + \rowcolor{rowgray} + \mintinline{json}|{"stop":true}| + & Arrêter immédiatement les roues et annuler la mission du robot \\ - \mintinline{json}|{"telemetry":500}| / \mintinline{json}|{"telemetry":0}| - & Envoyer la télémétrie toutes les 500 ms / désactiver la télémétrie périodique \\ + \mintinline{json}|{"telemetry":500}| / \mintinline{json}|{"telemetry":0}| + & Envoyer la télémétrie toutes les 500 ms / désactiver la télémétrie périodique \\ - \rowcolor{rowgray} - \mintinline{json}|{"mission":1}| / \mintinline{json}|{"mission":0}| - & Sélectionner la mission 1 / désactiver la mission du robot \\ + \rowcolor{rowgray} + \mintinline{json}|{"mission":1}| / \mintinline{json}|{"mission":0}| + & Sélectionner la mission 1 / désactiver la mission du robot \\ - \mintinline{json}|{"info":true}| - & Envoyer une ligne séparée contenant les informations du robot \\ + \mintinline{json}|{"info":true}| + & Envoyer une ligne séparée contenant les informations du robot \\ - \rowcolor{rowgray} - \mintinline{json}|{"seq":7,"left":100,"right":100}| - & Associer l'identifiant 7 aux télémétries suivantes \\ + \rowcolor{rowgray} + \mintinline{json}|{"seq":7,"left":100,"right":100}| + & Associer l'identifiant 7 aux télémétries suivantes \\ - \bottomrule - \end{tabular} - } - \end{center} + \bottomrule + \end{tabular} + } + \end{center} \end{frame} \begin{frame}[fragile]{L'étiquette \texttt{seq}} - \begin{itemize} - \item Choisie par l'émetteur - \item Chaque commande qui la fournit remplace la valeur mémorisée - \item Toutes les lignes de télémétrie suivantes portent la dernière valeur - \end{itemize} + \begin{itemize} + \item Choisie par l'émetteur + \item Chaque commande qui la fournit remplace la valeur mémorisée + \item Toutes les lignes de télémétrie suivantes portent la dernière valeur + \end{itemize} \end{frame} \begin{frame}[fragile]{Commande -- Communications -- Syntaxe des réponses (JSON)} - \begin{center} - \resizebox{0.9\textwidth}{!}{% - \footnotesize - \begin{tabular}{p{0.27\textwidth}p{0.68\textwidth}} - \toprule - \textbf{Champ} & \textbf{Signification} \\ - \midrule + \begin{center} + \resizebox{0.9\textwidth}{!}{% + \footnotesize + \begin{tabular}{p{0.27\textwidth}p{0.68\textwidth}} + \toprule + \textbf{Champ} & \textbf{Signification} \\ + \midrule - \rowcolor{rowgray} - \mintinline{text}|seq| - & Identifiant de la dernière commande, ou \mintinline{json}|-1| si aucun n'a été fourni \\ + \rowcolor{rowgray} + \mintinline{text}|seq| + & Identifiant de la dernière commande, ou \mintinline{json}|-1| si aucun n'a été fourni \\ - \mintinline{text}|ms| - & Temps écoulé depuis le démarrage du robot, en millisecondes \\ + \mintinline{text}|ms| + & Temps écoulé depuis le démarrage du robot, en millisecondes \\ - \rowcolor{rowgray} - \mintinline{text}|left|, \mintinline{text}|right| - & Vitesses actuellement demandées aux roues, et non vitesses mesurées \\ + \rowcolor{rowgray} + \mintinline{text}|left|, \mintinline{text}|right| + & Vitesses actuellement demandées aux roues, et non vitesses mesurées \\ - \mintinline{text}|moving| - & \mintinline{json}|true| si la vitesse demandée d'au moins une roue est non nulle \\ + \mintinline{text}|moving| + & \mintinline{json}|true| si la vitesse demandée d'au moins une roue est non nulle \\ - \rowcolor{rowgray} - \mintinline{text}|mission| - & Numéro de la mission sélectionnée ; \mintinline{json}|0| signifie qu'aucune mission n'est active \\ + \rowcolor{rowgray} + \mintinline{text}|mission| + & Numéro de la mission sélectionnée ; \mintinline{json}|0| signifie qu'aucune mission n'est active \\ - \mintinline{text}|front_mm|, \mintinline{text}|side_mm| - & Dernière distance mesurée en millimètres, ou \mintinline{json}|-1| si indisponible \\ + \mintinline{text}|front_mm|, \mintinline{text}|side_mm| + & Dernière distance mesurée en millimètres, ou \mintinline{json}|-1| si indisponible \\ - \rowcolor{rowgray} - \mintinline{text}|front_ok|, \mintinline{text}|side_ok| - & Indique si la dernière mesure du capteur est valide ; à vérifier avant d'utiliser la distance \\ + \rowcolor{rowgray} + \mintinline{text}|front_ok|, \mintinline{text}|side_ok| + & Indique si la dernière mesure du capteur est valide ; à vérifier avant d'utiliser la distance \\ - \mintinline{text}|front_q|, \mintinline{text}|side_q| - & Qualité du signal : \mintinline{text}|front_q| vaut toujours \mintinline{json}|-1| ; - \mintinline{text}|side_q| indique le taux de signal du VL53L1X, ou \mintinline{json}|-1| si indisponible \\ + \mintinline{text}|front_q|, \mintinline{text}|side_q| + & Qualité du signal : \mintinline{text}|front_q| vaut toujours \mintinline{json}|-1| ; + \mintinline{text}|side_q| indique le taux de signal du VL53L1X, ou \mintinline{json}|-1| si indisponible \\ - \rowcolor{rowgray} - \mintinline{text}|done| - & Présent avec la valeur \mintinline{json}|true| uniquement lorsque le contrôle de sécurité arrête les roues \\ - \bottomrule - \end{tabular} - } - \end{center} + \rowcolor{rowgray} + \mintinline{text}|done| + & Présent avec la valeur \mintinline{json}|true| uniquement lorsque le contrôle de sécurité arrête les roues \\ + \bottomrule + \end{tabular} + } + \end{center} \end{frame} \subsection{Interface utilisateur} \begin{frame}{IHM -- Terminal série} - \begin{itemize} - \item \textbf{Terminal} : interface en ligne de commande - \item Permet de communiquer avec le microcontrôleur via l'UART - \item Le Pico expose un \textbf{port série virtuel} \textit{via} USB - \begin{itemize} - \item Ex. : \texttt{/dev/ttyACM0} sous Linux - \end{itemize} - \item On peut envoyer des commandes et lire les réponses du microcontrôleur - \item On utilise \texttt{screen} ou \texttt{minicom} pour ouvrir un terminal série - \begin{itemize} - \item \texttt{screen /dev/ttyUSB0 115200} - \begin{itemize} - \item \texttt{Ctrl-A} puis \texttt{Ctrl-D} pour quitter \texttt{screen} - \end{itemize} - \item \texttt{minicom -D /dev/ttyUSB0 -b 115200} - \begin{itemize} - \item \texttt{Ctrl-A} puis \texttt{X} pour quitter \texttt{minicom} - \end{itemize} - \end{itemize} - \end{itemize} + \begin{itemize} + \item \textbf{Terminal} : interface en ligne de commande + \item Permet de communiquer avec le microcontrôleur via l'UART + \item Le Pico expose un \textbf{port série virtuel} \textit{via} USB + \begin{itemize} + \item Ex. : \texttt{/dev/ttyACM0} sous Linux + \end{itemize} + \item On peut envoyer des commandes et lire les réponses du microcontrôleur + \item On utilise \texttt{screen} ou \texttt{minicom} pour ouvrir un terminal série + \begin{itemize} + \item \texttt{screen /dev/ttyUSB0 115200} + \begin{itemize} + \item \texttt{Ctrl-A} puis \texttt{Ctrl-D} pour quitter \texttt{screen} + \end{itemize} + \item \texttt{minicom -D /dev/ttyUSB0 -b 115200} + \begin{itemize} + \item \texttt{Ctrl-A} puis \texttt{X} pour quitter \texttt{minicom} + \end{itemize} + \end{itemize} + \end{itemize} \end{frame} \begin{frame} - \begin{figure} - \centering - \includegraphics[width=0.7\linewidth]{img/ihm-terminal.png} - \end{figure} + \begin{figure} + \centering + \includegraphics[width=0.7\linewidth]{img/ihm-terminal.png} + \end{figure} \end{frame} \begin{frame} - \begin{figure} - \centering - \includegraphics[width=0.6\linewidth]{img/ihm-web.png} - \end{figure} + \begin{figure} + \centering + \includegraphics[width=0.6\linewidth]{img/ihm-web.png} + \end{figure} \end{frame} \begin{frame}{IHM -- Interface web} - \begin{alertblock}{Quelle différence ?} - \textit{Missions firmware} et \textit{missions téléphone} ? - \end{alertblock} + \TODO{JavaScript, Node, etc.} + + \TODO{programmation asynchrone} +\end{frame} + +\begin{frame}{IHM -- Interface web} + \begin{alertblock}{Quelle différence ?} + \textit{Missions firmware} et \textit{missions téléphone} ? + \end{alertblock} \end{frame} \subsection{Missions} \begin{frame}{Missions -- Interface de programmation du robot} - \begin{itemize} - \item \textbf{Protocole de commande} : envoyer des commandes JSON au robot et recevoir la télémétrie - \item \textbf{Interfaces de programmation} : - \begin{itemize} - \item fonctions C++ dans \texttt{Robot.h} pour piloter le robot "de l'intérieur" - \item fonctions JavaScript dans \texttt{robot.js} pour piloter le robot "depuis l'extérieur" - \end{itemize} - \item \textbf{Missions} : séquences de commandes à exécuter sur le robot - \end{itemize} + \begin{itemize} + \item \textbf{Protocole de commande} : envoyer des commandes JSON au robot et recevoir la télémétrie + \item \textbf{Interfaces de programmation} : + \begin{itemize} + \item fonctions C++ dans \texttt{Robot.h} pour piloter le robot "de l'intérieur" + \item fonctions JavaScript dans \texttt{robot.js} pour piloter le robot "depuis l'extérieur" + \end{itemize} + \item \textbf{Missions} : séquences de commandes à exécuter sur le robot + \end{itemize} \end{frame} \begin{frame}[fragile]{Missions -- Programmer des déplacements} - \begin{itemize} - \item \textbf{Objectif} : programmer une séquence de mouvements - \begin{itemize} - \item Avancer pendant 1 s, puis reculer pendant 1 s - \item Effectuer un quart de tour à gauche - \end{itemize} + \begin{itemize} + \item \textbf{Objectif} : programmer une séquence de mouvements + \begin{itemize} + \item Avancer pendant 1 s, puis reculer pendant 1 s + \item Effectuer un quart de tour à gauche + \end{itemize} - \item \textbf{Commande} : vitesse des roues gauche/droite et durée - \end{itemize} + \item \textbf{Commande} : vitesse des roues gauche/droite et durée + \end{itemize} - \begin{minted}[fontsize=\small]{json} + \begin{minted}[fontsize=\small]{json} {"left":200,"right":200,"duration":1000} \end{minted} - \begin{itemize} - \item \textbf{Enchaînement} : une nouvelle commande remplace la commande en cours - \begin{itemize} - \item Attendre la ligne \texttt{done:true} avant d'envoyer le mouvement suivant - \item Le champ \texttt{seq} renvoie le numéro de la dernière commande reçue : attendre un \texttt{done} dont le \texttt{seq} est $\geq$ à celui envoyé - \end{itemize} - \end{itemize} + \begin{itemize} + \item \textbf{Enchaînement} : une nouvelle commande remplace la commande en cours + \begin{itemize} + \item Attendre la ligne \texttt{done:true} avant d'envoyer le mouvement suivant + \item Le champ \texttt{seq} renvoie le numéro de la dernière commande reçue : attendre un \texttt{done} dont le \texttt{seq} est $\geq$ à celui envoyé + \end{itemize} + \end{itemize} \end{frame} \begin{frame}{Missions -- Deux architectures} - \begin{table} - \centering - \small - \begin{tabular}{L{3cm} L{4cm} L{4cm}} - \toprule - & \textbf{Téléphone (\texttt{robot.js})} - & \textbf{Robot (\texttt{Robot.h})} \\ - \midrule + \begin{table} + \centering + \small + \begin{tabular}{L{3cm} L{4cm} L{4cm}} + \toprule + & \textbf{Téléphone (\texttt{robot.js})} + & \textbf{Robot (\texttt{Robot.h})} \\ + \midrule - \rowcolor{rowgray} - \textbf{Exécution} - & Navigateur du téléphone - & Microcontrôleur Pico \\ + \rowcolor{rowgray} + \textbf{Exécution} + & Navigateur du téléphone + & Microcontrôleur Pico \\ - \textbf{Commandes} - & Envoyées successivement par HTTP - & Exécutées localement \\ + \textbf{Commandes} + & Envoyées successivement par HTTP + & Exécutées localement \\ - \rowcolor{rowgray} - \textbf{Synchronisation} - & Attente du message \texttt{done} - & Surveillance de l'horloge (\texttt{nowMs()}) \\ + \rowcolor{rowgray} + \textbf{Synchronisation} + & Attente du message \texttt{done} + & Surveillance de l'horloge (\texttt{nowMs()}) \\ - \textbf{Conséquence} - & Délais liés aux échanges réseau - & Enchaînement immédiat possible \\ + \textbf{Conséquence} + & Délais liés aux échanges réseau + & Enchaînement immédiat possible \\ - \bottomrule - \end{tabular} - \end{table} + \bottomrule + \end{tabular} + \end{table} - \vspace{0.3cm} + \vspace{0.3cm} - \begin{itemize} - \item \textbf{Téléphone} : l'API \texttt{Mission} automatise l'enchaînement des commandes. - \item \textbf{Robot} : la mission s'exécute dans \texttt{Robot::update()}, sans attente bloquante (\texttt{sleep\_ms()}). - \end{itemize} + \begin{itemize} + \item \textbf{Téléphone} : l'API \texttt{Mission} automatise l'enchaînement des commandes. + \item \textbf{Robot} : la mission s'exécute dans \texttt{Robot::update()}, sans attente bloquante (\texttt{sleep\_ms()}). + \end{itemize} \end{frame} \begin{frame}{Missions -- API et protocole de communication} - \centering + \centering - \begin{tikzpicture}[ - >=Latex, - block/.style={ - draw, - rounded corners=3pt, - fill=blue!5, - text width=3.2cm, - minimum height=3.4cm, - align=left, - inner sep=6pt, - font=\small - } - ] + \begin{tikzpicture}[ + >=Latex, + block/.style={ + draw, + rounded corners=3pt, + fill=blue!5, + text width=3.2cm, + minimum height=3.4cm, + align=left, + inner sep=6pt, + font=\small + } + ] - % Téléphone - \node[block] (js) at (-4,0) { - \textbf{Téléphone}\\ - \textit{Navigateur web}\\[0.3cm] + % Téléphone + \node[block] (js) at (-4,0) { + \textbf{Téléphone}\\ + \textit{Navigateur web}\\[0.3cm] - \textbf{API JavaScript}\\ - \texttt{robot.js}\\[0.2cm] + \textbf{API JavaScript}\\ + \texttt{robot.js}\\[0.2cm] - \footnotesize - \texttt{Robot} : commandes\\ - \texttt{Mission} : séquences - }; + \footnotesize + \texttt{Robot} : commandes\\ + \texttt{Mission} : séquences + }; - % Robot - \node[block] (cpp) at (4,0) { - \textbf{Robot}\\ - \textit{Raspberry Pi Pico}\\[0.3cm] + % Robot + \node[block] (cpp) at (4,0) { + \textbf{Robot}\\ + \textit{Raspberry Pi Pico}\\[0.3cm] - \textbf{API C++}\\ - \texttt{Robot.h}\\[0.2cm] + \textbf{API C++}\\ + \texttt{Robot.h}\\[0.2cm] - \footnotesize - \texttt{drive()} : moteurs\\ - \texttt{mission()} : séquences - }; + \footnotesize + \texttt{drive()} : moteurs\\ + \texttt{mission()} : séquences + }; - % Protocole - \node[align=center] at (0,2.3) { - \textbf{Protocole JSON}\\ - \scriptsize HTTP / Wi-Fi - }; + % Protocole + \node[align=center] at (0,2.3) { + \textbf{Protocole JSON}\\ + \scriptsize HTTP / Wi-Fi + }; - % Commandes - \draw[->, thick, blue] - ([yshift=0.7cm]js.east) -- - node[midway, above=4pt, align=center, - font=\scriptsize, text=blue] { - \textbf{Commandes}\\ - \texttt{\{"seq":42,...\}} - } - ([yshift=0.7cm]cpp.west); + % Commandes + \draw[->, thick, blue] + ([yshift=0.7cm]js.east) -- + node[midway, above=4pt, align=center, + font=\scriptsize, text=blue] { + \textbf{Commandes}\\ + \texttt{\{"seq":42,...\}} + } + ([yshift=0.7cm]cpp.west); - % Télémétrie - \draw[->, thick, ForestGreen] - ([yshift=-0.7cm]cpp.west) -- - node[midway, below=4pt, align=center, - font=\scriptsize, text=ForestGreen] { - \textbf{Télémétrie}\\ - \texttt{\{"seq":42,"done":true,...\}} - } - ([yshift=-0.7cm]js.east); + % Télémétrie + \draw[->, thick, ForestGreen] + ([yshift=-0.7cm]cpp.west) -- + node[midway, below=4pt, align=center, + font=\scriptsize, text=ForestGreen] { + \textbf{Télémétrie}\\ + \texttt{\{"seq":42,"done":true,...\}} + } + ([yshift=-0.7cm]js.east); - \end{tikzpicture} + \end{tikzpicture} - \vspace{0.4cm} + \vspace{0.4cm} - \begin{itemize} - \item \textbf{Deux possibilités} : séquencer les mouvements - depuis le téléphone ou directement sur le robot. - \end{itemize} + \begin{itemize} + \item \textbf{Deux possibilités} : séquencer les mouvements + depuis le téléphone ou directement sur le robot. + \end{itemize} \end{frame} \begin{frame}[fragile]{Missions -- Tourner de 90°} - \begin{itemize} - \item \textbf{Principe} : faire tourner les roues en sens opposés - \end{itemize} + \begin{itemize} + \item \textbf{Principe} : faire tourner les roues en sens opposés + \end{itemize} - \begin{minted}[fontsize=\small]{json} + \begin{minted}[fontsize=\small]{json} {"left":-180,"right":180,"duration":600} \end{minted} - \begin{itemize} - \item \textbf{Problème} : sans encodeur ni gyroscope, le robot ne mesure pas son angle de rotation. + \begin{itemize} + \item \textbf{Problème} : sans encodeur ni gyroscope, le robot ne mesure pas son angle de rotation. - \item \textbf{Solution} : calibrer la durée du mouvement - \begin{enumerate} - \item Effectuer un virage de durée connue - \item Mesurer l'angle obtenu - \item Ajuster la durée proportionnellement - \end{enumerate} - \end{itemize} + \item \textbf{Solution} : calibrer la durée du mouvement + \begin{enumerate} + \item Effectuer un virage de durée connue + \item Mesurer l'angle obtenu + \item Ajuster la durée proportionnellement + \end{enumerate} + \end{itemize} - \[ - t_{\text{nouveau}} = - t_{\text{ancien}} \times - \frac{90^\circ}{\theta_{\text{mesuré}}} - \] + \[ + t_{\text{nouveau}} = + t_{\text{ancien}} \times + \frac{90^\circ}{\theta_{\text{mesuré}}} + \] - \begin{itemize} - \item \textbf{Limite} : calibration dépendante de la vitesse, - du sol et du niveau de batterie. - \end{itemize} + \begin{itemize} + \item \textbf{Limite} : calibration dépendante de la vitesse, + du sol et du niveau de batterie. + \end{itemize} \end{frame} \subsection{Comportement autonome et contrôle} \begin{frame}{Un constat : le besoin de calibration} - \begin{itemize} - \item Les moteurs ne sont pas identiques - \item Les roues ne sont pas identiques - \item Le robot n'est pas parfaitement symétrique - \item Le sol n'est pas parfaitement plat - \item $\rightarrow$ Le robot ne se déplace pas \textit{exactement comme prévu} - \end{itemize} + \begin{itemize} + \item Les moteurs ne sont pas identiques + \item Les roues ne sont pas identiques + \item Le robot n'est pas parfaitement symétrique + \item Le sol n'est pas parfaitement plat + \item $\rightarrow$ Le robot ne se déplace pas \textit{exactement comme prévu} + \end{itemize} \end{frame} \begin{frame}{Comportement autonome -- Origines historiques} - \begin{columns} - \column{0.5\linewidth} - \begin{itemize} - \item Sans régulation : la machine peut \textbf{accélérer dangereusement} ou \textbf{ralentir} - \item Problèmes de sécurité et de fiabilité - \item $\rightarrow$ Comment stabiliser la vitesse des machines à vapeur (moulins, locomotives, etc.) ? - \end{itemize} - - \column{0.5\linewidth} - \begin{center} - \includegraphics[width=\columnwidth]{img/mulhouse_electropolis.jpg} - - {\footnotesize Machine à vapeur Sulzer et alternateur Brown Boveri (Electropolis, Mulhouse)} - \end{center} - \end{columns} -\end{frame} - -\begin{frame}{Comportement autonome -- Théorie du contrôle} - \begin{columns} - \column{0.3\linewidth} - \includegraphics[width=\columnwidth]{img/regulateur_huygens.jpg} - - \column{0.7\linewidth} - \begin{itemize} - \item Comment stabiliser la vitesse des machines à vapeur (moulins, locomotives, etc.) ? - \item \textbf{Régulateur à boules} pour machines à vapeur (James Watt \emoji{flag-scotland}) (XVIII~\textsuperscript{ème}) - \item Plus la machine accélère, plus les boules s'écartent, réduisant l'arrivée de vapeur $\rightarrow$ diminution de la vitesse - \item Initialement proposé par Christian Huygens \emoji{flag-netherlands} (XVII~\textsuperscript{ème}) - \item Principe purement mécanique - \item Limites : - \begin{itemize} - \item Réponse lente - \item Pas de correction d'erreur persistante - \item Pas d'anticipation des variations rapides - \item Pas adapté aux systèmes numériques ! - \end{itemize} - \end{itemize} - \end{columns} -\end{frame} - -\begin{frame}{Comportement autonome -- Théorie du contrôle} - \begin{columns} - \column{0.4\linewidth} - \begin{itemize} - \item \textbf{PID} : mis en équation en 1922 par Nicolas Minorsky \emoji{flag-russia} - \item Testé sur un cuirassé de l'US Navy, l'USS New Mexico - \item En pilotage automatique, en partant d'une erreur de 2 degrés, le navire a pu faire mieux qu'un barreur humain en maintenant son cap avec une précision d'1/3 de degré - \end{itemize} - - \column{0.6\linewidth} - \includegraphics[width=\columnwidth]{img/uss_new_mexico.jpg} - \end{columns} -\end{frame} - -\begin{frame}{Contrôle -- Fonctionnement du PID} - \begin{center} - \textit{Feedback loop} : stabiliser automatiquement des systèmes en s'appuyant sur les comportements passés - - \vspace{16px} - - \includegraphics[width=0.8\linewidth]{img/pid.png} - \end{center} -\end{frame} - -\begin{frame}{Contrôle -- Fonctionnement du PID} - Équation du PID en version discrète (pour une implantation numérique) : - - \begin{equation} - u[n] = K_p \cdot e[n] + K_i \cdot \sum_{k=0}^{n} e[k] + K_d \cdot (e[n] - e[n-1]) - \end{equation} -\end{frame} - -\begin{frame}{Contrôle -- Fonctionnement du PID} - Équation du PID en version discrète (pour une implantation numérique) : - - \begin{equation} - u[n] = K_p \cdot e[n] + K_i \cdot \sum_{k=0}^{n} e[k] + K_d \cdot (e[n] - e[n-1]) - \end{equation} - + \begin{columns} + \column{0.5\linewidth} \begin{itemize} - \item Composante $p$ : correction proportionnelle à l'erreur - \begin{itemize} - \item \emoji{cross-mark} Problème : erreur persistante $\rightarrow$ délai de correction très long - \end{itemize} - \item Composante $i$ : correction proportionnelle à la somme des erreurs précédentes - \begin{itemize} - \item \emoji{cross-mark} Problème : instabilité de la trajectoire $\rightarrow$ oscillations - \end{itemize} - \item Composante $d$ : correction prédictive basée sur la variation de l'erreur - \begin{itemize} - \item \emoji{check-mark} L'erreur augmente $\rightarrow$ on "accélère" la correction - \item \emoji{check-mark} L'erreur diminue $\rightarrow$ on "freine" la correction - \end{itemize} + \item Sans régulation : la machine peut \textbf{accélérer dangereusement} ou \textbf{ralentir} + \item Problèmes de sécurité et de fiabilité + \item $\rightarrow$ Comment stabiliser la vitesse des machines à vapeur (moulins, locomotives, etc.) ? \end{itemize} + + \column{0.5\linewidth} + \begin{center} + \includegraphics[width=\columnwidth]{img/mulhouse_electropolis.jpg} + + {\footnotesize Machine à vapeur Sulzer et alternateur Brown Boveri (Electropolis, Mulhouse)} + \end{center} + \end{columns} +\end{frame} + +\begin{frame}{Comportement autonome -- Théorie du contrôle} + \begin{columns} + \column{0.3\linewidth} + \includegraphics[width=\columnwidth]{img/regulateur_huygens.jpg} + + \column{0.7\linewidth} + \begin{itemize} + \item Comment stabiliser la vitesse des machines à vapeur (moulins, locomotives, etc.) ? + \item \textbf{Régulateur à boules} pour machines à vapeur (James Watt \emoji{flag-scotland}) (XVIII~\textsuperscript{ème}) + \item Plus la machine accélère, plus les boules s'écartent, réduisant l'arrivée de vapeur $\rightarrow$ diminution de la vitesse + \item Initialement proposé par Christian Huygens \emoji{flag-netherlands} (XVII~\textsuperscript{ème}) + \item Principe purement mécanique + \item Limites : + \begin{itemize} + \item Réponse lente + \item Pas de correction d'erreur persistante + \item Pas d'anticipation des variations rapides + \item Pas adapté aux systèmes numériques ! + \end{itemize} + \end{itemize} + \end{columns} +\end{frame} + +\begin{frame}{Comportement autonome -- Théorie du contrôle} + \begin{columns} + \column{0.4\linewidth} + \begin{itemize} + \item \textbf{PID} : mis en équation en 1922 par Nicolas Minorsky \emoji{flag-russia} + \item Testé sur un cuirassé de l'US Navy, l'USS New Mexico + \item En pilotage automatique, en partant d'une erreur de 2 degrés, le navire a pu faire mieux qu'un barreur humain en maintenant son cap avec une précision d'1/3 de degré + \end{itemize} + + \column{0.6\linewidth} + \includegraphics[width=\columnwidth]{img/uss_new_mexico.jpg} + \end{columns} +\end{frame} + +\begin{frame}{Contrôle -- Fonctionnement du PID} + \begin{center} + \textit{Feedback loop} : stabiliser automatiquement des systèmes en s'appuyant sur les comportements passés + + \vspace{16px} + + \includegraphics[width=0.8\linewidth]{img/pid.png} + \end{center} +\end{frame} + +\begin{frame}{Contrôle -- Fonctionnement du PID} + Équation du PID en version discrète (pour une implantation numérique) : + + \begin{equation} + u[n] = K_p \cdot e[n] + K_i \cdot \sum_{k=0}^{n} e[k] + K_d \cdot (e[n] - e[n-1]) + \end{equation} +\end{frame} + +\begin{frame}{Contrôle -- Fonctionnement du PID} + Équation du PID en version discrète (pour une implantation numérique) : + + \begin{equation} + u[n] = K_p \cdot e[n] + K_i \cdot \sum_{k=0}^{n} e[k] + K_d \cdot (e[n] - e[n-1]) + \end{equation} + + \begin{itemize} + \item Composante $p$ : correction proportionnelle à l'erreur + \begin{itemize} + \item \emoji{cross-mark} Problème : erreur persistante $\rightarrow$ délai de correction très long + \end{itemize} + \item Composante $i$ : correction proportionnelle à la somme des erreurs précédentes + \begin{itemize} + \item \emoji{cross-mark} Problème : instabilité de la trajectoire $\rightarrow$ oscillations + \end{itemize} + \item Composante $d$ : correction prédictive basée sur la variation de l'erreur + \begin{itemize} + \item \emoji{check-mark} L'erreur augmente $\rightarrow$ on "accélère" la correction + \item \emoji{check-mark} L'erreur diminue $\rightarrow$ on "freine" la correction + \end{itemize} + \end{itemize} \end{frame} \begin{frame}{Contrôle -- Objectifs du PID} - \begin{center} - { - \renewcommand{\arraystretch}{2} + \begin{center} + { + \renewcommand{\arraystretch}{2} - \begin{tabular}{C{0.45\textwidth} C{0.45\textwidth}} - \toprule - \textbf{Sans PID} & \textbf{Avec PID} \\ - \midrule + \begin{tabular}{C{0.45\textwidth} C{0.45\textwidth}} + \toprule + \textbf{Sans PID} & \textbf{Avec PID} \\ + \midrule - \rowcolor{rowgray} - \textcolor{BrickRed}{Réactions brutales} - & \textcolor{ForestGreen}{Réactions fluides} \\ + \rowcolor{rowgray} + \textcolor{BrickRed}{Réactions brutales} + & \textcolor{ForestGreen}{Réactions fluides} \\ - \textcolor{BrickRed}{Oscillations} - & \textcolor{ForestGreen}{Stabilité} \\ + \textcolor{BrickRed}{Oscillations} + & \textcolor{ForestGreen}{Stabilité} \\ - \rowcolor{rowgray} - \textcolor{BrickRed}{Dépassement} - & \textcolor{ForestGreen}{Précision} \\ + \rowcolor{rowgray} + \textcolor{BrickRed}{Dépassement} + & \textcolor{ForestGreen}{Précision} \\ - \bottomrule - \end{tabular} - } - \end{center} + \bottomrule + \end{tabular} + } + \end{center} \end{frame} \subsection{Calcul déporté} \begin{frame}{Calcul déporté -- Une affaire de compromis} + \begin{itemize} + \item Il est possible de réaliser une partie des calculs sur le PC qui commande le robot + \item Mais... + \end{itemize} + + \vspace{16px} + + \begin{exampleblock}{Avantages, inconvénients ?} \begin{itemize} - \item Il est possible de réaliser une partie des calculs sur le PC qui commande le robot - \item Mais... + \item Quels sont ici les \textbf{compromis} à réaliser ? + \item Comment appelle-t-on un tel système ? \end{itemize} - - \vspace{16px} - - \begin{exampleblock}{Avantages, inconvénients ?} - \begin{itemize} - \item Quels sont ici les \textbf{compromis} à réaliser ? - \item Comment appelle-t-on un tel système ? - \end{itemize} - \end{exampleblock} + \end{exampleblock} \end{frame} \begin{frame}{Calcul déporté -- Une affaire de compromis} - \begin{itemize} - \item Compromis techniques : - \begin{itemize} - \item \textbf{Temps de calcul} : PID simple adapté au Raspberry Pi Pico ? - \item \textbf{Mémoire} : quel historique des erreurs peut-on stocker ? - \item \textbf{Énergie} : gains avec le PID ? - \item \textbf{Latence} : calcul local = réponse rapide - \end{itemize} - \end{itemize} + \begin{itemize} + \item Compromis techniques : + \begin{itemize} + \item \textbf{Temps de calcul} : PID simple adapté au Raspberry Pi Pico ? + \item \textbf{Mémoire} : quel historique des erreurs peut-on stocker ? + \item \textbf{Énergie} : gains avec le PID ? + \item \textbf{Latence} : calcul local = réponse rapide + \end{itemize} + \end{itemize} \end{frame} \section{Présentation des TP} \begin{frame}{Organisation du dépôt} - \begin{itemize} - \item \texttt{robot/} : programme, drivers capteurs et actionneurs, sécurité - \begin{itemize} - \item \texttt{main.cpp} : boucle principale du robot - \item \texttt{Robot.h} : missions embarquées - \item \texttt{Config.h} : configuration matérielle - \end{itemize} - \item \texttt{robot/web/} : application web intégrée au firmware - \begin{itemize} - \item \texttt{index.html} : interface utilisateur - \item \texttt{robot.js} : envoi HTTP des commandes, lecture périodique de la télémétrie, exécution des séquences - \item \texttt{missions.js} : missions exécutées sur le téléphone - \end{itemize} - \item \texttt{schematics/} : schéma de câblage (Fritzing) - \end{itemize} + \begin{itemize} + \item \texttt{robot/} : programme, drivers capteurs et actionneurs, sécurité + \begin{itemize} + \item \texttt{main.cpp} : boucle principale du robot + \item \texttt{Robot.h} : missions embarquées + \item \texttt{Config.h} : configuration matérielle + \end{itemize} + \item \texttt{robot/web/} : application web intégrée au firmware + \begin{itemize} + \item \texttt{index.html} : interface utilisateur + \item \texttt{robot.js} : envoi HTTP des commandes, lecture périodique de la télémétrie, exécution des séquences + \item \texttt{missions.js} : missions exécutées sur le téléphone + \end{itemize} + \item \texttt{schematics/} : schéma de câblage (Fritzing) + \end{itemize} \end{frame} \begin{frame}{Deux liaisons, deux usages} - \begin{itemize} - \item \textbf{Ordinateur $\longleftrightarrow$ Pico (USB) :} - \begin{itemize} - \item chargement du programme - \item messages sur le port série - \item \textit{en mode série}, commandes et télémétrie échangées sur ce même port - \end{itemize} - \item \textbf{Téléphone $\longleftrightarrow$ Pico (WiFi) :} - \begin{itemize} - \item le Pico sert la page HTML - \item le navigateur du téléphone exécute le JavaScript - \item \textit{en mode WiFi}, commandes et télémétrie échangées en HTTP - \end{itemize} - \end{itemize} + \begin{itemize} + \item \textbf{Ordinateur $\longleftrightarrow$ Pico (USB) :} + \begin{itemize} + \item chargement du programme + \item messages sur le port série + \item \textit{en mode série}, commandes et télémétrie échangées sur ce même port + \end{itemize} + \item \textbf{Téléphone $\longleftrightarrow$ Pico (WiFi) :} + \begin{itemize} + \item le Pico sert la page HTML + \item le navigateur du téléphone exécute le JavaScript + \item \textit{en mode WiFi}, commandes et télémétrie échangées en HTTP + \end{itemize} + \end{itemize} - \begin{alertblock}{En pratique} - Le WiFi ne remplace pas complètement l'USB : toute modification du C++ \emph{ou de la page web} nécessite de recompiler et de recharger le Pico. - \end{alertblock} + \begin{alertblock}{En pratique} + Le WiFi ne remplace pas complètement l'USB : toute modification du C++ \emph{ou de la page web} nécessite de recompiler et de recharger le Pico. + \end{alertblock} \end{frame} \begin{frame}{Mission sur le Pico ou sur le téléphone ?} - \begin{columns}[T] - \column{0.5\linewidth} - \textbf{Mission sur le Pico} (\texttt{Robot.h}) + \begin{columns}[T] + \column{0.5\linewidth} + \textbf{Mission sur le Pico} (\texttt{Robot.h}) - \begin{itemize} - \item \Circled{1} Relevé capteur - \item \Circled{2} Décision dans la boucle du Pico - \item \Circled{3} Commande des moteurs - \end{itemize} + \begin{itemize} + \item \Circled{1} Relevé capteur + \item \Circled{2} Décision dans la boucle du Pico + \item \Circled{3} Commande des moteurs + \end{itemize} - \column{0.5\linewidth} - \textbf{Mission sur le téléphone} (\texttt{missions.js}) + \column{0.5\linewidth} + \textbf{Mission sur le téléphone} (\texttt{missions.js}) - \begin{itemize} - \item \Circled{1} Relevé capteur - \item \Circled{2} Télémétrie par WiFi - \item \Circled{3} Décision dans le navigateur - \item \Circled{4} Commande par WiFi - \item \Circled{5} Commande des moteurs - \end{itemize} - \end{columns} + \begin{itemize} + \item \Circled{1} Relevé capteur + \item \Circled{2} Télémétrie par WiFi + \item \Circled{3} Décision dans le navigateur + \item \Circled{4} Commande par WiFi + \item \Circled{5} Commande des moteurs + \end{itemize} + \end{columns} - \begin{alertblock}{En pratique} - Le trajet par le téléphone ajoute des délais et des risques de perte de communication. - \end{alertblock} + \begin{alertblock}{En pratique} + Le trajet par le téléphone ajoute des délais et des risques de perte de communication. + \end{alertblock} \end{frame} \begin{frame}{Progression des séances de TP} - \begin{center} - \begin{tabular}{@{}lp{0.30\textwidth}p{0.55\textwidth}@{}} - \toprule - \textbf{TP} & \textbf{Thème} & \textbf{Objectifs} \\ - \midrule + \begin{center} + \begin{tabular}{@{}lp{0.30\textwidth}p{0.55\textwidth}@{}} + \toprule + \textbf{TP} & \textbf{Thème} & \textbf{Objectifs} \\ + \midrule - \rowcolor{rowgray} - 1 & Découverte & Compiler, charger, piloter par USB puis WiFi \\ - 2 & Missions sur le téléphone & Programmer des mouvements depuis la page \\ - \rowcolor{rowgray} - 3 & Interface web & Commandes et mesures échangées en HTTP \\ - 4 & Deux boucles de décision & Comparer les distances d'arrêt robot / téléphone \\ - \rowcolor{rowgray} - 5 & Suivi de mur & Corriger la trajectoire sur le robot \\ - 6 & Correcteur PID & Atténuer les oscillations du suivi de mur \\ - \rowcolor{rowgray} - 7 & Mission autonome & Modéliser le robot comme un système à états \\ + \rowcolor{rowgray} + 1 & Découverte & Compiler, charger, piloter par USB puis WiFi \\ + 2 & Missions sur le téléphone & Programmer des mouvements depuis la page \\ + \rowcolor{rowgray} + 3 & Interface web & Commandes et mesures échangées en HTTP \\ + 4 & Deux boucles de décision & Comparer les distances d'arrêt robot / téléphone \\ + \rowcolor{rowgray} + 5 & Suivi de mur & Corriger la trajectoire sur le robot \\ + 6 & Correcteur PID & Atténuer les oscillations du suivi de mur \\ + \rowcolor{rowgray} + 7 & Mission autonome & Modéliser le robot comme un système à états \\ - \bottomrule - \end{tabular} - \end{center} + \bottomrule + \end{tabular} + \end{center} \end{frame} \appendix @@ -1944,69 +1942,69 @@ int main() { \section{Bibliographie} \begin{frame}[allowframebreaks]{Références} - \nocite{*} - \printbibliography[heading=none] + \nocite{*} + \printbibliography[heading=none] \end{frame} \section{API de programmation} \begin{frame}{Mission firmware ou mission téléphone} - \small - \begin{tabular}{@{}p{0.16\textwidth}p{0.36\textwidth}p{0.4\textwidth}@{}} - & \textbf{Firmware} & \textbf{Téléphone} \\ - \hline - Code & \texttt{Robot::mission()} & \texttt{Mission.run()}, configurée par \texttt{missions.js} \\ - Capteurs & mis à jour avant chaque appel & dernière télémétrie reçue \\ - Réaction & arrêt dans la même passe & télémétrie, puis requête, puis commande d'arrêt \\ - Perte de liaison & \texttt{enforceSafety()} arrête et annule & plus de commandes ; échéance et délai de liaison du robot \\ - \end{tabular} + \small + \begin{tabular}{@{}p{0.16\textwidth}p{0.36\textwidth}p{0.4\textwidth}@{}} + & \textbf{Firmware} & \textbf{Téléphone} \\ + \hline + Code & \texttt{Robot::mission()} & \texttt{Mission.run()}, configurée par \texttt{missions.js} \\ + Capteurs & mis à jour avant chaque appel & dernière télémétrie reçue \\ + Réaction & arrêt dans la même passe & télémétrie, puis requête, puis commande d'arrêt \\ + Perte de liaison & \texttt{enforceSafety()} arrête et annule & plus de commandes ; échéance et délai de liaison du robot \\ + \end{tabular} - \bigskip - Les deux passent par les mêmes commandes de déplacement et les mêmes contrôles de sécurité du firmware. + \bigskip + Les deux passent par les mêmes commandes de déplacement et les mêmes contrôles de sécurité du firmware. \end{frame} \subsection{API Robot.h} \begin{frame}{Boucle principale} - \texttt{Robot::update()} s'exécute à chaque passe, dans cet ordre : - \begin{enumerate} - \item mise à jour des capteurs ; - \item \texttt{readCommands()} ; - \item \texttt{mission()} ; - \item \texttt{enforceSafety()} ; - \item télémétrie ; - \item affichage. - \end{enumerate} + \texttt{Robot::update()} s'exécute à chaque passe, dans cet ordre : + \begin{enumerate} + \item mise à jour des capteurs ; + \item \texttt{readCommands()} ; + \item \texttt{mission()} ; + \item \texttt{enforceSafety()} ; + \item télémétrie ; + \item affichage. + \end{enumerate} - \bigskip - \alert{Rien de ce qu'elle appelle ne doit attendre} : une passe bloquée retarde aussi les contrôles d'échéance et de liaison. + \bigskip + \alert{Rien de ce qu'elle appelle ne doit attendre} : une passe bloquée retarde aussi les contrôles d'échéance et de liaison. \end{frame} \begin{frame}[fragile]{Se déplacer : \texttt{drive()}} - \begin{footnotesize} - \begin{verbatim} + \begin{footnotesize} + \begin{verbatim} void drive(int left, int right, uint32_t durationMs = DEFAULT_DURATION_MS); \end{verbatim} - \end{footnotesize} + \end{footnotesize} - \begin{itemize} - \item Fixe les deux vitesses, de $-255$ à $+255$, et arme une échéance. - \item \texttt{durationMs} est plafonnée à \texttt{MAX\_DURATION\_MS} (5000). - \item Chaque appel remplace le précédent : pour continuer, rappeler - \texttt{drive()} avant l'échéance. - \end{itemize} + \begin{itemize} + \item Fixe les deux vitesses, de $-255$ à $+255$, et arme une échéance. + \item \texttt{durationMs} est plafonnée à \texttt{MAX\_DURATION\_MS} (5000). + \item Chaque appel remplace le précédent : pour continuer, rappeler + \texttt{drive()} avant l'échéance. + \end{itemize} - \bigskip - \texttt{enforceSafety()} arrête les roues à l'échéance ou à la perte de liaison. - \begin{itemize} - \item \texttt{motors.stop()} arrête tout de suite. - \item Ne pas appeler \texttt{motors.set()} : un mouvement sans échéance est traité comme une faute et arrêté à la passe suivante. - \end{itemize} + \bigskip + \texttt{enforceSafety()} arrête les roues à l'échéance ou à la perte de liaison. + \begin{itemize} + \item \texttt{motors.stop()} arrête tout de suite. + \item Ne pas appeler \texttt{motors.set()} : un mouvement sans échéance est traité comme une faute et arrêté à la passe suivante. + \end{itemize} \end{frame} \begin{frame}[fragile]{Une mission firmware} - \begin{scriptsize} - \begin{verbatim} + \begin{scriptsize} + \begin{verbatim} static constexpr const char* MISSION_NAMES = "wiggle"; void mission() { @@ -2027,15 +2025,15 @@ void wiggle() { drive(_wiggleLeft ? -150 : 150, _wiggleLeft ? 150 : -150, 400); } \end{verbatim} - \end{scriptsize} + \end{scriptsize} - \small - Une mission rend la main à chaque appel, garde son état dans des membres, utilise \texttt{nowMs()} pour le temps et \texttt{drive()} pour bouger. + \small + Une mission rend la main à chaque appel, garde son état dans des membres, utilise \texttt{nowMs()} pour le temps et \texttt{drive()} pour bouger. \end{frame} \begin{frame}[fragile]{API \texttt{Robot.h} : une mission firmware} - \begin{scriptsize} - \begin{verbatim} + \begin{scriptsize} + \begin{verbatim} void wiggle() { if (nowMs() - _wiggleAt < 400) return; // pas encore _wiggleAt = nowMs(); @@ -2043,62 +2041,62 @@ void wiggle() { drive(_wiggleLeft ? -150 : 150, _wiggleLeft ? 150 : -150, 400); } \end{verbatim} - \end{scriptsize} + \end{scriptsize} - \begin{itemize} - \item \texttt{mission()} est appelée à chaque passe de la boucle et ne doit jamais attendre. - \item Une mission est donc une machine à états : \texttt{\_wiggleLeft} est l'état, \texttt{\_wiggleAt} la date de la dernière transition. Chaque appel change d'état ou rend la main. - \item \texttt{drive()} arme une échéance ; \texttt{enforceSafety()} arrête les roues quand elle passe. - \item Les capteurs sont lus avant chaque appel : la mission peut s'arrêter dans la même passe. - \end{itemize} + \begin{itemize} + \item \texttt{mission()} est appelée à chaque passe de la boucle et ne doit jamais attendre. + \item Une mission est donc une machine à états : \texttt{\_wiggleLeft} est l'état, \texttt{\_wiggleAt} la date de la dernière transition. Chaque appel change d'état ou rend la main. + \item \texttt{drive()} arme une échéance ; \texttt{enforceSafety()} arrête les roues quand elle passe. + \item Les capteurs sont lus avant chaque appel : la mission peut s'arrêter dans la même passe. + \end{itemize} \end{frame} \begin{frame}[fragile]{Capteurs et temps} - \texttt{front} (ultrasons) et \texttt{side} (VL53L1X, désactivé par défaut) sont mis à jour au début de chaque passe. - \begin{footnotesize} - \begin{verbatim} + \texttt{front} (ultrasons) et \texttt{side} (VL53L1X, désactivé par défaut) sont mis à jour au début de chaque passe. + \begin{footnotesize} + \begin{verbatim} if (front.valid() && front.distanceMm() < 200) { ... } \end{verbatim} - \end{footnotesize} - \begin{itemize} - \item \texttt{valid()} : la \textbf{dernière} mesure a réussi. - \item \texttt{distanceMm()} vaut $-1$ sauf si \texttt{valid()}. - \end{itemize} + \end{footnotesize} + \begin{itemize} + \item \texttt{valid()} : la \textbf{dernière} mesure a réussi. + \item \texttt{distanceMm()} vaut $-1$ sauf si \texttt{valid()}. + \end{itemize} - \bigskip - \texttt{nowMs()} repasse à zéro après environ 49 jours : - \begin{footnotesize} - \begin{verbatim} + \bigskip + \texttt{nowMs()} repasse à zéro après environ 49 jours : + \begin{footnotesize} + \begin{verbatim} if (nowMs() - startedAt > 1000) // juste : survit au passage à zéro if (nowMs() > startedAt + 1000) // faux : casse au passage à zéro \end{verbatim} - \end{footnotesize} + \end{footnotesize} \end{frame} \begin{frame}{Ajouter une commande} - \texttt{execute()} reçoit chaque commande analysée comme un - \texttt{JsonReader} : + \texttt{execute()} reçoit chaque commande analysée comme un + \texttt{JsonReader} : - \medskip - \begin{tabular}{@{}ll@{}} - \texttt{has(key)} & champ présent ? \texttt{null} vaut absent \\ - \texttt{integer(key, fallback = 0)} & le champ en \texttt{long} \\ - \texttt{boolean(key, fallback = false)} & le champ en \texttt{bool} \\ - \end{tabular} + \medskip + \begin{tabular}{@{}ll@{}} + \texttt{has(key)} & champ présent ? \texttt{null} vaut absent \\ + \texttt{integer(key, fallback = 0)} & le champ en \texttt{long} \\ + \texttt{boolean(key, fallback = false)} & le champ en \texttt{bool} \\ + \end{tabular} - \bigskip - \begin{itemize} - \item \texttt{has()} distingue un champ absent d'un zéro. - \item \texttt{execute()} ne doit pas attendre. - \item Pour répondre, suivre \texttt{sendInfo()} : remplir un \texttt{JsonWriter}, puis passer son \texttt{finish()} à \texttt{\_radio.send()}. - \end{itemize} + \bigskip + \begin{itemize} + \item \texttt{has()} distingue un champ absent d'un zéro. + \item \texttt{execute()} ne doit pas attendre. + \item Pour répondre, suivre \texttt{sendInfo()} : remplir un \texttt{JsonWriter}, puis passer son \texttt{finish()} à \texttt{\_radio.send()}. + \end{itemize} \end{frame} \subsection{API robot.js} \begin{frame}[fragile]{Le client \texttt{Robot}} - \begin{footnotesize} - \begin{verbatim} + \begin{footnotesize} + \begin{verbatim} import { Robot, Mission } from './robot.js'; const bot = new Robot(); @@ -2106,41 +2104,41 @@ bot.start(); // GET /api/lines toutes les 100 ms const seq = bot.forward(200, 1500); // POST /api/command, rend seq aussitôt await bot.waitUntilDone(seq); \end{verbatim} - \end{footnotesize} + \end{footnotesize} - \small - \begin{tabular}{@{}lp{0.6\textwidth}@{}} - \texttt{drive}, \texttt{forward}, \texttt{turnLeft}\ldots & envoient une commande, rendent son \texttt{seq} sans attendre \\ - \texttt{stop()}, \texttt{mission(n)}, \texttt{telemetry(ms)} & \texttt{\{stop\}}, \texttt{\{mission\}}, \texttt{\{telemetry\}} \\ - \texttt{last}, \texttt{info} & dernière télémétrie, dernière ligne \texttt{info} \\ - \texttt{connected} & le robot a répondu dans la dernière seconde \\ - \texttt{on(listener)} & appelé pour chaque ligne reçue \\ - \end{tabular} + \small + \begin{tabular}{@{}lp{0.6\textwidth}@{}} + \texttt{drive}, \texttt{forward}, \texttt{turnLeft}\ldots & envoient une commande, rendent son \texttt{seq} sans attendre \\ + \texttt{stop()}, \texttt{mission(n)}, \texttt{telemetry(ms)} & \texttt{\{stop\}}, \texttt{\{mission\}}, \texttt{\{telemetry\}} \\ + \texttt{last}, \texttt{info} & dernière télémétrie, dernière ligne \texttt{info} \\ + \texttt{connected} & le robot a répondu dans la dernière seconde \\ + \texttt{on(listener)} & appelé pour chaque ligne reçue \\ + \end{tabular} \end{frame} \begin{frame}[fragile]{Attendre le robot} - \begin{footnotesize} - \begin{verbatim} + \begin{footnotesize} + \begin{verbatim} waitUntil(test, timeoutMs = 10000, aborted = null) waitUntilDone(seq, timeoutMs = 6000, aborted = null) \end{verbatim} - \end{footnotesize} + \end{footnotesize} - \begin{itemize} - \item \texttt{waitUntil()} rend le premier message reçu après l'appel pour - lequel \texttt{test(message)} est vrai, ou \texttt{null} à - l'expiration ou si \texttt{aborted()} est vrai. - \item \texttt{waitUntilDone(seq)} attend une ligne \texttt{done} dont le - \texttt{seq} est \textbf{au moins} \texttt{seq} : une commande - suivante remplace l'étiquette. - \item Préférer \texttt{waitUntilDone()} à une attente de la durée - demandée : \texttt{ms} dit quand le robot a arrêté les roues. - \end{itemize} + \begin{itemize} + \item \texttt{waitUntil()} rend le premier message reçu après l'appel pour + lequel \texttt{test(message)} est vrai, ou \texttt{null} à + l'expiration ou si \texttt{aborted()} est vrai. + \item \texttt{waitUntilDone(seq)} attend une ligne \texttt{done} dont le + \texttt{seq} est \textbf{au moins} \texttt{seq} : une commande + suivante remplace l'étiquette. + \item Préférer \texttt{waitUntilDone()} à une attente de la durée + demandée : \texttt{ms} dit quand le robot a arrêté les roues. + \end{itemize} \end{frame} \begin{frame}[fragile]{Une mission téléphone : \texttt{Mission}} - \begin{footnotesize} - \begin{verbatim} + \begin{footnotesize} + \begin{verbatim} new Mission('carre') .forward(180, 1000) .turnRight(180, 600) @@ -2148,22 +2146,22 @@ new Mission('carre') .stopWhen((t) => t.front_ok && t.front_mm < 200, 'quelque chose devant') .run(bot); // -> { completed, stoppedAt, reason } \end{verbatim} - \end{footnotesize} + \end{footnotesize} - \begin{itemize} - \item \texttt{run()} règle la télémétrie à 100 ms, envoie chaque étape et - attend sa ligne \texttt{done}, au plus sa durée plus 2 s. - \item Elle s'arrête plus tôt si \texttt{stopWhen} est vrai, si - \texttt{aborted()} est vrai ou si une étape n'a pas de \texttt{done}. - \item Elle laisse toujours le robot arrêté. - \item \texttt{stopWhen()} teste la dernière télémétrie reçue, pas une - mesure en direct. - \end{itemize} + \begin{itemize} + \item \texttt{run()} règle la télémétrie à 100 ms, envoie chaque étape et + attend sa ligne \texttt{done}, au plus sa durée plus 2 s. + \item Elle s'arrête plus tôt si \texttt{stopWhen} est vrai, si + \texttt{aborted()} est vrai ou si une étape n'a pas de \texttt{done}. + \item Elle laisse toujours le robot arrêté. + \item \texttt{stopWhen()} teste la dernière télémétrie reçue, pas une + mesure en direct. + \end{itemize} \end{frame} \begin{frame}[fragile]{API \texttt{robot.js} : une mission téléphone} - \begin{scriptsize} - \begin{verbatim} + \begin{scriptsize} + \begin{verbatim} const bot = new Robot(); bot.start(); @@ -2174,14 +2172,14 @@ await new Mission('carre') .stopWhen((t) => t.front_ok && t.front_mm < 200, 'quelque chose devant') .run(bot); \end{verbatim} - \end{scriptsize} + \end{scriptsize} - \begin{itemize} - \item Chaque étape envoie une commande et attend sa ligne \texttt{done}. - \item \texttt{stopWhen()} teste la dernière télémétrie reçue : réagir - demande une requête, puis une commande d'arrêt. - \item Même commandes, même sécurité firmware qu'une mission firmware. - \end{itemize} + \begin{itemize} + \item Chaque étape envoie une commande et attend sa ligne \texttt{done}. + \item \texttt{stopWhen()} teste la dernière télémétrie reçue : réagir + demande une requête, puis une commande d'arrêt. + \item Même commandes, même sécurité firmware qu'une mission firmware. + \end{itemize} \end{frame} \end{document}