Laview PID.vi continues when event case is False - pid

I'm looking for a way to disable the PID.vi from running in Labview when the event case container is false.
The program controls motor position to maintain constant tension on a cable using target force and actual force as the input parameters. The output is motor position. Note that reinitialize is set to false since it needs previous instances to spool the motor.
Currently, when the event case is true the motor spools as expected and maintains the cable tension. But when the event case state is toggled the PID.vi seems to be running in the background when false causing the motor spool sporatically.
Is there a way to freeze the PID controls so that it continues from where it left off?

The PID VI does not run in the background. It only executes when you call it. That said, PID is a time-based calculation. It calculates the difference from the last time you called the VI and uses that to calculate the new values. If a lot of time passed, it will just try to fix it using that data.
If you want to freeze the value and then resume fixing smoothly, you can use the limits input on the top and set the max and min to your desired output. This will cause the PID VI to always output that value. You will probably need a feedback node or shift register to remember the last value output by the PID.

What Yair said is not entirely true - the integral and derivative terms are indeed time dependent, but the proportional is not. A great reference for understanding PIDs and how they are implemented in LabVIEW can be found here (not sure why it is archived). Also, the PID VIs are coded in G so you can simply open them to see how they operate.
If you take a closer look at the PID VI, you can see what is happening and why you might not get the response you expect. In the VI itself, dt will be either 1) what you set it to, or 2) an accumulation of time based on a tick count stored in the VI (the default). Since you have not specified a dt, the PID algorithm uses the accumulated time between calls. If you have "paused" calculation for some time, this will have an impact on the integral and derivative output.
The derivative output will kick in when there is a change in the process variable (use of the process variable prevents derivative kick). The effect of a large accumulated time between calls will be to reduce the response of this term. The time that you have paused will have a more significant impact on the integral term. Since the response of the integral portion of the controller is the proportional to the integral of the error over dt, the longer you pause the larger the response simply because because the the algorithm is performing a trapezoidal integration over dt.
My first suggestion is don't pause the controller - let the PID do what it is supposed to do. If you are using it properly, then you should not have to stop the controller action. But, if you must pause the controller action, consider re-initializing the controller. This will force the controller to reset the accumulated time term and the response in the first iteration will be purely proportional.
Hope this helps.

Related

Flink trigger on a custom window

I'm trying to evaluate Apache Flink for the use case we're currently running in production using custom code.
So let's say there's a stream of events each containing a specific attribute X which is a continuously increasing integer. That is a bunch of contiguous events have this attributes set to N, then the next batch has it set to N+1 etc.
I want to break the stream into windows of events with the same value of X and then do some computations on each separately.
So I define a GlobalWindow and a custom Trigger where in onElement method I check the attribute of any given element against the saved value of the current X (from state variable) and if they differ I conclude that we've accumulated all the events with X=CURRENT and it's time to do computation and increase the X value in the state.
The problem with this approach is that the element from the next logical batch (with X=CURRENT+1) has been already consumed but it's not a part of the previous batch.
Is there a way to put it back somehow into the stream so that it is properly accounted for the next batch?
Or maybe my approach is entirely wrong and there's an easier way to achieve what I need?
Thank you.
I think you are on a right track.
Trigger specifies when a window can be processed and results for a window can be emitted.
The WindowAssigner is the part which says to which window element will be assigned. So I would say you also need to provide a custom implementation of WindowAssigner that will assign same window to all elements with equal value of X.
A more idiomatic way to do this with Flink would be to use stream.keyBy(X).window(...). The keyBy(X) takes care of grouping elements by their particular value for X. You then apply any sort of window you like. In your case a SessionWindow may be a good choice. It will fire for each key after that key hasn't been seen for some configurable period of time.
This approach will be much more robust with regard to unordered data which you must always assume in a stream processing system.

Netlogo - how to show the final sum of ticks passed

I'm currently working on a simulation where i've programmed turtles to move faster when they reach a specific number of ticks. Given this reason i have to reset the ticks to make the command go over and over again. What i want to do is to see the final sum of ticks that has been run through the entire simulation but with the reset tick command, i can only see how many ticks has been run since the last time i used the move command on my turtles. This makes it impossible for me to use the "monitor" in my interface to show ticks. So how do i see the final count of ticks that has been run since i started the simulation, and not only since the last time it reset the ticks.
To do what you describe, you could create a global variable (say, tickTotal), increment it each tick, and add a monitor to the interface.
But what you should do instead is stop resetting ticks. Instead, use the mod command to control your cyclical response of turtle movement to the tick count.

Timer to represent AI reaction times

