We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Async Robots

00:00

Formal Metadata

Title
Async Robots
Title of Series
Number of Parts
141
Author
Contributors
License
CC Attribution - NonCommercial - ShareAlike 4.0 International:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
[EuroPython 2023 — South Hall 2B on 2023-07-19] https://ep2023.europython.eu/session/async-robots Interactive control of robots can be a challenge, as it requires a lot of things to happen in parallel while at the same time reacting to data from sensors and control signals. Using python's async facilities may greatly simplify this task, allowing us to write code that is similar to the non-parallel version, but that is at the same time easy to compose into bigger program doing many things at once. I will talk about my own experiences programming the Fluffbug robot with CircuitPython, point out the problems and the solutions I found. This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License http://creativecommons.org/licenses/by-nc-sa/4.0/
114
131
Address spaceGame theoryPresentation of a groupProjective planeBitVideoconferencingRoboticsSlide ruleVideo game consoleConnected spaceComputer animationLecture/ConferenceMeeting/Interview
RobotMereologySource codeKinematicsAssembly languageAlgorithmComputer programmingServer (computing)RoboticsMereologySlide ruleDigital electronicsWebsiteInverse elementPlastikkarteProper mapComputer animation
BitMusical ensembleRoboticsComputer animationLecture/Conference
RoboticsServer (computing)Presentation of a groupGastropod shellMereologyWhiteboardLecture/Conference
Point (geometry)BitComputer animation
BitRevision controlServer (computing)Presentation of a groupComputer animationLecture/ConferenceMeeting/Interview
Server (computing)BitBuildingLecture/Conference
Game theoryBuildingMereologyPoint (geometry)Computer programmingLecture/ConferenceMeeting/Interview
RobotSource codeMereologyKinematicsAssembly languageComputerGame controllerConsistencyUsabilityLoop (music)CodeWhiteboardFunctional (mathematics)Sound effectAdditionPresentation of a groupProgrammschleifeDifferent (Kate Ryan album)MathematicsTask (computing)Finite-state machineMultiplication signSpacetimeCASE <Informatik>RoboticsRepository (publishing)Computer multitaskingRevision controlMeasurementInheritance (object-oriented programming)ConsistencyProgrammer (hardware)Disk read-and-write headInfinityOpen set2 (number)Perspective (visual)BefehlsprozessorComputer programmingCodeDigital electronicsComa BerenicesOpen sourceRight angleBitGodComputer animation
Server (computing)AdditionWebsiteDigital electronicsPresentation of a groupTask (computing)Library (computing)BitInstance (computer science)RoboticsCoroutinePosition operatorWeightCodeLimit (category theory)Functional (mathematics)CodeChemical equationVirtualizationNeuroinformatikHydraulic jumpMultiplication signInverse elementWaveKinematicsProduct (business)Open sourceGodAngleAreaUniform resource locatoroutputSemiconductor memoryRight angleRemote procedure callParallel portProjective planeComputer animation
RobotAdvanced Encryption StandardType theoryRoboticsUtility softwareComputer programmingWeb browserInverse elementComputer fileProjective planeNeuroinformatikMultiplication signTask (computing)Buffer solutionLibrary (computing)MicrocontrollerComputer multitaskingoutputRight anglePower (physics)Pattern languageTable (information)Digital electronicsInstance (computer science)Scaling (geometry)Different (Kate Ryan album)Food energyCASE <Informatik>AlgorithmPhysical systemExpected valueCodeWaveKinematicsAxiom of choiceElectronic visual displayStreaming mediaSimilarity (geometry)Moving averageSoftware development kitDampingDecision theoryCuboidCrash (computing)MereologyCoefficient of determinationInternetworkingLogic gateField (computer science)Process (computing)Film editingData managementPresentation of a groupProduct (business)Operating systemRaw image formatConfiguration spaceBridging (networking)BitSoftware frameworkLecture/ConferenceMeeting/Interview
Transcript: English(auto-generated)
So if you saw me on some other presentations, you probably know that I built those Python-based game consoles. And during the COVID, I decided to take a break from that
a little bit. And since you are locked into your home, so what do you do? You start building killer robots, of course. So like any supervillain would do, right? So does this work?
It does. So I resurrected some of my super old projects and decided to simplify and make them a little bit more accessible for people to build. And I built, oh, we don't have slide. But is it possible to get the video on?
I have everything connected.
It worked in the morning.
OK. Thank you. Sorry about that. I promise I tested it in the morning, and it worked. OK. So this is the title of the presentation, and that's me.
If you need to contact me, the contact address is also there. I uploaded the slides on Discord into the right channel for the slides, so you can get them later. So this is the Fluff Pack Robot. And as you can see, it uses those very simple blue 9-gram
servers. It's very inexpensive, and the parts are very easy to get. And you program it with Circuit Python, so it should be very easy to program, because we already all know Python, right? So Python is easy.
And the main feature I focused on when building this robot is so that it will be complex enough to have inverse kinematics so that you can actually program correct walking algorithm, correct in the sense that it's not dragging its legs or like crawling on the floor,
but instead it's properly making steps. And the legs, once a leg is on the floor, it doesn't slip. I achieved that partially, because I wanted to make it cheap. I had to remove four servers from it,
so it only has eight servers, so two servers per leg. With that setup, it cannot turn without the legs slipping. But as long as it's walking forward, it's proper walk. The guy looks like this, and because you probably
can't see it from there, I came prepared, except, of course, I just disconnected that camera, so it no longer sees it. Sorry, a bit of technical problems.
Now you should see it. And of course, the technical problems continue.
I didn't charge it before. Sorry, but that's not a problem, because I brought more. So once I built this robot, I noticed, OK, those are the nice blue servers. They are nice and easy to get, and this
is the right size for a robot, because it fits on your desk. So it's easy to work on it, and you don't need a microscope to get into all the parts for it. But you know, I had in my drawer some of those smaller servers, the two-gram servers.
So I decided, OK, what if I did the same thing, but instead of the ESP32S2, as I used in here, I used the seats to do a show, the tiny boards that you saw in the previous presentation. And you know those tiny servers, so I made this little guy.
And hopefully, this one is charged. So the previous one is controlled through Wi-Fi,
so it has its own access point. This one is controlled with a remote. So you can see it's working properly. Maybe not. It's a bit dark in here, right?
Let me change this a little bit. Let's put it where the light is, and now you can see it, hopefully. Yeah.
You know, you put it in your room, and it scuttles somewhere, and then you never sleep again. Until you find it. So that's the tiny one. But I thought, OK, for the presentation, you know, the room is big. People from the back of the room
probably will not be able to see it. And there are those bigger servers out there. So I thought maybe, OK, I made the 50% version. Maybe I can make the 200% version.
So here it is. It's a bit slower than the tiny one, because the servers move a bit slower.
But it's still, I think, quite fun to build that. But you know, building is my favorite part of playing with it. But it's not all play and games. At some point, when you build it, you have to program it as well for it to do anything.
Since it likes very much that channel. So we will put it here. So let's talk about programming. We are at a programming conference, after all.
So they said, OK, I've built those robots. So what could be the excuse to show them on EuroPython? You know, we have to do some Python as well. So you can ask me to show you the robots later. And let's play with Python now.
By the way, there will be an open space tomorrow at 2 where you can come and we can play with those robots a little bit personally. So yeah, as I said, it's programmed with MicroPython. In particular, it's actually programmed
in a fork of MicroPython that's called CircuitPython. It's a friendly fork. So there is no animosity between the two teams. In fact, they make pull requests to each other's repositories as well. So it's a nice cooperation. Why there is a fork? It's because MicroPython is focused
on professional use of Python, on industrial use cases and so on. And sometimes that's not convenient for the other use of Python, which is for education and for beginners. So there was a need of a version of MicroPython
that would be more focused on learning and on ease of use. And that's why Adafruit, the company that made that fork, and the fork is still open source. It's not owned by Adafruit.
And actually, it's much easier to get your code merged into CircuitPython than into MicroPython. They are very happy to review your pull requests and so on. And they prioritize the ease of use and consistency. So if you have code written for one board,
we hear in the previous presentation that this is often a problem. You have code for one board. You want to use another board. You have to change some things. In CircuitPython, they made it so that the changes you have to do, if you have to do any, are minimal. So there are very small differences between,
mostly because they don't want to write tutorials for every board they sell. They just want to have one tutorial for everything. Anyways, blinking code. So this is a code in CircuitPython for blinking an LED. I'm removing everything that is obvious,
but that is not important. So there are imports, of course, before this code runs and so on. I'm just simplifying here for clarity. So you have a wire loop. You change the value of the LED to the opposite of that value,
and you wait half a second. Easy enough. But what if you want to blink two LEDs at the same time with different speeds? The obvious solution that every beginning programmer will try is something like this. But of course, this doesn't work, because the first loop never terminates.
So it will keep blinking the first LED and never get to blink the second one. So what you have to do is to completely turn the problem in your head 90 degrees and rewrite your program in a completely different way. You need to have a blink without sleep.
So basically, you have an infinite loop that doesn't wait anywhere, but that measures time. And whenever enough time has passed from the last blink of the LED, you blink the LED again. The time monotonic is just a value that tells you how much time has passed
since switching the device on, simplifying a little bit. And you just remember that time in the last variable. And then when that last time is further away than half a second, you blink an LED.
And then you can extend this like this to blink two LEDs. That's super easy, right? But what if we didn't want to do that? You know, this is a kind of mind-bending thing to have to rewrite your code like this. And you have to suddenly create state machines in your code.
And you know, it's complicated. That's why you can use async, in particular, async.io. If you define those two functions for blinking LEDs as async tasks.
Oh my god, I forgot the while loops in them. Imagine each of those functions has a while loop around them as well, because it won't work like this. Sorry. So there is a while loop in each of those. And you can run them with async.io at the same time.
But notice that instead of time.sleep, we are using async. Again, mistakes should be async.io.sleep. That also does the waiting. But it also has this additional side effect that while waiting in one function,
you are executing the other function. And then when the other function is waiting, it's executing your function, right? So they kind of cooperate to share the CPU time. That's why it's called cooperative multitasking.
And when you have a robot, like I just showed you, like this one, you basically need to walk forward. You need to do two things. You need to move your body forward. And moving your body forward, if you look at it from the perspective of the robot,
is basically moving all your legs backward like this. So that moves the body forward, assuming the tips of the legs stay on the floor where they were, right? So you have to do that. But sooner or later, you will run out of legs, right?
And you will face plant, basically. So the second thing you have to do is to make a step forward with one of the legs. Why one? Because with four legs, you can still stand on the floor in a stable way with one leg up, right?
Three legs are enough to support you in a stable way. So you make a step with one of the legs. And then when that step is done, you make a step with another leg and another leg and so on until you get back to the first one. And by that time, usually, they
move back enough for you to do that step. This is the code to do this. Again, I removed all the inputs. And I removed the code I already have there in the robot for calculating the angles of the servo, so the inverse kinematics stuff is removed for clarity.
But you can see that there is a function weight that also moves the legs backwards. And there is the main code that makes the step and periodically calls that function weight.
So this is my old code before I used async. When I rewrote this to async, I could do it in a more consistent way. So we have those two async function tasks that run in parallel. And I no longer am calling the weight from the step function.
They are completely independent from each other, right? But then once we have done this step, the two codes don't seem like much of an improvement.
But actually, it is because you can keep adding tasks. For instance, this guy here is controlled through Wi-Fi. That means it has an HTTP server running on it. And you can go on a website that displays you some buttons
and control it through those buttons. That means we need to run an HTTP server. We can do it easily in circuit Python. There is a right library for this. But we need to add a task that will call HTTP.pol regularly to make sure all the requests are handled, right?
It will do it in between of moving those servers. The small guy is controlled with a remote. There is another library for that. And again, the way it's implemented, we have a small library in C that actually
runs in the background and collects the signal from the remote sensor and caches them in the memory. And then we periodically call decoder.read to actually decode those signals and decide what to do. So as you can see, you can easily add more behaviors,
more functionality to your robot this way without having to rewrite your codes completely every time you need to add something. So where can we go from there? Right now, the robots only walk forward.
But we would like them to be able to wave at you or dance, jump. So that leads to task cancellation things or replacing one task with another task. You need to be aware what position the robot is right now
when you want to cancel this task because you might end up with a leg up. And then before you start dancing, you have to put that leg down on the floor. That takes time. That's an additional task you have to do. You have to make sure there are limits,
that you tilt your robot a little bit before you raise the leg, and things like that. So there is a huge amount of additional stuff you could add to that. For instance, balancing, as I said, you can tilt the robot to a side before you raise the leg to make sure you don't do face
palming, face planting thing. And if you introduce a virtual vehicle thing where you control not the robot itself, but the imagined position of the robot,
then it's easier to write all the controlling routines for you. So yeah, this is a very deep topic. I thought I will tell you everything about robots. But then I started to do research for my presentation.
And oh my god, this is an active area of research. We don't know how to program robots. We know how to program computers very well. We have been doing that for 100 years already. We still don't know how to program robots. So if you are interested in this, physical things that actually move when you change your code,
it's extremely satisfying. And I think this robot I built is a nice toy you could start with. It's all open source. You can build one like that yourself. And yeah, if there are any questions, I'm happy to answer them.
Otherwise, you can find me on, you can email me. You can find me on Adafruit's Discord or on the EuroPython Discord, of course. And there is the URL for the robot project if you want to build one like that. So questions. All right.
Thanks for the talk. Very entertaining. Now we open the floor for questions. And we have five minutes. And we have standing microphone. If you sit closer to the standing microphone,
you can go there. Otherwise, raise your hand. I'll give you the mic. Thank you. So I've been looking into PIOs for the Raspberry Pi Pico. And your talk makes me wonder if asyncio
could be used for some things instead of PIOs. So basically, how fast can it be? Is it nanoseconds, milliseconds, microseconds? So it's cooperative multitasking.
So it all depends what other tasks are running there. Because it can only switch between tasks when the other task says, you can switch now. Yeah, but in best case scenario. I never timed it. I mean, it's a very bad idea to expect any timing
guarantees from it. You shouldn't just expect timing guarantees. The only thing you can be sure of that eventually, you will get to run your code. So there is work ongoing in circuit pattern right now to make the PIO a wait table.
That means that you will be able to write some PIO code for the Raspberry Pi Pico and then await on it in your asyncio task. So for instance, to wait for data in the buffer to process it. And then that works very well.
Because PIO gives you this fast guaranteed timings thing. And then you can await on it to have this loose, no guarantees multitasking. Thank you. Any further questions?
Thank you. You built your own robot, and you used those libraries to move the parts of those robots.
Is it possible to buy a robot from somewhere and use those libraries to on the library that you buy? Yes, of course. There are some robot kits you can buy. For instance, there is an internet shop called Pololu
that sells robot kits. There are many more. If you go to Crowdsappley or Tindy.com, there are many hobbyist made robot kits that you can find.
So that's definitely possible. I don't know about many walking robots. There is one called the Petois, Petoi. I'm not sure how they pronounce it, because they are Chinese, not French. But they have two robots.
One is called Bittle, Bittle, Bittle. Let me look for it.
Right. So there is this similar walking dog robot. And you could also use the same MicroPython, CircuitPython libraries that I'm using. Problem is, of course, it has different leg configuration, as you can see. So you would have to modify the code to work for you.
But I think that's perfectly possible. And I know they write their own. I think it's called OpenCAD. They own libraries for controlling those robots.
They are not necessarily as easy to use, but should be one way of going there. Thank you. I have a question about different input devices. You mentioned that you can do commands over HTTP. Is it possible to have audio inputs into all of them?
So the way I mounted this microcontroller on the robot, you can actually put shields on top of it. So it's compatible with D1 mini shields. But you can also create your own one. And I have a whole box of different shields I made for it.
So this one is for a display that displays a face. But I also have one with a camera that you can actually stream through that web browser. I have one with a gesture sensor, where you can detect movement in front of the robot. So you can do different things depending
on how you wave your hands in front of it. And I have one with a distance sensor. So you can do obstacle avoidance algorithm with it. The problem is for all of those sensors, and I also have an alternate leg
that has a switch at the end. So you can tell when it's touching the ground or not. And the problem with all those is that you have to write the code to support them. Thank you. Any additional questions?
Thank you very much. So there's the... Oh, I'm sorry. You don't have to turn it back on. There's the ROS library or framework, the robot operating system written in Python.
I'm assuming it doesn't scale down to MicroPython or microcontrollers, but... There is something called ROS Micro, I think, or ROS Mini, which works in a way... It's a bridge, basically. You run it on your microcontroller, and it communicates over Wi-Fi or over Bluetooth
with a ROS instance that's running on a computer away from the robot. Right, right. So this way, you can use all the power of ROS and still only have a small microcontroller on your robot. Yeah, yeah. I was wondering if there were any utilities in ROS like for inverse kinematics or something for walking
that would help with... I'm sure, like, ROS is huge, and it has a lot of stuff already implemented. So I'm sure you can find inverse kinematics and walking probably several different gates for, like, robots, because, you know,
it's a huge thing that exists for years now, and people have been contributing to it for years. The thing is, I like to learn on simple things, so I didn't feel like learning ROS from scratch just to have my robots walk, so I just improvised.
I'm sure you made the right choice as a person who has tried to learn ROS, I suppose. I mean, ROS is a really, really huge thing, and if you are doing professional robotics, I highly recommend you go with ROS and don't roll your own algorithms for everything,
but, you know, for hobbyist stuff. Any questions?
Thank you for presentation. I'm also making a robot using a Python async. I'm using a Torrio asynchronous library. I use async for movement management,
decision making, behavior, and crashes management. I use async. We definitely need to compare notes. Sorry, please tell me why you choice Circuit Python.
Right, so the thing is, I like building things, but I don't enjoy coding them, programming them so much, so I have a lot of projects where I build them physically, and then I have no energy left to actually program them because programming is my day job, so it's boring.
So I decided to use Circuit Python for most of my projects now because it makes things easier. It makes it easier for me to start programming because it's, you know, I don't have to compile anything. I don't have to do as much research.
I can just sit down and create a Python file and type code into it, and that's it. So it's easier to me to force myself to actually do the programming for my projects this way. That's why I'm using Circuit Python,
and I know it's slower. I know it needs more resources, but at least the program, the project is working instead of waiting in the drawer for programming. So thank you, thank you. Well, this concludes our session.
Thank you for coming. Enjoying the rest of the conference. I'll see you then.