Shooter Lifting Code

Hello, I qould like an inquiry on whether this routine will work. For lifting and adjusting the angle of our shooter, we have 5 touch sensors lined up at different angles of the lift, and this program is supposed to get the distance sensed by the vision camera(it’s a placeholder for now), and compare the desired level with the level the lift is currently at, telling the motor to move up or down depending on the direction needed. Does my current program look alright? (it’s in teleop.vi)

Also, I would like to know how to make the routine run only once when you press the button on the joystick, instead of constantly running while the button is held down, as it would work atm.

Thanks!





I don’t believe your code will work correctly as designed right now.

You actually have quite a few problems.

1st, in BLUE. The In Range / Coerce function is very useful and is exactly what you want for this logic, but… what about numbers between say 15 and 16, 24 and 25, 38 and 39, or 44 and 45? The way you have it setup is almost perfect because of the solid diamond on the bottom (include the value and all values above) and the hollow diamond at the top (include all values below, but not the value). So you need to decide on one of the two numbers. So instead of 15 and 16, you need to either have just 15 or just 16 for both of them. Otherwise you have a gap in your logic.

2nd, in PINK. The red dot in the code means you’re doing a coercion, or that you are converting from one data type to another without explicitly meaning to. This may be fine for your use, as long as the number is EXACTLY what you specify. If it’s somewhere between say 4 and 5… which one should it pick? If there’s no need for decimal points (floating point arithmetic), then take it out. It only slows down the code, uses more memory, and complicates your code.

3rd, in GREEN. Two problems here. You have an unthrottled while loop… while it’s waiting on your DIO to return a value, it will just sit there in a loop, waiting, going as fast as it can, using all available CPU time. But that doesn’t matter because you **CANNOT **place an undeterministic ‘while’ loop in the Teleop VI. This is a HUGE no no. This will cause all other functions in teleop to become unresponsive while the lift motor is running. Still… even with all of this, you have an even bigger problem…

4th, in ORANGE. This loop will never terminate because the DIO input will never be updated within the loop. Once the while loop begins, it gets stuck there, forever. Hence why it’s such a HUGE no no to have a while loop in teleop. In this case, your robot would cease to function because it would get stuck in this while loop. If (and I strongly discourage it) you stuck with this while loop in teleop, you need to have the DIO Get function inside of the while loop. That way, it can update and terminate the while loop once the motor is done moving.

5th, in RED… what are you trying to do here? Are you trying to selectively get the reference to your DIO input? Don’t you already know what desired level you want because of the case structure that was partically circled in **PINK **a moment ago? Why complicate your code like this?







Search for Rising Edge Detection

http://www.chiefdelphi.com/forums/showthread.php?t=81938&highlight=Rising+Edge+Detection

I agree, your code will not work as intended as pointed out above.
Also with the embedded while loop it should not be located in Teleop

Your Distance is a float but you do not have a continuous range from 0 to 60. What will happen if Distance is 15.5 or 24.3 or 38.04 or 44.99999? Does your “distance sense by the vision camera” return? Does it return whole numbers (Blue) or floating point numbers (orange)? see attached code

Also, are there any “dead zones” in between the positions of your touch sensors when your shoots is moving up or down that no sensors will be “TRUE”? That will make it hard to program for.

A Potentiometer would work better for reading absolute position and you could have a variable numbers of shooting position instead of just 5.

But, can you set up your hardware, (the limit switches and your shooter) so that as it move up the next higher limit switch is engaged before the lower one is disengaged (or they could just all stay on as it moves up with you testing for only the highest one)

Give us a better idea on how your hardware works.

Threshold.png


Threshold.png

Hello, same team as OP here. (4110)

I apologize for the lack of thorough information. We posted this last night in a rush to get home, thinking that we would get more responses over night than to wait until this morning to post it.

In my begin.vi, I have the reference name for each touch sensor as “1”,“2”, etc. I convert the value from DesiredLevel into a string so that it would pull the info from the touch sensor located at the desired level, and use that value to stop the motor when the that specific sensor is pressed.

