Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   NI LabVIEW (http://www.chiefdelphi.com/forums/forumdisplay.php?f=182)
-   -   Programming Puzzle (http://www.chiefdelphi.com/forums/showthread.php?t=107951)

baronep 21-08-2012 16:43

Programming Puzzle
 
So I am trying to solve a programming problem that we are having with our T-Shirt cannon.

We have an analog rotation sensor that, as the cannon rotates a full rotation, the analog signal changes between 0 and 5V (linearly).

My question is how I should deal with the transition between 0 to 5 volts in code. I want to be able to index the cannon so that it will snap to a position every 1/6th of the rotation. How should I do this?

Chris Hibner 21-08-2012 16:54

Re: Programming Puzzle
 
1) Measure how much rotation (in degrees) you get from 0 - 5 V of your sensor. Specifically, at 0 V, set the protractor to 0 degrees. Turn your cannon to the 5V reading and read the angle on the protractor.

2) Calculate the conversion factor from voltage to degrees. Let's say in step 1 you determined that at 5 volts the angle was 270 degrees. Then your conversion factor is 270 degrees / 5 V = 54 degrees/V

3) Now in LabVIEW, multiply your sensor reading (0 - 5V) by the conversion factor calculated in step 2. This will tell your code the angle of your cannon in degrees.

4) Use a PID loop to command your motor to any angle (in degrees) you want your cannon to shoot.

baronep 21-08-2012 17:03

Re: Programming Puzzle
 
But the problem is that I want the motor to rotate seamlessly through the 5v to 0v. For instance, if it overshoots a setpoint at 4.9 to .1, i don't want it to rotate the rest of the way around, but back up past 5v to 4.9

Ether 21-08-2012 17:06

Re: Programming Puzzle
 
Quote:

Originally Posted by baronep (Post 1182563)
But the problem is that I want the motor to rotate seamlessly through the 5v to 0v. For instance, if it overshoots a setpoint at 4.9 to .1, i don't want it to rotate the rest of the way around, but back up past 5v to 4.9

The canon can turn only so fast. Put rate checks in your code. That will tell you whether .1 actually means .1 or 5.1

BTW, how much of a deadband is there ? You may need to swap out your sensor.


baronep 21-08-2012 17:09

Re: Programming Puzzle
 
I think you misunderstand. If I was just using a simple comparator like > or < between setpoint and the analog input, and the cannon overshot past the wraparound, how do i force the cannon to go backwards instead of continuing another complete rotation to get back to the setpoint?

Ether 21-08-2012 17:14

Re: Programming Puzzle
 
Quote:

Originally Posted by baronep (Post 1182565)
I think you misunderstand. If I was just using a simple comparator like > or < between setpoint and the analog input, and the cannon overshot past the wraparound, how do i force the cannon to go backwards instead of continuing another complete rotation to get back to the setpoint?

I understood you perfectly clearly. You need to add code to detect zero crossings. You do that with rate checks. If your sensor reads 0.1 in the current iteration, and it read 4.9 in the previous iteration, then the actual reading is 5.1, not 0.1

Can you work from there, or do you need a more detailed explanation?

Again, how large is the sensor's dead zone? You may need a new sensor.


baronep 21-08-2012 17:20

Re: Programming Puzzle
 
This zero crossing makes sense in theory but I am still unsure about how to implement it.

The dead zone is very small

EricVanWyk 21-08-2012 17:29

Re: Programming Puzzle
 
It may be easier to think in terms of "difference between where I am and where I want to be", and write as much of your code in that reference as possible. Then you will only have to handle the wrap-around in the one spot where you calculate that value. You will need some if statements and a little bit of math - if it is calculated as past half way around in one direction, map it in the other direction.

baronep 21-08-2012 17:32

Re: Programming Puzzle
 
I think I found a fix, I found a zero crossing VI that I am going to try and use. Lets see how it works

Ether 21-08-2012 17:52

Re: Programming Puzzle
 

I don't have LabVIEW here, so I can't say for sure, but I seem to recall that the LabVIEW PID VI has an input where you can tell it that your sensor wraps around, and the VI will handle it for you. Can someone confirm?



baronep 21-08-2012 18:06

Re: Programming Puzzle
 
I was not able to find that, but maybe i'm missing it.

I have drafted up some code that can (using the pt by pt zero crossing vi) count the number and direction of zero crossings and then calculate an integer for the number of full rotations. After that point, it simply multiplies that number by 5 and adds that to the number that it is receiving from the sensor.

From that, I added PID functionality to control the spinning of the motor.

We will see how it works tomorrow

billbo911 21-08-2012 18:56

Re: Programming Puzzle
 
Quote:

Originally Posted by Ether (Post 1182566)
I understood you perfectly clearly. You need to add code to detect zero crossings. You do that with rate checks. If your sensor reads 0.1 in the current iteration, and it read 4.9 in the previous iteration, then the actual reading is 5.1, not 0.1

Can you work from there, or do you need a more detailed explanation?

Again, how large is the sensor's dead zone? You may need a new sensor.


I believe Ether is alluding to the portion of the rotation where the pot has no reading. Many pots only read in a 270 deg. range. This leaves 90 degrees of rotation unaccounted for. Even continuous rotations pots suffer from some amount of non-sensing.
You may want to look into a absolute position encoder if your pot just doesn't work out.

plnyyanks 21-08-2012 19:01

Re: Programming Puzzle
 
