Ian is an engineer and maker from Ireland - he spends most of his spare time making things, filiming it for RU-vid or writing articles about it for his website.
Thanks for explaining this so well. I wish my control classes in uni showed explicitly how the theory is applied to real-world problems. After watching this, I feel I have a better intuitive understanding of PID control. God bless you!
HI! great video! But I don't understand how you pass the 'dt' value into the pid() function without using a additional parameter, like pid(error, dt); . Arduino manage the 'dt' as local or global variable ? Thanks!
@@careyian is there any way I can talk with you? I am using a different stepper motor driver which is specifically A4988 and my sensor is MPU6050 .. will your code work with this components?
@@filevillahermosa7167 you can message me here if you like: iancarey.ie/contact However, my code will not work with those components. The driver might work, as I believe they have the same pinout but I don’t know, I’ve never used one. As for the sensor, that’s a completely different type of sensor that I am using, so my code won’t directly work with it. You would have to modify it heavily.
I controlled the temperature in a greenhouse (90m*20m*6m) almost entirely on the derivative portion - the time constant of that volume of air required it.
No specific plans for right now, but I will take what I've learned to future projects! Thanks, it's not my dream workshop by any stretch, but you can get a lot done in it!
Hi, I don't know what you mean, could you elaborate? The values will probably be different if you set this up yourself and you will have to tune them yourself.
Ollo! I have a project in mind where the speed of the motor is generally more important than positioning (except for linear end points). I have a physical input device that sets motor speed at one of 8 speeds in either direction. Does it make sense to use PID to keep the speed consistent and to smooth the transitions from one speed to another? (I'm trying to improve on a standard control protocol that often leads to visible motion jerks) Very much a newbie so sorry if this doesn't make much sense!
Hi there, yes a PID controller will work well for speed control too. The only difference will be your feedback sensor will measure speed not position. Everything else will be pretty similar to what I talk about above.
Little bit of a delay in getting this one out, I have been very busy with my day job and I was also on holidays, but we are back! Hope you enjoy this one, it's only short but it's the latest view on my progress on the line following robot! More to come
This is an amazing content . i wish there was a quick way to calculate the pid values and tune them quickly since as an engineer you have dead lines to meet
Great point, real engineers can build actual models of these things and simulate different PID values, it’s never going to be 100%, there is a trade off of detailed models and the time it takes to build etc. There are also methods for tuning PID controllers. However, it might end up being faster to do it manually. You also have to think about if you are building a product, the base tuning might come from a model and simulation, you only need to build that once, then you can tweak and tune it afterwards.
Have you ever considered micromouse? I came across the UKMARS yt channel and am now hooked! I'll be building my own soon but thought it might be up your alley as well. I've watched your videos a lot, I like your problem solving style!
Fun fact: For keeping the state of active cells you can use a hash set of touples that represent coordinates. and then use a matcher to progress the game. It's incredibly fast.
I actually refactored my code since to use the tuples, it's much nicer! The string keys came from my previous experience building larger hash keys with more params while doing advent of code in Ruby. It can be handy to easily print for visually debug them. For this project, the tuple keys are much better.
This is awesome, I am teaching myself C++ and OpenGL and conway's game of life is my first project. I would love to learn Rust one day. Keep up the great content!
The optimization to only check live / neighboring dead cells is interesting, but depending on the state is short-lived, no? It's never removing entries, so a single glider going across the grid would end up leaving a ton of dead cells with no live neighbors in the HashMap. Is there also a reason you initialize to a default hashmap in main, then immediately reassign? It seems like `seed_grid` should just be the initializer, or take the `grid` as an `&mut` so you don't need to reassign the value
Oh yeah, there is no need to reassign after the initial, seed_grid can re assign it. As for your first observation, note at the start of the loop, we recreate a new empty grid each time and only then fill it with the next set of live cells and their adjacent dead ones.
@@careyian Ah, I totally forgot about the new_grid! Great optimization. Something about using Strings as keys for the coordinates still bothers me, for some reason. I wonder if a simple struct with two i32s would be more efficient? But this is all still very neat. You can probably use `std::mem::swap` on the two grids instead of cloning when you reassign. I'm imagining a 2nd iteration on this where you could either "move" the view of the grid (i.e. WASD and be able to follow a glider), or use the `print_area` to either have it wrap around or stop storing cells out of bounds
@@yigglesmoto I actually just did a few tweaks to the code there and published my Ruby example of doing it too. I actually realised I didn't need to clone, I think I had it in while debugging because I had some compiler error at some point, but it wasn't needed anyway. On the string keys, there probably is a better way, it's a pattern I have used tonnes while doing advent of code for creating hashing keys of many different params, so it's just the first thing that occured to me. That said, it works well in Ruby, but isn't as nice in Rust.
I have been crazy busy recently and haven't had as much time as I'd like to work on my projects. I plan to jump back into my recent robotics project soon, but this was a welcome for me to just code up something fun and I hope you guys learn something from it! Edit: Thanks for all the comments folks, between your comments here and some comments on Reddit I have refactored some of the code which you can see in the GitHub link in the description. The main thing I changed was swapping from string keys in the hash to tuple keys for the coords, it's much cleaner this way! The string keys came from my previous experience building larger hash keys with more params while doing advent of code in Ruby. It can be handy to easily print for visually debug them. For this project, the tuple keys are much better. I also added my Ruby solution there too. Thanks for the comments folks!!
That's a great explanation; however, I think we should consider making the PID gains more adaptive to enhance the code's generality and accuracy. Would this improvement be beneficial or will it add unnecessary overhead to the code?
@@careyian I mean if we can make a simple method that changes the gains within the runtime based on the time the system takes to reach its steady state. Therefore we will have a better gains for the next time.
@@careyian this is a drawing with pin markings where the boards will be connected to each other through wires. This makes it easier to navigate in which rem you need to connect the boards
Comment for the algo 🤖 This reminds me of a project we did back in college, except it was using Lego/Technic and a light sensor - had to build a robot that would go looking for lit candles and try to extinguish them 🔥 Looking forward to part 2!
Haha, class! That sounds like a fun project. This was actually inspired by a project I did in college to monitor and control the speed of a spinning disc. Strip of black tape on a white disc, read the pulses from an LDR. Then use a PID controller to match the speed to differing breaking forces on the disc.
PID have three values. "P" ,"I" and "D". It's very confusing when you call all of them "gain". I've watched it three times and still got confused what is what:/
Why 32k and not the 32.768k(?) one? Internal crystal for most the STM32's I've seen are already tuned for the inferior 32k clocks. And Do you mean to say that on the low speed pins, your original board had the wrong clocks at 16MHz? Finally, with such low volume, just get an active circuit, single clock oscillator. Dealing with caps and impedance tuning on such low volume made in china boards is just annoying at best and a waste of time at worst. Also if you fuck up and put the wrong speed, you can easily just pop off that oscillator and put the right one on. Regardless, doing your own board and messing up like 20 times really is the best way to learn.
Ahhh sorry, I’m just rounding it off when I say 32k, just easier to say than the decimals, I also keep forgetting what the decimal points are! Originally I had a 16Mhz resonator connected to the same pins, basically didn’t read the docs properly at all… You are also totally right about the external modules for this, this specific STM32 actually only even supports the HSE via one of those type of modules, so in future I’ll probably go with one of them if I come to need it. However, like you say, this was a great way to learn