I will redo the invalid parts of the code today. How would I substitute the while loop for something not-destructive to the teleop vi.

Thanks again, in a rush again, sorry. haha

Can you tell what your Current Level is just by reading all the DIO?
Potentiometer would be better for position feed then the limit switch as it will give you continuous read on your position

No loops in Teleop

Read Distance “calculate” DesiredLevel
Read the DIOs “calculate” CurrentLevel

If CurrentLevel = DesiredLevel then write 0 out to Lift Motor
If CurrentLevel > DesiredLevel then write -20 out to Lift Motor
If CurrentLevel < DesiredLevel then write +20 out to Lift Motor
NO LOOPThe Teleop loop will loop around and you get to do it all over again.
As long as CurrentLevel < DesiredLevel the motor goes up
As long as CurrentLevel > DesiredLevel the motor goes down

Each time through Teleop you check CurrentLevel and compare it to DesiredLevel.

You can put this all in a case structure and enable or disable with the toggle I sent you earlier.

Again from my question asked early, Can you always tell your Current Level by the limit switches alone?
Or do you have positions in between

If you can not always tell your position then you will have to maintain the level in some kind of state machine.

This might work depending on how your limit switches work.
Give us more info about your limit switches.

You will need to fill in the Ref to your DIOs and Motor
The top DIO Get would be 1 and the bottom DIO Get would 5





Oops, I meant to attach this diagram to the last post to better illustrate how the sensors are laid out. With this layout there are only 5 possible angles to shoot from. If none of the sensors are being touched, the motor should be turning to angle the shooter at the right angle for the currently processed distance, and then stop once it touches that sensor.

I’m curious to know how you would use a potentiometer to read the position of the motor. I was assuming that we would have to use an encoder to do so, and that we would not have enough time now to configure it for the motor. I’ll do some research on it, but if you know a way to make the potentiometer work for this task in a simpler way than the touch sensor setup, we’d be glad if you shared. I see that there are difficulties in programming the current approach, and with us, even simpler things tend to fail at the worst of times. I would rather not go through with a complicated program that I’m not completely sure will work without fault.





The potentiometer would be attached to the bottom of your (gray) shooter. Not on the motor. Where the Gray shooter pivots on the Orange ground/top of robot and changes it reading as the angle of the shooter changes.

Anyway, can your shooter go lower than the 1st or higher than the 5th?

Can the motor move too fast that it could go pass the position if you are not reading the limit switch fast enough?

With the fact that we can’t know for sure where we are if the shooter is in between position, the best option then would be a state machine and hope you do not get out of sync.

Right now I am at a system that does not have FRC stuff loaded and can’t post a solution.

First off, a potentiometer is not an encoder, and an encoder is not a potentiometer. They’re completely different things.

A potentiometer is an analog sensor which can measure angle.

You have 3 pins normally. The left one could be your ground, center will be the signal, and the right one could be your 5V power. This sensor would plug into the analog breakout board.

The reason I say could in the previous paragraph is because you can swap them around. This would change whether the voltage rises or falls in a given direction. To put it plain and simple, a potentiometer is a voltage divider circuit. You will have a voltage from 0 to 5V based on the position of the shaft.

Normal potentiometers have about a 170˚ rotation, but I would say they are only usable for about 140˚, as there is usually a huge dead zone on either end.

Okay, so now you have a general idea on how potentiometers work. Now, how to use them?

In LabVIEW, you will have a few new things to work with…

In your begin VI, you need to open an analog channel.

Screen Shot 2013-02-13 at 4.16.46 PM.png

Here would be how to open the channel and give it a reference… Easy so far, right?

Begin.PNG

How about we place a while loop in periodic tasks. What we’re going to do is make a PID control loop. This is what is called closed loop control. You have a sensor giving direct feedback to the system in order to control the motor.

I’m going to change your local variable (represented with the home symbol in the first picture you provided) to a global variable. This means, you can set this variable globally (anywhere) in your code. However, this also gives you another responsibility. You cannot set global variables from more than one place in the code at a single time.

