Detailed MPU6050 Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today on maker's wharf we'll learn how an mpu measures orientation hide jeff roberg's complex library behind a simple and easy to use interface fix jeff's flawed conversion from quaternion to yaw pitch and roll learn how to save calibration results to persist in memory so that you don't have to calibrate every time you power on overhaul the current animation procedure and finally create a test procedure how does one measure 3d orientation meaning yaw pitch and roll well for ya you could use a compass or magnometer however if you're also using say a brushless motor in your project that will create a magnetic field that'll interfere with the magnometer's measurement you could use a gps those measure course which is similar though not exactly the same as y'all but those have their own problems one of those problems is a low sampling rate meaning you'll need something to fill in the 200 millisecond gaps between readouts from your gps device the mpu6050 does that it also measures pitch and roll the question is how well the mpu6050 measures three linear accelerations called accelerometer readings and three angular accelerations called gyro readings the question is how does it get from these acceleration measurements to a measurement of 3d orientation note first that the mpu6050 performs local measurements sure it interacts with the outside world whenever it sends its results over to the microprocessor and sure it draws power from the outside battery however when it comes to the actual acceleration measurements themselves those are done entirely within the confines of the small mpu6050 module why am i belaboring this local aspect of measurement well because there's a very important principle in physics called the principle of equivalence that says that you cannot locally distinguish between the effects of gravity and acceleration meaning you cannot tell how much of your accelerometer reading is due to acceleration versus gravity but to the extent that you can ignore acceleration you can say that your accelerometer is measuring gravity meaning if we just rename the accelerometer and called it gravitometer we can say that acceleration of the gravitometer is the error in the gravitometer's measurement of gravity the question then becomes how does one get from a measurement of gravity to a measurement of 3d orientation here's how you're standing inside a small windowless container here on earth with a scale underneath your feet let's say someone on the outside pushes the container enough to tilt it the container floor tilts causing you to almost fall over but you stick your arm out to support yourself against the container wall by leaning on the container wall you've now relieved pressure off the scale that lies underneath your feet the more the elevator tilts the lower the reading on the scale will be in other words you can use the reduction in the scale reading to infer the tilt angle this must be how the mpu6050 measures through the orientation mystery solved well almost this trick and let's call it the gravitometer trick for future reference has two problems one is the acceleration error problem we spoke of just moments ago the other is the fact that it only works for two of the angles we need for 3d orientation it allows us to measure left right tilt which you can think of as roll and it allows us to measure back fourth field which you can think of as pitch but it doesn't work for the yaw angle if somebody rotated the container around its vertical axis you would not see any changes in the readings in the scale underneath your feet that's too bad is there some other trick we can use to get the yaw angle one of the readings from the mpu6050 is of course rotational acceleration around the vertical axis meaning the second derivative with respect to time of the yaw angle can we get from the second time derivative of something two to something well we can apply an antiderivative also known as an integral so it looks like we may have another trick now let's call this one the gyro integration trick for getting these orientations if you remember from your calculus class however we can only get the final or current values using this trick if we have the initial values including the initial value of the yaw angle for example so that's one limitation of this trick are there any other problems we should worry about using this gyro integration trick well there's one more if there's a bias error in the gyros measurement meaning let's say the gyro overestimates the angular acceleration by some constant amount then if you look at what that does to the integral you would see that it creates a term that gets magnified over time in summary this gyro integration trick is only going to be accurate over small intervals of time now by the way this gyro integration trick is performed for all three angles in an mpu not just the yar angle so these two detectors the gyro and accelerometer have opposite problems meaning the strength of one is the weakness of the other and vice versa they're complementary they go together like yin and yang like peanut butter and jelly you get the idea it turns out in engineering there are methods designed specifically for combining data from such detector pairs within the mpu-6050 module the temple if you will where this holy marriage occurs between the gyro and accelerometer is called the dmp so when we go to install an arduino library shortly we need to make sure to find one that reads directly from the dmp otherwise we're missing out on the whole point of using a detector like this one finally i will say that the yaw angle sort of got left out of the marriage here the gyro integration trick worked for all three angles but the gravitometer trick remember only worked for two of the angles it didn't work for the yaw angle not to fear though there are several potential suitors for marriage with the yaw angle remember our old friend the gps it measures coarse which is similar to yaw so the same way the gyro and accelerometer were fused together inside the mpu data from the mpu can then be fused with an external detector such as the gps or the magnetometer the mpu6050 is cheap tiny and accurate so if you know how to use one it's a wonderful thing when it actually works unfortunately when you go to buy one it's a flip of the coin whether you get one that works if you go on this website providing import export data and type in mpu gy521 gy521 by the way is the name of the breakout board for the mpu6050 you'll see that they all come from the same region for some reason bad modules are thoroughly mixed in upstream so it's unavoidable this is of course reflected in online reviews for all sellers if you look at the reviews for the top seller on amazon the first review you see is titled if you buy these test them before you install them the review clarifies that half the modules don't work and most of the reviews for this seller and other sellers look the same this is especially frustrating for new users because you never know if you're running into trouble because the board itself is bad or because you did something silly now you might say i'll just buy 10 of these and keep swapping them out to check to see if it's my fault or the manufacturers and if you scroll down to the review immediately below the one we just looked at you see a reviewer trying exactly this approach he's gone through seven modules already by the time he penned this review and each of the seven modules had one fault or another what makes this even worse is that if you look at his review you'll see different faults occurring at different points in the setup so he probably had to repeatedly swap out all seven modules at different points so this approach might not save you time and frustration after all but hold on is it really unavoidable can't we just have someone who is not a new user someone who knows enough about this board to say be making youtube tutorials about it buy a whole bunch of these test them one by one to separate the good from the bad and sell us only the good ones who me okay all right i'll do it look in the description box below for a purchase link any component you buy using one of the links below will have been thoroughly tested by me before i shut them out now the wiring diagram vcc goes to 5 volts scl on the mpu goes to scl on your arduino and sda on your mpu goes to sda on your arduino to find out where scl and sda pins are on your arduino please consult the following table the 80 pin allows you to select the i2c address for this module by setting it low you're choosing hexadecimal 68. by setting it high you're choosing hexadecimal 69. the library we're going to install will use hexadecimal 68 by default but allows you to connect using hexadecimal 69 by commenting out one line of code and uncommenting another interrupt pin on mpu is connected to digital eye open number two and arduino now many arduino users will use jumper wires and red boards to make these connections and this is a very easy and convenient way to prototype but it has one huge drawback and that's loose connections in fact loose connections are a heightened concern in our situation because we'll be moving the mpu around and rotating it into different orientations during testing because that's what the mpu does it measures orientation there are alternatives that help to mitigate or eliminate the chances of a loose connection if you're using a pcb like this one for example you eliminate the chance of a loose connection the drawback there is that you have to design it order it and wait for the company to fabricate it luckily i've designed and ordered pcbs that handle this connection and others and have them ready to ship to you if you wish to purchase from me this board right here connects to the following components an arduino mega 2560 pro an mpu6050 a microsd card reader rider an a6m gps device and an on off switch you can purchase it with all these components included and each component will have been thoroughly tested personally by me before they're sent out to you please see purchase links in the description section below [Music] now i recommend that we look for and install the mpu6050 library using the arduino ide so you fire it up and you go to tools manage libraries now we're going to search for mpu600 and we get a bunch of choices if you go through each of these choices you can click on more info on the first one for example and then search within the github for the keyword dmp and you can choose in this repository and you'll see this option doesn't make any mention of the dmp so it has failed our litmus test for our library if you perform this test for each of these libraries you will find that they all fail except for the one by electronic cats right here so if i hit on more info for this one and in the search bar again type dmp search in this repository you'll see that that it is in fact using the dmp and so this one passes we're going to choose this one you click install and the library is now installed before getting started with coding i want to briefly discuss development style and environment on this channel i will be using things like interfaces and dependency injection now you don't often come across these practices in the arduino community for a couple of reasons one is the misconception that interfaces introduce a significant performance cost this is simply not the case and if you're really concerned about memory constraints by the way i highly recommend using an arduino mega pro like this one you can use this board to program large ambitious projects without any problems the real reason you don't see these practices in the arduino community however is that it's a hobbyist community and hobbyists are typically newcomers and these modern design practices are very unfriendly to the newcomer's intuition we all start out with the intuition that the fewer intermediaries and classes in our code the simpler and better our code will be you actually have to work hard to disabuse yourself of this intuition we include these intermediaries called interfaces between different parts of our code because they allow for what's called loose coupling compare a flexible piece of wood in your mind to one that's completely rigid which one breaks more easily and you don't have to wait until you're working on large ambitious projects to finally fix this intuition i go over the logic for adopting these practices in excruciating detail in my video on dependency injection linked in the description box below finally there's development environment as you may know there are many choices here you can go with the good old arduino ide it's free it's very easy to set up and use however it doesn't offer much in the way of automation another very good choice is visual studio code the problem a lot of people have with visual studio code is that they're unable to get intelligence to stop issuing these warnings you know those red squiggly lines i have what i believe is the right solution to this which you can check in my video on configuring visual studio code for arduino linked in the top right corner and in the description section below with the intellisense problem out of the way visual studio code is an excellent choice however my problem is that i'm very greedy and i want to get as much automation out of my ide as possible to this end i'm keen on using visual studio community 2019 not to be confused with visual studio code in order to do so however i have to use an extension called v micro now right off the bat i want to say that i have no relationship with vmicro i don't know who they are they don't know who i am we have not been in communication they don't pay or sponsor me and unlike all the tools we've discussed so far vmicro is not free now with all this out of the way let's finally get started with some coding we're going to start by hiding this library's complexity behind a simple and easy to use interface for a more in-depth look at interfaces and how to make full use of them please check my video on dependency injection linked in the top right corner and in the description section below we'll fire up visual studio 2019 and we'll create a new arduino library project as defined by the v micro extension we'll call it impu the eye indicating that it's an interface we'll create this library in the arduino library subfolder so that we can go ahead and use it right away if you look at the impu.h file that v micro has automatically generated for us you'll see that we already have squiggly red lines from our intellisense if i'm going to live with intellisense errors i might as well be using notepad for development to get rid of them you have to open the project as a regular arduino project as opposed to an arduino library project so we have to close and get back in before closing though note that this header file is already somewhat cluttered for example it's using the if and diff syntax which takes up three lines of code to ensure that the header file is not included twice in new versions of c plus plus we can achieve the same effect with one line of code namely a pragma once command and there are other examples of unnecessary clutter in this file i'm sure this was all done with intentions of backwards compatibility but personally i prefer to let go of the past so that i can move gloriously into the future and since i have not committed yet to uploading this to github i'm really just writing this for myself and my viewers at this point so i'm going to just delete this header file i'll also delete the cpp file because interface classes should not have a corresponding cpp file the reason we didn't start by directly creating a regular arduino project by the way is that the library project option automatically generates for us the src subfolder as well as the library properties file which helps anyways now we're going to close out and start up again this time creating a regular arduino project we'll place it in the example subfolder because an arduino project is really just an arduino sketch and the first arduino sketch might as well be an example sketch to add an impu.h file we right click on the project and choose add now we're going to avoid choosing any of the v micro options at the bottom of the list because v micro tends to over clutter our files with backwards compatibility that we're not interested in so we're just going to choose class here we'll name our class impu the trick is to now click the three dots and very carefully choose to create these files in the src folder above our project folder now i don't have to browse to this location because i've chosen this folder in the past and visual city remember is my choice you on the other hand will need to browse to the src folder note also that there's some buggish behavior here by visual studio just because you see the path that you want doesn't mean that this is the path where the files will be created if you click the x or cancel buttons visual studio will create these files somewhere else you have to make sure to click the save button after browsing to the desired path you also need to remember to do this for both the header and cpp files as you can see the header file when created this way is far less cluttered than when using the vmicro automation note also that we don't need and include arduino.h statement in this file because this class is an interface you're also able to confirm in the file properties window in the bottom right that the file was created in the desired location now an interface is simply a class that lists all the methods that our users will interact with so naturally these will be public we will start out with a very simple interface that has only two methods an init method and a get yaw pitch roll method we will add more methods later when we need to create calibration functionality but for now this is it a quick look at the electronic cat's library reveals that it is not compatible with the interface class we created we're not going to modify the interface to ensure this compatibility because interface design has to be independent of implementation detail if you're not sure why please see my video on dependency injection linked in the description section below on the other hand we don't want to directly modify the electronic cats library folder because any changes there would be lost if and when we update that library so if we cannot modify the interface and we cannot modify the library then the only way to ensure compatibility is through an adapter that wraps around the library let's create this wrapper class now we'll call it wmpu the w indicating it's a wrapper class now the outside of the wrapper layer needs to match the inside of the interface layer the outside of a class is simply its method signatures meaning its method names input and output types the inside of a class is whatever you place inside its method definitions the interface class is special in that it doesn't have an inside remember we deleted the automatically generated cpp file for the interface where our method definitions would have been placed the interface is nothing more than method signatures so the outside of the wrapper class meaning its method signatures must match the interface method signatures we achieve this by having the wrapper class inherit the interface class when you inherit an interface class you promise to implement its method signatures visual studio helps you get started on fulfilling this promise with a nice automation it even gives us a peek at the function definitions is created for us in wmpu.cpp right now they're empty function definitions how should we populate them well matching the wrapper layer with the library trivially means that inside method definitions of the wrapper class we'll call library methods of course using library method signatures there's plenty of cost library methods in the dmp example sketch so let's start populating method definitions of our wrapper class by copying and pasting content from the dmp sketch the sketch starts with a bunch of include statements let's copy those into our wrapper class okay where should we place them wmpu.h or wmpu.cpp well if you chose wmpu.h then you've just fallen into one of this library's worst pitfalls to avoid being flooded with compiler errors we need to instead place them in wmpu.cpp i believe this is related to the ill-advised placement of function definitions in one of this library's header files to find out more about why one should not place function definitions and header files please see my video on c plus plus header files the setup function starts with some initializations let's copy these over to our init function definition emitting any serial commands along the way if the compiler warns that we're missing declarations we'll copy the necessary declarations it then uses calibration results perhaps previously obtained for another mpu6050 module as a guess for a starting point for the current calibration procedure we'll explain later why calibration results are referred to as offsets it waits for the user to send any character indicating that the module is lying still and flat before the calibration commences we're going to add calibration functionality to our wrapper class later for now however we do want to give ourselves the option to at least use the guess offset values as our calibration so we'll copy these set offset commands into a private guess offset method that we create on our wrapper class and we'll call it in our init method now we want to define our get yappie troll function we do this by grabbing the 3d orientations outputted by the dmp the dmp outputs these in what's called quaternion format so we'll need the conversion from this dmp's quaternion format to the more familiar format of the output chin role sounds easy enough just the conversion from one format to another yet this is where many aspiring mpu6050 users run into problems i think it's because you can more easily find conversions that are correct enough meaning they'll give you the correct results at most angles with the exception of two angles namely the north and south poles where you get what's called gimbal lock issues in fact if you scroll up to the comments section at the top of this dmp sketch by jeff roberg you'll see a warning about gimbal locks meaning he uses one of these incorrect but correct enough conversions i have the correct conversion so we'll use mine instead of this we'll borrow some of jeff roberg's code here that lets us read the quaternion from the dmp but we'll take care of the rest ourselves here's the correct transformation from this dnp's quaternion as obtained by jeff's library to your picture and role as defined by the wikipedia page on aircraft principal axes finally we want to use degrees instead of radians so we have to remember to convert we've put together quite a bit of code here it'd be nice if we could run a test to see that it works this is the purpose of our first example sketch which we fittingly called runtest.ino now we'll want to only use the interface class in the sketch when interacting with our mpu we don't want any mention of the wrapper class or any of the installed library classes here let's quickly remind ourselves of the reason why think of our sketches and our classes as parts of our code these parts interact with each other and the number of interactions grows quadratically with the number of parts so to keep development tractable as our code grows we need to avoid having to rewrite the interaction terms if you will whenever a part is modified or swapped out this is why we create interface classes by a making sure that the parts only interact through interfaces and b making sure that the interfaces are independent of implementation detail we have much more robust software that is easier to maintain we fulfilled condition b when we deleted the interface's cpp file to fulfill condition a we have to avoid mentioning the wrapper or installed library classes in our sketch but we cannot simply declare an impu variable c plus does not allow us to instantiate interface classes we can only create impu pointers or references to other objects that are not interfaces so the way to solve this problem is to write a function that returns an input reference to an instance of the wrapper class we'll call this function in our sketch but we'll define it outside our sketch specifically we'll define it as a method of a config class which we'll call sample config we'll need to then include the header file for this sample config class in our sketch in a real world project we'll have to create our own config class where we'll choose what specific class implementation gets returned for each interface think of our wrapper class as one choice of implementation of the mpu interface we may have more if we're experimenting with different mpu libraries or different versions of the same mpu library our project's config class will likely have other methods returning implementation choices for other interfaces for example a gps interface or an electronic speed controller interface etc our sample config class just serves as a guide let's create it so that we get rid of these intellisense errors let's add a comment reminding users to create their own config class this sample config class is just a guide in setup let's begin cereal and let's initialize our mpu in the loop section let's call our get your patrol method and finally let's bring our results to cereal all right let's run it to see if it works now we can run it using the v micro extension in visual city here but let's just run it using the arduino ide for now great it's running so we see numbers printing out that's a good sign if i move it now i see that the numbers are changing so great so the first test is a success we've now confirmed that the simple and easy to use interface we built around the mpu library runs it's still missing calibration functionality though let's create this functionality now so what does it mean to calibrate a sensor well ideally we want our reading to equal the actual value being measured so if we graph our reading as a function of the actual values we want the graph to be a line that goes through the origin at a 45 degree angle with the horizontal axis in other words the blue line instead in the real world our raw readings as a function of actual values will look more like the red line let's define the origin as the actual value when the mpu is lying flat and still by adding or subtracting a constant called an offset to the reading we can make it match the actual value at the origin this is called offset calibration the other part we often have to worry about is correcting the slope of the raw readings as a function of actual values meaning the slope of the red line this is called gain calibration it turns out in our case that we can get accurate results by only performing offset calibration and without having to worry about gain calibration so when we say calibration going forward we simply mean offset calibration now the graph shown is for a single sensor remember that our mpu6050 has six readings three linear accelerations and three angular accelerations so calibration will involve obtaining six offsets there's an important feature we'd like to have in our calibration function not offered by the library we installed rather than have to calibrate the mpu every time we power on arduino we want to perform the calibration only once and have the results of that one calibration saved to persistent memory and pull that result from that persistent memory every time we power on arduino in the future does arduino have memory that persists after turning off and back on yes it's called eeprom now it's likely that in any given project we may need to store values in eeprom from multiple classes or sensors and we want to make sure that one class does not override values written by another to mitigate this problem we want all the decisions made regarding which value from which class or sensor is stored in which location in eeprom we want all of those decisions to be made in one place in our code this way to check that there aren't any conflicts we just have to visit this one place as opposed to having to track down different parts of our code where these write operations are made we'll call this one place where these decisions are made the eeprom manager class also as you might have guessed our wmpu class will interact with eeprom manager through an interface we'll call ieee prom mpu so let's start creating ieee prom npu it's an interface so we won't need the cpp file how will our mpu class interact with eeprom manager by asking it to write and read calibration offsets to and from eeprom so the interface will list the following method signatures we'd like to also be able to write and read a flag indicating whether valid calibration offsets have been saved and to be able to reset this flag if for whatever reason we lose confidence in the offsets saved the class that will implement ieee prom mpu is of course the ee prom manager so let's create that now remember this is where all decisions are made regarding where each value from each sensor including the mpu is stored for the mpu we'll need to store offset values and a calibration flag we'll use an enum to express where each offset will be stored on eeprom one important point to note here is that each location on eeprom is one byte an integer is two bytes so if we're storing the offsets as integers we need to make sure to space them out on eeprom so that they don't overlap this is why you see values in the enum skipping one as they go from two to four to six to eight to ten to twelve we'll use a constant integer for the location of our calibration flag on eeprom and we'll call it calibflag address if this flag stores an integer value of 77 it tells us that valid offsets are stored a value of 0 on the other hand indicates that no valid offsets are stored we can save ourselves a lot of typing by using visual studio automation to help us implement the methods of ieprom mpu each of the methods we just added either writes or reads an integer value to or from eeprom so let's create a couple of private helper functions to perform this basic task to read the bytes themselves we use the eeprom library that comes along by default with the arduino ide however for me to convince visual studio to recognize this library i have to take a couple of extra steps i have to add this library's header file to my project and add the path to this libraries folder to my c plus bus configuration if you're not using visual studio you don't have to worry about taking these two steps now we can use these helper methods to fill out the remaining method definitions we'll use the enum and constant integers that we defined earlier for the offsets and calibration flag as input arguments for our helper functions this takes care of eeprom manager and its interface let's now update impu and wmpu to reflect the fact that we're adding calibration functionality that includes this feature of being able to save offsets to eeprom we want wmpu to interact with the eeprom manager only through the ieee prom mpu interface we can achieve this by passing an instance of the manager class to the wmpu constructor however we'll pass it in as an ie prime mpe reference this way we'll avoid any mention of the manager class in wmpu we'll then use this past reference to set the private member that we just declared here now there's only three things you can do with our mpu class you're either using it calibrating it or resetting it if you're resetting it you just call the reset calib flag method invalidating any previously stored calibration results if you're calibrating it you simply make sure it's lying flat and still before calling its calibrate method that's it nothing else if you're using it on the other hand you have to make two calls one to the neat method which runs some initializations and loads previously stored calibration results and then you have to call the get your patrol method some initializations are common to both the calibrating and using scenarios meaning they're performed both at the beginning of the calibrate method and in the init method but we don't want to have to write these out twice so we'll place them in a private method called begin note that we're using a member initializer list to set the private member eeprom manager for more information about initializer lists please see my video on class constructors in c plus if anything goes wrong during the initializations in the begin method that we just mentioned earlier then we want to halt execution as we marked earlier the init method will load previously stored calibration results if they exist and are valid what does it mean to load calibration results well it's a two-step process the first is to grab offsets from eeprom using our eeprom manager reference the second is to set these as the active offsets which is handled by methods from jeff roberto's library we'll use calibrate methods from jeff roberg's library to perform the actual calibration these automatically obtain the offsets and set them active we then grab these offsets using methods from jeff's library and store them in eeprom using our eeprom manager reference as mentioned earlier we plan on passing an instance of the eeprom manager class to the wnpu constructor so let's go now to our conflict class where we currently call wnpu's constructor and modify it accordingly it's time to start creating new example sketches that test our new functionality start with reset calib flag.ino before we create and run it though let's add a serial command at the end of our reset caliber flag method to let us know it completed the run this new example sketch will look exactly like runtestorano only simpler let's save and run it to see what we get a serial message telling us the reset is complete great now let's see what happens if we run runtest.ino we get a serial message informing us that the mpu is not calibrated and that execution has been halted excellent next is the calibration example sketch all we do is replace the reset color flag method call by the calibrate method call and we have our calibrate.ino example sketch let's save and run great and now that it's calibrated when we run runtest.ino it runs without a problem now that we've finished adding functionality to our mpu class we want to test it to see that it's working correctly there's two ways to do this we can create a real-time animation of its outputted 3d rotations to see if they match with the reality think of this as the visual component of our test and we can also directly check the numbers themselves which you can think of as the quantitative part of our test it so happens that the dnp sketch that jeff roberg's library provides has an option for animation it sends data over serial to another software called processing.exe that then creates the animation using a library called toxic libs i'm not sure the official download page is still alive for toxic libs regardless though i really think that this entire animation process is in need of an overhaul at this point instead of sending data to processing.exe and toxic libs we're going to send it to v python our runtest.ino sketch right now is already sending the opportune data over serial the only modification we need to make to it is to add 100 millisecond delay to the loop so that we're not jamming the data into python let's create a python project in visual studio that will grab this data and create the animation we launch visual studio and type python in the search box if you've installed the python development workload in the past you'll see a python application option if not it'll come up empty with the option to install more tools you can then check the python development checkbox to install it i have it installed already so i'll back up at this point we'll place our new python application in the example sketch folder for runtest.ino we'll start by typing in the command for importing the v python library most likely in your case you have not yet installed v python so you'll see red squiggly lines head over to the solution explorer and expand python environments right click the entry underneath it and open interactive window my case if i scroll down i'll see that i already have the python i also have another library we're going to need to connect over serial called py serial but you likely will have neither of these to install them you can just type v python in the search box and you'll see the option to run command pip install v python click that option once that's done installing go back to the search box and type in py serial and choose to run the command pip install py serial let's finish up our import statements we'll start by creating the stuff that's not affected by rotations things like the title background color dimensions and so on we'll do this in a function fittingly called set scene next we want to display the numeric values of our three angles yaw pitch and roll this display will not rotate but we'll need to update the values displayed in real time as the mpu is rotated next we'll create the objects that actually rotate this includes of course the mpu board itself it also includes the labels on this board we have the x-axis label y-axis and the label indicating which side is up we want to also create those curved arrows we saw in wikipedia's illustration of aircraft axes of rotation these will help us check that the angles outputted by our mpu class increase and decrease in accordance with the convention set out by that illustration now the same procedure is used to construct each of these curved arrows so rather than rewrite code we'll place the procedure inside a helper function called rotation info finally we'll combine all these objects together and return them as a compound object let's define that rotation info function recall just now it'll take as input the ring's position vector which also serves to define the axis of rotation the arrow itself will be offset from the ring center and this offset is also passed in as an input argument to this function finally the function takes in the name of the angle which will be either real pitch or roll we'll then use these inputs to create the ring which you can think of as the curved portion of the arrow then the arrow which you can think of as the straight part and finally the angle name next we'll use the py serial library to create the serial object i have my arduino connected on com9 you'll have to change this com9 string literal to match whatever port your arduino is connected on we want to continually update our object's orientation so we'll place the update code in a while true loop also data might not be available at first and we want to keep trying to update until it's there so we'll wrap our update code in a try statement we'll start by reading in the data from serial and parsing out the yaw pitch and roll values we have to include a race statement here this tells v python the update grade now we'll use these freshly obtained yaw pitch and roll values to update the numeric values displayed in our figure next we'll convert these freshly obtained angles from degrees to radians because python likes radians now these freshly obtained yaw pitch and roll values only tell us the orientation relative to an initial orientation defined at zero yappa channel we'll stipulate that at zero yaw pitch and roll the x and y axes of the mpu point in the following directions all we have to do now to obtain the fresh orientation is to apply the yaw pitch and roll rotations in sequence to this initial pair of vectors x and y let's start with the yar rotation we know what the starting directions are we know the axis of rotation and we know the angle and radius in a situation like this we can use what's called the rodriguez formula to perform the yaw rotation on both the x and y vectors we'll use this formula to define our rodriguez rotation function which again takes in an initial vector and acts as a rotation and an angle and radians as inputs next is the pitch rotation note however that the x-axis is invaried under pitch rotation so we only need to apply the rodriguez pitch rotation to the y vector similarly the y axis is invariant under roll rotation so we'll only apply the rodriguez role to the x vector we finally have the fresh orientation of x and y axes however to draw an object in v python you have to specify the y and up vectors not the y and x luckily it's very easy to get the up vector from the x and y vectors the up vector is simply the cross product of the x and y vectors our python code is now complete let's use it now for our test procedure we're going to need a cuboid jig to help us align the mpu along cardinal orientations first check that you have a level surface make sure that you're facing both the jig and the computer screen to facilitate comparison make sure that the jig is aligned against some fixed support or marking so that it can later be returned orthogonal to this initial orientation and that this initial orientation matches figure 1 of the test form check that the serial port in animation.py matches the one arduino is connected on now go ahead and upload run tested ino to arduino now run animation.py we're now going to check our transformation to yaw pitch enroll i recommend performing this check whenever the code is modified pick the jig up move and rotate it checking that these real rotations match what you see in the animation check also that each curved arrow in the animation matches the corresponding one in figure 2 of the test form check that numeric values displayed for the angles in animation increase and decrease in accordance with the curved arrows check that these numeric values have a range of minus 180 to 180 for yaw and roll and -90 to 90 for pitch finally check for gimbal locks rotate the shakes so that the y-axis is vertical and check that there are no spurious rotations or flips in the animation repeat for when the x-axis is vertical now let's perform our quantitative check here we're simply checking to see that virtual pitch and roll are close to plus or minus 90 degrees when the y and x axis are vertical respectively finally line up the jig against the fixed support or marking this time in the orientation orthogonal to the initial one as shown in figure 4 of the test form and check that yaw reads close to -90 test complete if you've made it to this point congratulations you are now an mpu6050 expert if you wish to see more videos like this in the future please support my channel using one of the links provided below till next time
Info
Channel: Maker's Wharf
Views: 37,297
Rating: undefined out of 5
Keywords: MPU-6050, MPU, MPU6050, MPU 6050, GY 521, GY-521, EEPROM, quaternion, quaternion conversion, yaw, pitch, roll, gimbal lock, Arduino, Animation, VPython, Python, pyserial, Rodrigues' rotation formula, Rodrigues' rotation, Rodrigues' formula, Rodrigues formula, offset calibration, gain calibration, calibration, gyro, accelerometer, fusion, DMP, Digital Motion Processor, drift error, dependency injection, equivalence principle, principle of equivalence, IMU, balancing, inertial
Id: k5i-vE5rZR0
Channel Id: undefined
Length: 55min 34sec (3334 seconds)
Published: Wed Jan 26 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.