This action might not be possible to undo. Are you sure you want to continue?
Michael Kleinigger, RPI Undergraduate Engineering Student Dr. Kevin Craig, Professor of Mechanical Engineering RPI Mechatronics Laboratory – UPDATED 1/18/2007
In this tutorial we will explore the process of implementing a previously-developed control scheme within LabVIEW. As an example, we will walk through the necessary steps to implement a controller, for both swing-up and balancing, for the Rotary Inverted Pendulum system, pictured below. The Engineering System Investigation Process was followed to thoroughly understand the system and then design several controllers to swing up and balance the inverted pendulum. LabVIEW allows one to quickly prototype a controller on the hardware system, as the controller previously developed and simulated in LabVIEW is quickly and effortlessly implemented on the actual hardware system. This tutorial shows you how this is done. What would have taken days or weeks to implement if programmed on a microcontroller can be accomplished in a matter of hours with National Instruments’ LabVIEW.
+ I1z + m 2
cos 2 φ + I2z cos 2 φ + I2y sin 2 φ θ + I2x y − m 2 22 2 2
sin φφ + I2 − m 2 x 2y2
cos φφ2 +
I2 − m 2 y2
− I2z ( 2 cos φ sin φ ) φθ = T − Bθ θ + Tfθ sgn θ 2
+ I2x φ + I2x y − m 2 2 22
sin φθ + m 2
− I2y + I2z ( cos φ sin φ ) θ2 + m 2 g 2 2
cos φ = − Bφφ + Tfφ sgn φ
The Rotary Inverted Pendulum was first developed by students in Professor Kevin Craig’s Mechatronics System Design course in the spring of 1999. It has gone through numerous revisions since. Classical, state-space, and fuzzy logic controllers for balancing, as well as an energy-based swing-up controller, were originally designed using Matlab / Simulink and implemented using dSpace. We will be implementing both state-space and classical controllers, as well as a swing-up controller, in LabVIEW. Then we will configure our virtual instrument (VI) so that we can switch between state-space and classical control on the fly in order to compare the two controls.
Step 1 - Beginning First, open LabVIEW 8.0. Once the “Getting Started” screen has appeared (Figure 1), select “Blank VI” under the “New” menu. You should soon see a blank front panel and behind it an empty block diagram (Figure 2).
However. then select the simulation loop. then click and drag the boxes which appear on its edges to adjust the size. This same keyboard shortcut can also be used to return to the front panel.Figure 2 Step 2 – Simulation Loop Switch to the block diagram by clicking the block diagram window or pressing Ctrl+E. You will now see the functions palette (Figure 3). If at a later time you wish to adjust the size of the loop. a possible solution is to use a simple while loop or a timed loop. You will need the simulation module installed in order to use this. right-click in any white space on the block diagram. you may click to select it. We will begin building our control system by adding a simulation loop. If you’d like. Now move your mouse over “Control Design and Simulation” → “Simulation”. Your cursor will change its icon and you can then click and drag to place the simulation loop onto the block diagram (Figure 4). the simulation loop typically provides much better performance and accuracy. To add the simulation loop. If the simulation loop is not available. 3 . click the thumbtack in the top left corner of this window to fix it in place.
Figure 3 Figure 4 4 .
• • • • • Simulation Final Time: “Inf” (click in the box.” In the window that appears. cause the simulation loop to run indefinitely. right-click in any white space on the block diagram. executing all blocks within it every 5 milliseconds. as you might guess. make the following changes.To set the simulation loop parameters. Figure 5 5 . Move your mouse over “Express” → “Input” and from the resulting window click “DAQ Assistant” (Figure 5). then type) ODE Solver: “Runge-Kutta 1 (Euler)” Time step: 0. Step 3 – Sensor Input Next we will add our DAQ Assistant input block. which will allow us to receive data from our two position encoders. These settings. uncheck “Software Timing” and select “1 kHz” under “Loop Timing Source” Set the loop timing period to 5.005 Under the “Timing Parameters” tab. To add this block. right-click anywhere on the thick black border of the loop and select “Configure Simulation Parameters. then click OK.
this system was at one time tested with an external device that produced a voltage output proportional to velocity. Figure 6 Note that for other systems. We will be using the National Instruments USB-6211 DAQ device. At this point. open the Measurement and Automation Explorer (Start → All Programs → National Instruments → Measurement and Automation). Note that to find out where on your device or breakout board you must connect your input sensors. which can be configured to convert the encoder pulses to angular positions. Once this is opened. 6 . A window will now appear which will allow you to configure your input (Figure 6). an analog or digital input may be appropriate depending on the type of sensor you are using. expand the list to the left to find your DAQ device and from the toolbar on the top right select “Device Pinouts”. For example. In order to read that voltage. we created a DAQ Assistant block which was configured for Analog Input → Voltage.Place the “DAQ Assistant” block within the simulation loop on the block diagram. make sure you have connected your data acquisition device and have connected your sensors as appropriate. We will now select Counter Input → Position → Angular.
you may want to click the “Test” button to verify that input is being properly read. click OK and LabVIEW will build the DAQ Assistant block.Next.14159. When creating an input for your own system. which tells LabVIEW to make differential voltage measurements. Click “Finish” and LabVIEW will present you with another window in which you can configure the DAQ Assistant block (Figure 7). • • • • Set the value of “Pulses / Rev” to 1250 Set “Initial Angle” to -3. For an analog input voltage.” This is important since we will be acquiring single data points at each iteration of the simulation loop. rather than groups or at hardware-specified frequencies. a common mistake is to leave the “Terminal Configuration” set to “Differential” (the default choice). Once finished. and “Units” to “Radians” Set “Decoding Type” to “X4” Make sure that “1 Sample (On Demand)” is selected under “Task Timing. We are using the USB-6211 and will select “ctr0” from the list. you should see a list of your attached DAQ devices. Figure 7 7 . instead of measurements with respect to ground. To make measurements with respect to ground. select “RSE” instead.
Next. For DAQ Assistant output blocks using multiple channels. However. one revolution begins at -π. a unique DAQ Assistant block must be created for each counter input. to read those inputs on the block diagram. This will be done such that. and our “Pulses / Rev” to 512. also found under “Express” → “Signal Manipulation”. which can be found on the functions palette under “Express” → “Signal Manipulation”. Add a switch block (“Control Design and Simulation” → “Simulation” → “Nonlinear Systems” → “Switch”) Create two more wire branches from the remainder output of the Q&R block and connect them to the “control input” and “input 2” terminals of the switch block. found on the functions palette under “Programming” (opened by default) → “Numeric” Wire the output from the “From DDT” block to the “x” input of the Q&R block (top left terminal). then again leftclicking on the left side of the “From DDT” block. top to bottom. Now open the functions palette and select “Express” → “Arithmetic and Comparison” → “Express Numeric” → “Express Math and Scientific Constants” → “2*π” Wire the 2*π block to the “y” input of the Q&R block. then increases back to π as the pendulum falls. as the DAQ input channels. Next. Create a second wire branch from the 2*π block by clicking once on its output line. we will set our “Initial Angle” to 0. Then. Wire the input to this block to the output from our DAQ Assistant block by left-clicking on the small blue arrow to the right of the word “data” on the DAQ block. which will return the angle of the horizontal arm. then from the window which appears. and immediately flips back to -π. then clicking on the “y” input to the subtraction block. • • • • • • • • • • First. select “Single scalar” from the list of resulting data types and click OK. you will need to add a “Marge Signals” block. we need to “normalize” the angles we read from our encoders. add the “Quotient and Remainder” block. we will repeat step 3 once more to add another counter input. Connect this block to the output of your DAQ Assistant block and increase its size to the number of channels in your DAQ Assistant block. in the case of the pendulum. Step 4 – Angle Normalization Now that we have our input blocks. 8 . several analog or digital inputs (or outputs) can be grouped into a single DAQ Assistant block by holding the control key and selecting multiple inputs from the “Create New…” DAQ Assistant window. reaches zero at the balancing point. For this encoder. open the functions palette and select “Express” → “Signal Manipulation” → “From DDT” Click to place this block. This time we will select “ctr1” from the “Create New…” DAQ Assistant window.For our system. you will need to add a “Split Signals” block. The output from the split signals block will be in the same order. In general. add a subtraction block (“Programming” → “Numeric”) and connect the remainder output from the Q&R block (top right) to the “x” input of the subtraction block.
You can also double-click anywhere on the block diagram to add a text label. Double-click on the words “DAQ Assistant” and you will be able to type in a new name. Double-click the switch block to open its configuration page. Rather than repeating this procedure for the second encoder input. we will create a subsystem from the blocks we have created thus far. Step 5 – Encapsulation We have now completed all the steps necessary to accept and process data from our position encoders. add the “π” block. Finally.” Connect this to the “threshold” terminal of the switch block. To do this. We must first add indicators to our system to let LabVIEW know which values we would like to set as outputs from our subsystem. Right-click and select “Create” → “Indicator. move your mouse over the “output” terminal on one of the switch blocks. Figure 8 Also note that it is possible to name these blocks to make it easier to differentiate between them later.” You may type to label this indicator as shown in Figure 9. click and drag a box around the blocks you have just created. Change the “Parameter source” dropdown box to read “Terminal” and click OK. 9 . Then. This will also allow us to re-use this set of blocks quickly and easily. click and drag the selected blocks to create a copy of them (Figure 8). Repeat this procedure for the other switch block output as well as the wires connecting the “From DDT” blocks to the Q&R blocks (Figure 9). also found under “Express” → “Arithmetic and Comparison” → “Express Numeric” → “Express Math and Scientific Constants” → “π. while holding the control key.• • • Connect the output from the subtraction block to the “input 1” terminal of the switch block. In order to keep our block diagram neat.
While holding your left mouse button. Release your mouse button. click the “Edit” menu then choose “Create Simulation Subsystem. but still within the simulation loop.” For easier viewing. Figure 10 10 . click in a blank space above and to the left of the DAQ Assistant blocks. Select the four indicators and press the delete key. hold the Shift key and click to select other blocks and wires. since they will not be needed.Figure 9 • • • • • Next. If there are any disconnected wires remaining. Finally. press Ctrl+B to quickly delete them. right-click the subsystem block which has just been created and select “Icon Style” → “Text Only” (Figure 10). If you were unable to select all of the blocks in one pass. move your cursor diagonally across the blocks until they are all within a dashed-line rectangle.
For the Rotary Inverted Pendulum System. However. since the position signals from the encoders are given in discrete steps. Click OK. • • • • • • Right-click in any blank space on the block diagram and select “Control Design and Simulation” → “Simulation” → “Continuous Linear Systems” → “Transfer Function”. we will need to take the derivative of position in order to compute velocity. Place this block close to the output from your encoder subsystem. pendulum position. Change the value listed under Denominator → a1 from “1” to “0. Hold down the control key and click and drag the transfer function block we just configured to create a copy with identical configuration. Figure 11 11 . Double-click this block to open the configuration window (Figure 11).03” as shown. Since we cannot read velocity directly from the encoders.Step 6 – Velocity Computation We will now begin the implementation of the state-space controller. we will first need to “smooth” our input signals using a transfer function low-pass filter (otherwise we would see large spikes in velocity at every count of the encoder). arm velocity and pendulum velocity. we account for four states: arm position.
This is standard LabVIEW behavior and is often quite convenient. still within the simulation loop. we can add gain blocks and a summation block to compute the control effort needed to balance the pendulum arm. we will add the derivative block. • • Right-click in any blank space on the block diagram and select “Control Design and Simulation” → “Simulation” → “Continuous Linear Systems” → “Derivative”. You may need to expand the simulation loop at this point by placing your mouse over its edge. 12 . • • • Right-click to bring up the functions palette and select “Control Design and Simulation” → “Simulation” → “Simulation Arithmetic” → “Gain” Place this block to the right of the derivative blocks. Step 7 – State Space Now that we have all of the necessary inputs. Your block diagram should now look similar to Figure 12. create one connecting the transfer function block output and the derivative block input.Once you have finished configuring the transfer functions. Place this block close to the output from one of your transfer function blocks. Figure 12 Next. Double-click the Gain block you just added. connect their input terminals to the “arm angle” and “pendulum angle” terminals of your formula block. then clicking and dragging the small gray boxes which appear. You may notice that when you bring the derivative block close to your transfer function block a wire automatically appears to connect the two. which completes our velocity computation. If a wire did not appear.
connect the second and fourth gain blocks to the respective outputs from the derivative blocks. center terminal which should now be labeled “gain” Select Create → Control. Connect the third gain block similarly to the “pendulum angle normalized” terminal. • • • Connect the top gain block to the “arm angle normalized” terminal of our subsystem. Figure 13 Now we need to connect the inputs to the gain blocks (located on the left side. 13 . Make four copies of this block by holding the control key while dragging the block to a new position (Figure 13).• • • Under “Parameter source” select “Terminal” from the drop-down box. Click OK. Next. Finally. Repeat this procedure for the other three gain blocks (Figure 14). we will add controls so that we can set the values of our gains via the front panel. close to the “k”) to the sensor outputs. Right-click the top. A new orange box will appear and you can type to label it. • • • • Move your mouse over any one of the gain blocks so that the orange terminals appear.
Figure 14 At this point. set the number of inputs to 4 and click the symbols around the circle until they are all + signs (Figure 15). whose default value is 1. • • • • Bring up the functions palette and select “Control Design and Simulation” → “Simulation” → “Simulation Arithmetic” → “Summation. Figure 15 14 . Wire the output from each of the gain block into one of the inputs on the summation block.” Place this block to the right of the gains. Next. To do this. right-click on the control you wish to change and select “Replace” then choose the control you wish to use. if you switch to the front panel you will see four text boxes. we will add a block to sum the outputs from the gain blocks. If you’d like. The output from this block will ultimately be fed to an output DAQ Assistant to control our motor. From the window that appears. Double-click the summation block. you can replace these with any type of control you’d like.
We will now add another DAQ Assistant block to send output to our motor control hardware. select “Analog Output” → “Voltage” Select “ao0” from the list of supported channels. • • • • • Right-click on an empty part of the block diagram to open the functions palette. Select “Express” → “Output” → “DAQ Assistant” From the window that appears.Step 8 – Output At this point the state-space control is essentially complete. Figure 16 15 .” Configure the DAQ Assistant with an output range of -5 to 5 volts. then click “Finish. task timing “1 Sample (On Demand)” and click OK (Figure 16).
Figure 17 We should now switch to the front panel and enter values for each of our state-space gains. Note that the state-space controller we’ve just created can easily be adapted to fit the needs of any system. 16 .” Now we are ready to run our VI and test the operation of our state-space balancing controller. the pendulum should balance. connect the output from the saturation block to the input of the DAQ Assistant output block (Figure 17). Once these have been entered.8 volts. connect the output from the sum block created in step 6 to the input of the saturation block.Once LabVIEW has created the DAQ Assistant block. We will run the VI (by clicking the “Run” button on the front panel toolbar) with the pendulum hanging straight down. one possible mistake is to reverse the polarity of the motor output or of one of more state-space gains. we will set the output’s lower limit at -4. the VI could stop unexpectedly during execution). Then. we are ready to continue. If we have done everything correctly. In order to prevent the control system from sending a value outside the -5 to 5 range we must add a saturation block (if this block were not added. we can make them default by right-clicking the control and selecting “Data Operations” → “Make Current Value Default. Once the saturation block has been configured. • Bring up the functions palette again and select “Control Design and Simulation” → “Simulation” → “Nonlinear Systems” → “Saturation” • Place this block to the left of the DAQ Assistant output block and then double-click it to open the configuration window.8 and the upper limit at 4. Then we will move the pendulum by hand to its balancing position and turn on motor power. • For our system. If the system does not react as expected. This can be done by changing the type and/or number of DAQ Assistant input and gain blocks.
Switch to the front panel by pressing Ctrl+E. add the “SimTime Waveform” blocks (“Control Design and Simulation” → “Simulation” → “Graph Utilities”) Connect the input to the SimTime Waveform block to whichever value you wish to graph. we will briefly describe the steps taken to implement our swing-up algorithms. connect the SimTime Waveform blocks to the values you wish to graph. If. copy the SimTime Waveform block (hold the control key. • • From the functions palette. scale. when you run your VI. then click and drag). Select “Chart History Length” and increase the value as needed. Finally. To do this. Right-click on the new waveform graph and select “Properties. Add a “Merge Signals” block (under “Express” → “Signal Manipulation”) Connect the outputs from the SimTime Waveform blocks to the inputs on your “Merge Signals” block. you find that the last part of the graph tends to disappear after a short period of time. then several numeric blocks which determine the proper motor output voltage (Figure 19). Connect the output from the “Merge Signals” block to the input of your waveform graph. Next. go to the front panel and right-click on the waveform graph. etc as you wish. we need to create a graphical indication of certain values versus time. you may need to increase your chart history length. 17 .” Here you may adjust the format of the graph. LabVIEW makes creating graphs quite simple. Since the swing-up controller is an energy-based system. first delete the wire between the SimTime Waveform block and the Waveform graph. we will be using five formula blocks to compute the total energy of the system. Step 10 –Swing-Up Now that we have successfully implemented our state-space controller.Step 9 – Graphing I/O In order to observe the system’s behavior more precisely. Figure 18 • • • • • • • If you wish to view multiple values on the graph simultaneously (Figure 18).
” The “cos” (cosine) block in the lower left can be found on the functions palette under “Express” → “Arithmetic and Comparison” → “Express Math” → “Express Trigonometric Functions. Figure 20 18 . they have been configured to be viewed as icons in order to save space. See step 5 for a detailed description of this process.” The “x” (multiplication) blocks.” To create the numeric constants you see in orange boxes. and the sign block (directly beneath the lowest formula block) can be found under “Programming” → “Numeric. identical (with the exception of their internal formulae) to the blocks we created in step 4. the “–” (subtraction) blocks. However. We will now create subsystems for our state-space and swing-up controllers (Figure 20).” Then you can enter any numeric value. This can be accomplished by right-clicking a block and selecting “View as Icon.Figure 19 • • • • The blocks with the calculator symbol are formula blocks. right-click on the input terminal to any block and select “Create” → “Constant.
Set the threshold value to 0. then wire its input to the “pendulum angle normalized” wire. Double-click on the switch block to open its configuration page. then wire “input 2” to the output from the balance controller (before the saturation block). Wire the output from the absolute value block to the “x” input (top left) of the greaterthan block. Wire the output from the conversion block to the “control input” of the switch block (Figure 21). Add a Boolean to numeric conversion block (“Programming” → “Boolean” → “Bool to (0. the system will switch between balancing and swing-up controllers at 20 degrees. Select “Programming” (opened by default) → “Numeric” → “Absolute Value” Place this block within the simulation loop. Right-click on the greater-than block “y” input (bottom left) and select “Create” → “Constant. Next. However. Wire “input 1” to the swing-up subsystem output. add a switch block (“Control Design and Simulation” → “Simulation” → “Nonlinear Systems” → “Switch”). The Rotary Inverted Pendulum is designed to operate in swing-up mode at any point below 25 degrees from vertical. Figure 21 • • • • • • • • • • First open the functions palette by right-clicking in a blank space on the block diagram. Between 20 and 25 degrees. 1)”). we need to add a second switch to cut power to the motor between 20 and 25 degrees (Figure 22).Step 11 – Control Switching Next.” Enter “0. At any point less than 20 degrees from vertical. 19 . Connect the input to the conversion block to the output from the greater-than block. we need to add blocks to switch between swing-up and balancing control based on pendulum position.5 then click OK. Next. open the functions palette and select “Programming” → “Comparison” → “Greater?” Place this block to the right of the absolute value block.436” (radians) for this value. the motor receives no power. the balancing controller takes over. This “dead-zone” is designed to prevent the pendulum from building up too much energy and thus swinging past the balance point. As it is configured now.
connect the output from the new switch to the input to the saturation block. Add another switch block by selecting the block added in the previous section. At this point the system can be run to test the functionality of our swing-up algorithms as well as our switching logic.349” for this value. Connect the output from the previous switch block to the “input 2” terminal of this new switch block. and dragging. Right-click the “input 1” terminal and select “Create” → “Constant”. Next. Wire the outputs from the greater-than block and the less-than block to the two inputs of the “AND” block. holding the control key. Right-click on the “y” terminal of this block and select “Create” → “Constant. Finally. Add another Boolean to numeric conversion block by selecting the block added in the previous step.” Enter “0. and dragging. 20 .Figure 22 • • • • • • • • • Open the functions palette again and select “Less?” (under “Programming” → “Comparison”) Create a second wire branch from the absolute value block and connect it to the “x” input of the less-than block. holding the control key. We have now completed the control system for the Rotary Inverted Pendulum. Connect the conversion block’s input terminal to the output from the “AND” block then connect its output to the new switch’s “control input” terminal. we will add the “AND” block (“Programming” → “Boolean”). Leave the value as 0.
etc) can cause the arm to move suddenly. Figure 24 Note that with its two transfer functions. classical control is quite computationally intense. then created a switch block identical to that used in step 10 but controlled on the front panel (Figure 24). Figure 23 As you can see. and only requires changing the DAQ Assistant input and output ports. we could try to run this VI on a PXI or other “Real-time” LabVIEW system.Step 12 – Adding the Classical Controller (optional) In order to determine which control scheme best balances the pendulum. often knocking the pendulum out of its balanced position. developing a controller within LabVIEW is both simple and efficient. In order to improve this behavior. It also allows quick testing and comparison of different control methods. 21 . even a simple action taken by the control computer’s user (switching windows. The implementation of this controller involves many of the same steps we have taken to develop other parts of this VI (Figure 23). When the pendulum is balancing with the classical control. we have chosen to implement a classical controller alongside the state-space control. Doing so is quite simple. As you can see. In experiment we see evidence of this. opening files. We have added this to a subsystem. with only two gain blocks. two transfer functions. and an addition block. the classical controller implementation is somewhat simpler.
This action might not be possible to undo. Are you sure you want to continue?