I'm creating a card game in pygame for my college project, and a large aspect of the game is how the game's AI reacts to the current situation. I have a function to randomly generate a number within 2 parameters, and this is how long I want the program to wait.
All of the code on my ai is contained within an if statement, and once called I want the program to wait generated amount of time, and then make it's decision on what to do.
Originally I had:
pygame.time.delay(calcAISpeed(AIspeed))
This would work well, if it didn't pause the rest of the program whilst the AI is waiting, stopping the user from interacting with the program. This means I cannot use while loops to create my timer either.
What is the best way to work around this without going into multi-threading or other complex solutions? My project is due in soon and I don't want to make massive changes. I've tried using pygame.time.Clock functions to compare the current time to the generated one, but resetting the clock once the operation has been performed has proved troublesome.
Thanks for the help and I look forward to your input.
The easiest way around this would be to have a variable within your AI called something like "wait" and set it to a random number (of course it will have to be tweaked to your program speed... I'll explain in the code below.). Then in your update function have a conditional that waits to see if that wait number is zero or below, and if not subtract a certain amount of time from it. Below is a basic set of code to explain this...
class AI(object):
def __init__(self):
#put the stuff you want in your ai in here
self.currentwait = 100
#^^^ All you need is this variable defined somewhere
#If you want a static number as your wait time add this variable
self.wait = 100 #Your number here
def updateAI(self):
#If the wait number is less than zero then do stuff
if self.currentwait <= 0:
#Do your AI stuff here
else:
#Based on your game's tick speed and how long you want
#your AI to wait you can change the amount removed from
#your "current wait" variable
self.currentwait -= 100 #Your number here
To give you an idea of what is going on above, you have a variable called currentwait. This variable describes the time left the program has to wait. If this number is greater than 0, there is still time to wait, so nothing will get executed. However, time will be subtracted from this variable so every tick there is less time to wait. You can control this rate by using the clock tick rate. For example, if you clock rate is set to 60, then you can make the program wait 1 second by setting currentwait to 60 and taking 1 off every tick until the number reaches zero.
Like I said this is very basic so you will probably have to change it to fit your program slightly, but it should do the trick. Hope this helps you and good luck with your project :)
The other option is to create a timer event on the event queue and listen for it in the event loop: How can I detect if the user has double-clicked in pygame?

Can I implement PID control directly on velocity along axis for a quadcopter

I am making an automated quadcopter: no radio transmitter-receiver and the quacopter flies on its own with pre-programmed orders.
All most all quadcopter implement PID on throttle/yaw/pitch/roll as these 4 axes are directly on an remote controller. However this is a bit inconvenient for an automated one without a controller. As an automated quadcopter without user input, velocities along x/y/z axis are of more concern, because:
keeping balance(yaw/pitch/roll=0) doesn't mean keeping still, as first, there will be some error in manufacture so it might still have some acceleration. Second, even there's no acceleration, it can have speed, causing it to drift in space. And as there's no user input, it can not fix the drift on it's own. Besides, if there's wind, it might got blow away, even it thinks it's balanced.
Orders are mostly given in "go to position(x,y)" or "keeping velocity x, fly above position(x,y) and start camera video capture." or so. These orders can't be translated into yaw/pitch/roll directly.
So basically I have two ideas:
Implement PID on yaw/pitch/roll/height and use a second PID loop to control velocity. The second PID loop take desired velocity and current velocity as input and output desired yaw/pitch/roll for first loop.
Implement PID directly on velocity. The pid loop take desired velocity and current velocity(by integrating acceleration from accelerometer) as input and output PWM width for 4 motors.
Have anyone tried idea 2? Will this work?
PID maps a measured value to a controlled value. If you can sense velocity reliably, you can use it to drive a PID. However, integrating an accelerometer won't give you a reliable enough velocity. Any sensing errors will compound through the integration and could grow your velocity estimate unbounded.
The R/P/Y PIDs on a quadcopter don't control the PWM to the motors directly, they control the roll, pitch, and yaw rates, then convert the rates to thrusts, then convert the thrust components for the various motors, then convert the thrusts into PWMs. See ArduPilor MotorMatrix code for hints.
You can put PIDs anywhere you like in the process between whatever is choosing the velocity and the motors, but you likely need some intermediate control/state variables between 'velocity' and 'PWM[1-4]' to balance things and have coordinated flight.

Timing while a value is true in Labview

I have been making a labview program for kids to moniter energy production from various types of power sources. I have a condition where if they are underproducing a warning will fire, and if they are overproducing by a certian threshold, another warning will fire.
I would like to time how long throughout the activity, each type of warning is fired so each group will have a score at the end. This is just to simulate how the eventual program will behave.
Currently I have a timer which can derrive the amount of time the warning is true, but it will overwrite itself each time the warning goes off and on again.
So basically I need to to sum up the total time that the value has been true, even when it has flitted between true and false.
One method of tabulating the total time spent "True" would be exporting the Warning indicator from the While-loop using an indexed tunnel. If you also export from the loop a millisecond counter value of when the indicator was triggered, you can post process what will be an array of True/False values with the corresponding time at which the value transitioned.
The post processing could be a for-loop that keeps a running total of time spent true.
P.s. if you export your code as a VI snippet, others will be able to directly examine and modify the code without needing to remake it from scratch. See the NI webpage on the subject:
http://www.ni.com/white-paper/9330/en/
I would suggest going another way. Personally, I found the code you used confusing, since you subtract the tick count from the value in the shift register, which may work, but doesn't make any logical sense.
Instead, I would suggest turning this into a subVI which does the following:
Keep the current boolean value, the running total and the last reset time in shift registers.
Initialize these SRs on the first call using the first call primitive and a case structure.
If the value changes from F to T (compare the input to the SR), update the start time.
If it changes from T to F, subtract the start time from the current time and add that to the total.
I didn't actually code this now, so there may be holes there, but I'm leaving that as an exercise. Also, I would suggest making the VI reentrant. That way, you can simply call it a second time to get the same functionality for the second timer.

Resources