Quote:

Originally Posted by Ether (Post 1182576)

I don't have LabVIEW here, so I can't say for sure, but I seem to recall that the LabVIEW PID VI has an input where you can tell it that your sensor wraps around, and the VI will handle it for you. Can someone confirm?

It doesn't look like this functionality is in any of the PID VIs.

However, there is a separate VI that should be helpful (link) and will return a boolean when zero is crossed. (edit: this VI won't function as I first thought - it'll actually check for when a number goes from positive to negative)

Ether 21-08-2012 19:07

Re: Programming Puzzle
 
Quote:

Originally Posted by plnyyanks (Post 1182591)
It doesn't look like this functionality is in any of the PID VIs.

This is from WPILib. Doesn't LabVIEW have something similar?

Code:

/**
 *  Set the PID controller to consider the input to be continuous,
 *  Rather then using the max and min in as constraints, it considers them to
 *  be the same point and automatically calculates the shortest route to
 *  the setpoint.
 * @param continuous Set to true turns on continuous, false turns off continuous
 */


Ether 21-08-2012 19:37

Re: Programming Puzzle
 
Quote:

Originally Posted by Ether (Post 1182592)
This is from WPILib. Doesn't LabVIEW have something similar?

If not, I think this or this would work, where angle error is your desired canon angle (in degrees) minus your sensor reading (converted to degrees).

Then for your PID inputs, use:

setpoint = desired canon angle in degrees

processVariable = setpoint - corrected_angle_error




plnyyanks 21-08-2012 19:38

Re: Programming Puzzle
 
1 Attachment(s)
Quote:

Originally Posted by Ether (Post 1182592)
This is from WPILib. Doesn't LabVIEW have something similar?

Not to my knowledge. Here is the manpage for the basic PID VI we're given. Also, none other more advanced PID VIs seem to indicate that this functionality exists, either.

Bummer, because it'd be nice...


Quote:

Originally Posted by Ether (Post 1182593)
If not, I think this or this would work, where angle error is your desired canon angle (in degrees) minus your sensor reading (converted to degrees).

Yeah, we've done stuff like this in the past when using sensors that will cross zero. Or, I think the VI I linked in my last post could be good, as well. (edit: no, it won't. see my last post)

edit: here's a VI I quickly wrote up that demonstrates both of the methods Ether wrote up: Attachment 12945

Todd 21-08-2012 20:54

Re: Programming Puzzle
 
You could also try using a PID to minimize error, rather than reach a setpoint.

IE: Rather than

My setpoint is currently 4.5 my process variable is at .1

Say

My setpoint is always 0, currently my process variable is -.6 (where -.6 is the circular difference between your 'goal' and your 'actual') then when your goal changes, the frame of reference you use to calculate your process variable changes, and your (probably only proportional gain?) controller will move your motor.

Chris Hibner 21-08-2012 22:45

Re: Programming Puzzle
 
I wrote a vi called HeadingWrap.vi that we've used for autonomous. You can use it to convert an angle outside of +/-180 degrees to be within the +/-180 degree range. You can use it to do what you're trying to do.

This is how it's used: Calculate your angle error into your PID (i.e. desired - actual) and feed the result into HeadingWrap.vi. The output will come out within the +/-180 range and will give you the shortest turn to your desired angle.

You can find it here: http://www.chiefdelphi.com/media/papers/2553 in the sample robot code zip file.

Here's more or less how it works:

Let's say you command your canon to 355 degrees and it overshoots so your sensor reads 3 degrees. For your next PID calculation, your error is 355 - 3 = 352 degrees. This is the problem you've had: it wants to command your canon to do another loop. To solve it, check your error to be within +/- 180. If not, subtract (or add, if the error is negative) 360 degrees. For this case, we subtract 360 so: 352 - 360 = -8 degrees. This will get your canon to head in the right direction by the correct number of degrees.

Here's the basic algorithm:

Code:

Error = desired - actual;
while (abs(Error) > 180)
{
  if (Error > 180)
      Error -= 360;
  else
      Error += 360;
}

You now just have to trick your PID: feed the above "Error" calculation into your setpoint and feed 0 into the process variable.

EDIT: For your application, the while loop is unnecessary. We use it in autonomous since we allow the heading integrator to grow past 360 in both directions (i.e. we don't wrap the heading integral - we just take care of the wrap on the error term as stated above).

Chris Hibner 21-08-2012 23:04

Re: Programming Puzzle
 
While my above post solves your math issue, you may have a bigger problem.

A continuous pot has a gap in which the wiper will not contact the resister band (right where it will flip from 5V to 0V). When that happens, the A/D pin will be at a floating voltage. You may get weird voltage readings in that band depending on how the A/D pin is "wired". Is there a pull-up or pull-down resistor on your board? If not, you should definitely add one so when the wiper loses contact, you have a defined voltage that is either 0V or 5V (not somewhere in between).

Ether 21-08-2012 23:27

Re: Programming Puzzle
 
Quote:

Originally Posted by plnyyanks (Post 1182595)
edit: here's a VI I quickly wrote up that demonstrates both of the methods Ether wrote up: Attachment 12945

Thanks Phil. For any C programmers who may be lurking, here's how to do it in C:

Code:


error -= 360*floor(0.5+error/360);

That converts any angle to the equivalent minimum absolute value, with the correct sign.




All times are GMT -5. The time now is 21:45.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi