 So, if you saw me on some other presentations, you probably know that I built those like 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. 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. Is it possible to get the video on? I have everything connected. It worked in the morning. Okay. Thank you. Sorry about that. I promise I tested it in the morning and it worked. Okay. So this is the title of the presentation, and that's me. If you need to contact me there, contact address 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 Fluffback robot, and as you can see, it uses those very simple blue nine-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 sleep. 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 sleeping. But as long as it's walking forward, it's proper walk. And 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, right? And of course, the technical problems continue. I didn't charge it before that. Sorry, but that's not a problem because I brought more. So once I built this robot, I noticed, okay, 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, okay, what if I did the same thing? But instead of the ESP32S2, as I used in here, I used the Studio Show, the tiny boards that you saw in the previous presentation. And you know, those tiny servers, 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 walking 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, okay, 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 is, you know, those bigger servers out there. So I thought maybe, okay, 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. Seems it likes very much that chair. So we will put it here. So let's talk about programming. We are at a programming conference after all. So they said, okay, I've built those robots. So what could be the excuse to show them on EuroPython? 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, 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 a previous presentation that 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 and 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 variable, last time is further away than half a second you blink the 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, async tasks, oh, my God, I forgot the Y loops in them. Imagine each of those functions has a Y loop around them as well, because it won't work like this. Sorry, so there is a Y 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, mistake 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. 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 the step. This is the code to do this. Again, I removed all the imports and I removed the code. I already have in the robot for calculating the angles of the service. 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 wrote this to async, I could do it in a more consistent way. So we have those two async 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 once we have done this step, the two codes don't seem... This doesn'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 we'll call HTTP.Pole 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 the coder.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 you never that you tilt your robot a little bit before you rise 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 rise the leg to make sure you don't do face planting thing. And if you introduce a virtual vehicle thing where you control not the robot itself, but an 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 email me. You can find me on Adafruit Discord or on the Europe Python Discord, of course. And there is the URL for the robot project if you want to build one like that. So questions. Thanks for the talk. Very entertaining. Now we open the floor for questions. And we have five minutes. And we have standing microphone. If it sits closer to the standing microphone, you can go there. Otherwise, raise your hand. I'll give you the mic. Thank you. So I have 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 this 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. And the only thing you can be sure of that, eventually, you will get to run your code. So there is work ongoing in Circuit Patron right now to make the PIO awaitable. 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 timing thing. And then you can await on it to have this lose, no guarantees, multitasking. Thank you. Any further questions? Thank you. You built your own robot and you use those libraries to move the parts of those robots. Is it possible to buy a robot from somewhere and use those libraries 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 CrowdSupply or tindi.com, there are many hobbyists 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 petoi. I'm not sure how they pronounce it because they are Chinese, not French. But they have two robots. One is called Blitl. Blitl, let me look for it. Right. So there is this similar walking dog robot. And you could also use the same micro Python, circuit Python 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 input into the robot? Right. 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. 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 like obstacle avoidance algorithm with it. The problem is for all of those sensors, oh, 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, yeah. I'm sorry. You don't have to turn it back on. There's the Rust library or framework, the robot operating system written in Python. Right. It doesn't scale down to microfiber or microcontrollers, but... There is something called Rust Micro, I think, or Rust 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 Rust instance that's running on a computer away from the robot. Right, right. So this way you can use all the power of Rust and still only have a small microcontroller on your robot. Yeah, but I was wondering if there are any utilities in Rust like for inverse kinematics or something for walking that would help with... I'm sure, like, Rust is huge and it has a lot of stuff already implemented. So I'm sure you can find inverse kinematics and working probably several different gates for four-legged 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 Rust 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 Rust, I sympathize. I mean, Rust is a really, really huge thing and if you are doing professional robotics, I highly recommend you go with Rust and don't roll your own algorithms for everything. But, you know, for hobbyists, stuff. Any questions? Thank you for presentation. I'm also making a robot using Python Async. I'm using Torio, asynchronous library. I use Async for movement management, decision making, behavior, and crisis management. I use Async. We definitely need to compare notes. Sorry, please tell me why you chose Circuit Python. 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 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 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 there.