The Ultimate Guide to using Motors in Robotics (including ROS, Raspberry Pi)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so you want to build a robot you go out you pick up some motors a raspberry pi you've got some cool software maybe ross but then you go to put it all together and you pretty quickly realize that it's not so straightforward the good news is this is a problem we can solve fairly easily and we're going to solve it using an onion [Music] there's a saying that any problem can be solved with enough layers of abstraction and so just like an onion or an ogre that's what we're going to be doing with this problem we're going to treat it as a bunch of simple smaller layers of problems that together let us solve the bigger problem more easily in the first half of the video i'm going to be going through what those layers are the theory of it all so motor drivers controllers ross that sort of thing and then in the second half of the video i'll actually be wiring up a circuit that you can make for yourself at home now the concepts in this video are going to apply to pretty much any kind of motor and any kind of robot but for my particular example i'm going to be using brushed dc motors with encoders that are ultimately to be controlled using the ros2 control libraries if you're using brushless motors or stepper motors or different kinds of controllers then you might have to tweak things a little to suit your project also this isn't a video on what the different motor types are and how they work and how to choose them but if that's something that you'd like to see a video on down the track let us know in the comments so at the center of our onion we've got the motor without electricity though it's not going to do us much good and the easiest way to make it move for a brushed dc motor at least is to apply the appropriate supply voltage so that's our first layer here i've got a 12 volt dc gear motor connected to a 12 volt battery with a switch and sure enough when i turn it on the motor spins that's all very well but we've got no way to change the speed or direction and no way to control it remotely so the next layer that we're going to add is a motor driver part of the reason we can't just plug a motor straight into a pi or an arduino is that motors require a relatively high voltage and higher current compared to what the pins on these chips can handle instead we use a motor driver this little board takes a low voltage low current signal from some kind of controller and uses our power supply to amplify it creating a higher voltage higher current feed to drive the motors this signal is usually pwm a series of fast pulses that when you average them out over time the ratio of on time to off time called the duty cycle determines the percentage of the total voltage that a motor effectively sees basically the shorter the pulse is the slower the motor will go the longer the pulse is the faster the motor will go and if the pulse is on 100 of the time then the motor is going to be going full speed so here's that motor from before i've got it hooked up to a motor driver with some other circuitry off screen and i can make it go fast or slow or even backwards so that's our motor driver but now we need a way to generate that pwm input signal and for that we'll use a motor controller now let's just pause for a second and talk about terminology it's a bit vague but the way i use it a motor driver is a circuit that just blindly takes an input signal and amplifies it to send to the motor whereas a motor controller is a bit smarter its input is in a more practical format maybe a target speed or a target position and then it calculates the appropriate signal to send to the driver to get the motor to go the right speed sometimes both of these will be combined into one circuit especially you'll find this with brushless motors because they're a bit more complex or sometimes they'll even be all bound up in one unit with the motor itself like with a servo or a dynamixer conceptually though we're going to keep the driver and the controller separated the simplest kind of motor controller is an open loop controller this is where we have some kind of predefined map between our input signal and our output signal if the robot is ultimately being driven by a human this can be as simple as taking the operator's joystick signals and mapping zero percent to 0 and 100 to 100 but if we want to start getting a bit more automated we can try to come up with a function that maps our requested input speed in whatever unit maybe degrees per second to the appropriate pwm value and we can figure out what this function is by testing a bunch of input values measuring the speed we get out and fitting an equation to the result although this approach is really simple and it might be good enough for some applications it tends to fall down pretty quickly the appropriate speed to drive a signal function can change depending on a whole lot of factors the load that the robot's under the battery charge or even if the motor is going forwards versus backwards a human operator can naturally compensate for these with slight changes but if we want to do robust automation we really need to be able to command our motors to go an exact speed to achieve this we need a way to measure the actual speed of the motor live and feed that back into our controller so that we can adjust our input until we're getting the speed exactly right and this is called closed loop control or sometimes feedback control there are different kinds of closed loop control methodologies we're not going to go into them now the most popular one is called pid control i'll try and find a video and include a link to it but basically we look at how far we are away from where we want to be and adjust our signal accordingly so if we're really far away we make big changes if we're not very far away we make small changes and that's why the motors i've got have encoders on them as this little wheel on the back of the motor spins around it'll send a signal back to the controller that we can use to calculate the speed so whether it's open loop or closed loop off the shelf or custom built like we'll see in a minute our motor controller is able to take a target speed or sometimes a target position in a format that's good for us and it converts it into a signal for that driver and that way our robot controller in my case the raspberry pi is able to just send the speed that it wants and the motor will go that speed and it doesn't have to worry about all the low level details the motor controller takes care of that now you might be wondering can i just implement that kind of control straight on the raspberry pi itself and you can but i don't necessarily think you should there are two main reasons for that firstly it keeps the system more modular so imagine later on down the track you instead wanted to swap out your motors for something that has its own controller maybe like a dynamixer having done it this way lets us create a kind of a divide between these two parts and we can more easily separate that component switch it out maybe you want to switch out the raspberry pi itself for a different board and keep our motor controller the same secondly it means you never have to worry about other things on the pi interrupting the control system code you can imagine that maybe the camera code decides that it wants to hog the processor and all of a sudden your pid loop is taking 10 seconds to process and your motor's off doing something weird if your motor controller is on the same board as your robot controller maybe in a simpler robot it does make things easier but otherwise we're going to need a way to communicate we need some way for our main robot controller the raspberry pi in my case to transmit speed requests to the motor controller and then a way for the motor controller to potentially feed information back maybe speeds or positions or even currents or temperatures it'll vary depending on the controller but these comms will often be some kind of serial line maybe rs232 422 485 or sometimes something else like can i squared c even pwm in my case i've got a pie communicating to an arduino using serial over usb so the final stage is the overall control software for the robot and on any reasonably complex robot this is going to be running on some kind of onboard computer like a raspberry pi this software is going to need to do two different things firstly it's going to need to calculate the speeds that it wants the motors to go for its application and then secondly it's got to transmit those speeds using the appropriate protocol to the motor controller so i'm going to split these up into two separate conceptual components i'm going to call them the robot controller and the driver software not to be confused with the motor driver this could look a little bit different depending on your exact setup so maybe all of the code is in one program but the driver is a separate library that it loads or if you're using regular ros then maybe these are two different nodes that are communicating using topics or if you're using ros2 control then the controller will be a ros2 controller and the driver will be what they call a hardware interface which is like a separate library that it loads to communicate with the motors so this is the rough structure that we use pretty much whenever we're going to be using motors in robotics realistically it's not going to look the same for every situation sometimes you might have the motor driver and the motor controller on one board or you might choose to implement a motor controller and a robot controller on one processor to eliminate the need for a driver or you might be using different types of motors like steppers or brushless that work a little bit differently regardless it's probably going to fit this structure in some way having a diagram like this is great but we're going to learn a lot more by getting stuck in and building one for ourself so i'm about to make a demo circuit and i encourage you to go out get the parts and do it for yourself at home this video is actually part of a larger series where i'm going through how to build an autonomous robot from start to finish make sure you subscribe if you want more of that but for that project i'm eventually going to be using ros2 control i'll be using the diff drive controller that it comes with and i've written my own hardware interface which i'll make available on github for this video though i've just written a simple driver that uses regular ros so it's listening for speeds on a topic and then there's a graphical interface that you can use to request speeds it'll send them via serial and then it'll report the information back to the graphical interface here's a quick overview of the circuit i'm going to be building i've got two motors although we'll start by wiring up just one of them and they're connected to an l298n motor driver which is getting its power from a 3 cell lipo battery that is then connected to an arduino nano that's acting as our motor controller and we've got it also connected to the encoders of the motors so that we can get speed feedback for closed loop control then i've got a raspberry pi running a driver node in ros and it'll be communicating over serial over usb to the motor controller giving it the speeds and then instead of having the robot controller on board like we would have in a real robot for this demonstration i've just got another ros node that's going to run on my dev machine and it'll pop up with a little graphical interface that we can control the motors with and it'll be sending the data over ros topics over wi-fi so here's my motor it's a 12 volt dc gear motor and it came with a mounting bracket and a wheel but i'm not going to put the wheel on just yet because it's taller than the mounting bracket and so then i need a way to prop it up to stop it from spinning away on the table instead i've just stuck a piece of tape around the shaft that way it won't catch on the bench and it also makes it easier to see how fast the motor is spinning next up is the motor driver for my robot for this example i'll be using the popular l298n driver now honestly this is not a good motor driver it has a maximum of 2 amps of current per motor with 3 amp spikes and that's fine for these motors that have a 1.8 amp store current but you wouldn't want to be driving something much bigger also it's got a pretty decent voltage drop so even though we'll be putting in maybe 11 to 12 volts from our battery it's only going to be getting 9 to 10 volts out so our motor is going to be running at like maximum 3 4 speed however it does have one thing going for it and that is that it is very cheap let's take a closer look something useful to understand is that l298n refers to the actual chip that's doing all the hard work and this is just a popular board that this chip comes on that has some extra terminals and stuff to make it easier to use so we've got 12 volts in to power our motors we've got five volts in to power the chip itself and a common ground then we've got a pair of terminals on each side and these will supply power to our motors this little jumper here enables an onboard 5 volt regulator which i'm going to remove because i've got my own 5v power supply and i don't want them to conflict with each other this row of 6 pins here at the front is what we use to control the motors now normally you use the two outside ones to control the speed of each motor and then the other two pairs are used to control the direction and so when you want to control the speed you need to remove these two jumpers because they're currently tying those pins to five volts forcing the motor to go at full speed however the controller that i'm using actually expects these jumpers to be left on and it uses the other four pins to control both speed and direction so i'll be leaving them there so i've connected up the 12 volt to the pass-through voltage of our regulator you can check out the last video for more information on that i've got the motors power leads connected to the output terminals for motor 2. if you get them the wrong way around it just means that your motor is going to spin the other direction so you don't need to worry too much about the direction of them just yet then i've got two pairs of jumper wires coming out of the motor control pins and then finally i've left the five volt terminal empty and we'll see why in just a minute for the motor controller i'll be using an arduino specifically an arduino nano clone you could also use an arduino uno i'd like to redo the controller from scratch one day maybe with a different chip like the raspberry pi pico but the arduino works totally fine for now i had planned to power the arduino using the 5 volt pin and only use the usb for serial comms but instead i've decided to let it be powered over usb as well however if you remember from the last video i'm actually going to be connecting it to this powered usb hub and that way i'm going to minimize the amount of current that's being drawn from the raspberry pi then we can piggyback the 5 volts from the arduino into the motor driver and the ground is shared through the whole system back by the regulator then you want to run those other four wires from the driver pins to the arduino pins according to the diagram although i'd probably wait until you've uploaded the code first before you go ahead and plug it all in we've got the hardware for our motor controller mostly done apart from these four wires which are for our encoder we'll set that up soon but first we're going to upload the code to the arduino i'll be using a modified version of some code that i found online now i didn't write this code i'd like to rewrite it from scratch one day but in the meantime thanks heaps to the original authors for creating it you can download the code from my github and upload it using whatever method you like i just made a video on a couple of different ways to do it and the way that i think is best so you can go check that out i'll include a link in the description and unless your hardware is exactly the same as what i'm using then i recommend you read the readme file first just to check if you need to make any changes before you upload the code once the code is uploaded we can test if our serial comms works i'll be using a program called mini term and you can install that using the command up on the screen if you don't already have it assuming you've got serial access enabled on your pi then you can type mini term e for local echo then the serial port so for me so that slash dev slash tty usb0 and then the board rate so 57600 and so i can type e to check the current encoder values they're zero because we haven't plugged them in but then what i can do to check things are working so far i can type o 255 255 and this tells it to run both motors at full speed in open loop raw pwm mode and sure enough the motor spins around type 0 and 0 to stop it now because i've only got motor 2 plugged in i should be able to type o 0 70 and run just this motor at a slower speed and then i can also try a negative speed just to check that that works so let's go minus 150 and sure enough it spins backwards now that open loop control is working we want to implement closed loop control and remember from earlier that means we need speed feedback back from our motors to the controller we can solve this problem using encoders on the back of the motor here you can see there's this little black disc on your motor they might be covered up or there might not be one at all in which case you can buy them to install yourself but i recommend getting them pre-installed and then as the motor spins the magnetic field of the disk is going to go past these little hall effect sensors and they'll send a signal that goes up and down in pulses back to the controller i've put a bit of tape on mine so that you can see the spinning easier usually they'll just be all black and so for each revolution of this disk you're going to get the signal go up and down a certain number of times not heaps of times maybe like eight times per revolution for a cheap one maybe even over a hundred on a good one and that might not seem like a whole lot but you've got to remember that this is going through a gearbox and so each revolution here is going to be only a fraction of a revolution on this side and so for one revolution on this end you might be getting like 100 turns on the other end so if i spin this you can see that spinning many many times as to how the controller is able to convert these blips into a measured speed we're not going to go into too much detail if you want a video on how encoders work let us know in the comments i might make one down the track but basically it's able to convert these blips into a count that's going up and down as it turns and then by checking that counter regularly say 10 times a second and noting the difference in the counts we're able to calculate the motor's speed in counts per second then if we know how many counts there are in a full revolution we can convert that counts per second speed into rpm degrees per second radians per second whatever we like now for these particular encoders we've got four wires two of them are going to go to five volts and ground that'll give power to the encoder circuitry and then the other two are going to go to input pins on the arduino i'll put them up on the screen then going back to our serial terminal we can run the e command to read the encoder values now if they're not already zero then we can just press r to reset them and now we can turn the shaft in whatever direction was positive when we were doing open loop control before if you haven't got a wheel connected it can sometimes be a bit hard to turn and when we hit e we should see a positive number in the reading if it isn't then we just want to swap the the two wires that are going to the arduino reset with the r command and try again now to control it properly we're going to need to know our total counts per revolution of the output shaft we could figure this out by looking at the data sheet and multiplying the encoder counts per evolution by the gear ratio but i don't always trust the data sheets and for cheap motors like this you might not even have one the best way to do it is to just measure it ourselves empirically so we'll hit r again to reset the measurement and then we want to rotate the shaft a whole lot of times maybe 10 20 30 times and then we'll divide what the final count is by the number of times we rotated it to get the counts per revolution so we'll check the encoders they're zero i'm going to cheat by just running it in open loop control for a while and then i'll just finish this one up try to get it back to where i started i think it was about there so we'll check the encoders and we're reading 110 337 so i'll open up the calculator 110 337 divided by 32 revolutions and we get 34.48 so that means for each revolution of the output shaft we're getting 3404 counts i'll round that up to 3450 and so that means we can calculate the actual speed that it's going now that we can send a control signal to our motor driver and receive speed feedback from the motor that means we're ready for closed loop control but before we do that i'm just going to get a second motor wired up now the way that we tell this particular controller how to go is with number of encoder counts per pid loop it's a bit of a weird unit i'm not a huge fan of it but we'll just roll with it now the pid loop is set to run at 30 times per second so if we want to make motor one go at one revolution per second that's going to be 115 counts per loop so i'm just going to check that open loop control is still working and now let's try closed loop control so for that we use the m command so i'm going to type m 115 115 and we should see each motor turning at one revolution per second and we can try backwards as well let's go maybe half that oops now for my motors the default pid parameters are fine if you do need something different you can tune those parameters if you check out the readme in the code repo it explains how to do that so now that closed loop control is working we want a way that we can interact with it from a higher level for a simple robot you could do it all on an arduino but for anything more advanced you're going to want something with more grunt so for my robot i've got a raspberry pi on board connected to the arduino so i've got a little demo that we're going to run it comes with two ros nodes one of them is going to run on the raspberry pi and that will be listening for motor speeds on a topic and sending them to the controller and then there'll be another node that's a gui that will run on my development machine where i can send commands in a more user-friendly interface so i'm going to clone that repo into my workspace now we can source our workspace so on the pi we want to run the driver so we'll type ros2 run the package is serial motor demo and the node is driver now there are a few parameters we have to pass this so we'll type ros args we've got the serial port which is slash dev slash tty usb0 the board rate is 57 600 the loop rate is 30 and the encoder counts per revolution remember is 34.50 that error is okay so that driver is now listening on a topic waiting for me to send it some motor speeds which it'll then send down to the controller so we can now swap over to our dev machine and we can type ros2 run serial motor demo gui there's no parameters for this one and that'll bring up this little gui where we can control the motors so let's start by setting both motors to pwm about 130 in positive and yep that works so we can stop them let's try going negative and they go backwards we can swap to feedback mode closed loop control now we need to specify the maximum number of revolutions per second and i know that this motor can only do about 1.5 so we'll click that it'll update the sliders let's set motor 1 to go plus half a revolution per second and motor 2 to go backwards at half a revolution per second and you'll see they do exactly that so now we've got a circuit that lets us control the speed of two dc motors reasonably accurately from a raspberry pi and a road map on how we're going to be able to integrate that with ross2 control down the track in the meantime we can start adding some sensors to our robot so in the next video we'll be looking at lidar we'll go through how lidar works with ross how to simulate it in gazebo and then how to integrate the real hardware in our robot make sure you like and subscribe so that you don't miss out on that if you've got any other questions or comments or ideas let us know in the comments otherwise i'll see you next time [Music]
Info
Channel: Articulated Robotics
Views: 20,777
Rating: undefined out of 5
Keywords:
Id: -PCuDnpgiew
Channel Id: undefined
Length: 25min 56sec (1556 seconds)
Published: Thu May 19 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.