An appropriate use of a global variable would be from autonomous and from teleoperated code. However, an inappropriate use would be setting this value multiple times such as from teleop two or three more times. Basically what I’m getting to… this global variable should only show up at most 3 times in all of your code.

  1. Autonomous Independent.vi
  2. Teleop.vi
  3. Periodic Tasks.vi

First, lets create that global variable.

Double click on Robot Global Data.vi in the Project Explorer.

Project Explorer.PNG

You want to add a numeric control.

It will default to a floating point (double). This is fine for what we want to do. At this point, we need to define what DesiredLevel is… Is it an angle? Is it the voltage being fed back from the potentiometer? For the sake of time and for simplicity of this demo, we’ll make it represent a voltage from 0 to 5 volts.

Robot Global Data.PNG

More to come…

Screen Shot 2013-02-13 at 4.16.46 PM.png
Project Explorer.PNG
Begin.PNG


Robot Global Data.PNG


Screen Shot 2013-02-13 at 4.16.46 PM.png
Project Explorer.PNG
Begin.PNG

Robot Global Data.PNG

Next, let’s go to periodic tasks. Create a new while loop, place a timer inside of it, and set your execution to never stop.

PT1.PNG

This code will start running as soon as your code begins running, and it will never stop. Having loops in periodic tasks is fine because they execute outside the scope of teleop. Basically what you’re doing is multitasking. Your robot can run simultaneous loops at the same time.

Now let’s just get your hardware setup… for this we have the potentiometer and the lift motor. Let’s also get in that global variable. To do this, just drag and drop the Robot Global Data into the Periodic Tasks VI. Right click on the global variable, and select “Change to Read” You also need to select the DesiredLevel variable. You can do this also by right clicking, and going to “Select Item”.

PT2.PNG

Now we have everything we need to do a closed loop controller. By far, my favorite is PID.

To implement a PID controller, right click in the Block Diagram, go to PID, and select PID.vi.

Hook it up as you would expect. Your setpoint is the desired level, your process variable is the voltage from the potentiometer, and the output goes directly to the motor.

You’ll want to be extremely careful the first time you run it. You have to tune the PID controller for your system.

You need to specify the output range (-1 to 1 for our motors), and the PID gains, which are what controls the response of the system.

Here’s the block diagram for the finished control loop.

PT3.PNG

Here’s what will be on your front panel.

PTFP.PNG

Once the system is tuned, you’ll want to save those values. To do this, right click on the cluster, go to Data Operations, and select Make Current Values Default.

Screen Shot 2013-02-13 at 5.10.51 PM.png

PT1.PNG
PT2.PNG
PT3.PNG
PTFP.PNG
Screen Shot 2013-02-13 at 5.10.51 PM.png


PT1.PNG
PT2.PNG
PT3.PNG
PTFP.PNG
Screen Shot 2013-02-13 at 5.10.51 PM.png

Try this code. The VI is 8.6 but 2012 will open it.

You could just drop the VI on to your block diagram and wire up the DIO, Distance, Joystick button and the Motor Speed.

You are still at risk of having the system getting out of sync with the levels especially if the robot starts in between the positions and returns a current level of zero (0). You might have to create manual override if the shooter gets out of sync due to the dead zones in between limit switches or out side of the limit switches.

The init on the motor speed feedback should be 0.2


Shooter.vi (10.8 KB)



Shooter.vi (10.8 KB)

Thanks for that Ryan, I’ve got at least that much now.

Anyway, can your shooter go lower than the 1st or higher than the 5th?

It technically could, since the hinge that the shooter can rotate further than the angles that we want to move to, but the intended purpose is for the the absolute maximum and minimum positions to be where the lifter arm touches the most outward touch sensors. I now plan on switching to the potentiometer setup, so programming these touch sensors as limit switches should be much easier than having 5 of them and checking for position with them, like before.

Can the motor move too fast that it could go pass the position if you are not reading the limit switch fast enough?

I can fix this problem by slowing down the motor when the potentiometer’s voltage gets closer to matching the max and min shooter angles.

Thank you for the help guys. We are now testing different available potentiometers, and we will manufacture a mount to attach it to the lift system.