![]() |
switching between Teleoperated enabled and Wathcdog notfed
Hey All! I need some more help :rolleyes: I was working on the program today and after programming my solenoids I built the program and ran it has startup on the robot. Well I logged into FRC driver station and it is switching between Teleoperated enabled and watchdog not fed. How do I fix this? it is a slow alternating maybe once every second.. Thanks guys!
|
Re: switching between Teleoperated enabled and Wathcdog notfed
From that evidence I'd say you have a section of your Teleop that takes a long time to complete, usually a loop or a timed delay, and the Watchdog is not being fed on a timely basis.
The solution depends on how the delay is being caused. If the delay is too long, then your driver controls will also respond slowly and that can be a danger. That's sort of what the Watchdog is intended to warn you of. |
Re: switching between Teleoperated enabled and Wathcdog notfed
Well here is what I am attempting to do. I want solenoid one to open and then stay open for a length of time, and then close. and then I want solenoid 2 to ope. immediately after solenoid one closes. in turn it will make the kicker(our cylinder) go out and then come back in before two seconds so we don't get the penalty for having something outside our framer perimeter for more then 2 seconds. Thanks
|
Re: switching between Teleoperated enabled and Wathcdog notfed
You could write this as a state machine in Teleop.vi or you could write it as a sequence in Periodic.vi
It's probably clearer to visualize as a sequence structure in Periodic.vi |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
As for "sequence in Periodic vi" I'm not as sure. Here's what I think you mean, in pseudo-code (with line numbers for reference): 10 loop: 15 loop1: 20 watchdog_delay_and_feed(some reasonable polling value, say 40ms?) 25 if you haven't received a kick command from teleop, goto loop1 30 do something here 35 watchdog_delay_and_feed( 2 seconds) 40 do something else here 45 clear the kick command 50 goto loop Is the above a possible implementation of what you are suggesting? If not, could you give more details please. If so, I have some questions/comments: The infinite loop (lines 10 and 50) means that this task never terminates. So in that sense it's not "periodic", even though it uses the "machinery" of the periodic vi in the framework. true? The watchdog delay and feed in line 20 is required so that this "periodic" task does not consume all the CPU resources. It releases the CPU to go do other things. The RTOS recognizes this command as an opportunity to take resources away from this task and use it for other tasks. Is this anywhere close to true? How does the RTOS know when to return to this task? Does the "watchdog delay and feed" command cause the RTOS to suspend the task and set some sort of timer event to wake it back up again? What's the best way to pass a "kick command" (lines 25 and 45) to this task? Some have suggested using a simple global boolean. What are the benefits/drawbacks of doing this? What are the advantages of using other approaches? Our team is brand-new to LabVIEW this year, and they have zero prior knowledge/experience with real-time control. I am trying to teach them some fundamentals in language they can understand, but I am hampered by the fact that I know absolutely nothing about LabVIEW and am having difficulty relating it to the real-time knowledge I already have from working with embedded reatime projects using assembly language and C. Thanks. ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
1 Attachment(s)
You have the essentials in your pseudo-code example.
There is one point that differs and that's with the use of the Watchdog. The Watchdog should not be fed in a periodic loop. That'll end up defeating the purpose, in that the Watchdog will become a Watchdog only for that one Periodic task and not for anything else. It would never time out anywhere once you get your Periodic loop running properly, since this is a parallel task. The Watchdog should be constrained to the primary Autonomous and Teleop data paths or sub vi's of those. Instead a Timer vi is used. At the conclusion of the Timer it goes back on the OS task queue. No long loop anywhere in our code should run unconstrained. They should all have at least a 10ms timer delay, so they don't prevent other concurrent actions. This has been the cause of many "sluggish" controls complained about by teams (it's the field's fault:rolleyes:). I knocked off an example (untested) to illustrate the point in a LabVIEW context. It includes two different ways to "kickoff" the sequence:
Quote:
The Periodic Tasks vi does not get called periodically, it's only called once and the loops define for themselves what the period is for each parallel task within that vi. |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
I was somehow stuck in the mindset that the period was controlled by the RTOS. I suppose if I had actually learned a little LabVIEW it would have been obvious. Your comment about not feeding the watchdog also makes perfect sense. Now, about the Timer vi: when LabVIEW encounters a Timer vi in TaskA, it generates code that suspends TaskA? So the CPU is then free to go service other Tasks that are waiting to execute? And a timer is set by the RTOS to alert it when it's time to go back and service TaskA? (or some logically equivalent mechanism?) If all the above is correct, it sounds like cooperative multitasking, and I'm trying to imagine how the framework manages task execution when there are several "periodic tasks" with different periods. I had somehow imagined that these would be preemptively serviced in a rate-monotonic fashion, but I guess that's not what happens? For example, let's say there are two periodic tasks: TaskA 5ms TaskB 100ms ... and TaskA takes 2ms to complete (40% CPU usage), and TaskB takes 30ms to complete (30% CPU usage). That's only 30+40=70% CPU usage, and yet TaskA will not run at 200Hz because it cannot preempt TaskB which takes 30ms to run. Is that correct? ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
The multi-tasking LabVIEW environment gets even more complicated when you recognize that vi's are operating in parallel and in fact operations within vi's are also operating in parallel.
There's nothing unique about Periodic Tasks.vi that's given it and all the tasks within it priority over Teleop.vi or Vision Processing.vi, etc. In my example posted above the four Refnum Gets are all parallel tasks synchronized only by the While loop data tunnels. Everything's clamoring for scheduled CPU time and somebody's going to have to wait sometime. It's non-deterministic in this framework. There are some low-level non-RT calls made too, but for our FRC purposes think of it as close-to-RT. The timer alerts the task scheduler when it needs servicing again. In fact you can use a timer with zero time just to break a task out of the CPU and send it to the back of the scheduler queue. |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
Quote:
Quote:
Quote:
~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
I'm responding for the masses too :)
|
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
In your case the 5ms timed loop will repeat every 5 ms or as soon as the task scheduler allows after 5ms are up.
The timer vi counts down from the moment it is started, and usually that's co-incident with the loop starting. Using the example I posted above each use of the timer is a parallel task so it runs at the same time as all the other stuff within the loop. For instance, the outer loop begins as soon as the four data tunnels in the outer wall are satisfied. These actions then occur in parallel:
Now if all that other stuff (the inner Case statement and loop) finish sooner than 100ms. The outer loop will be waiting for that 100ms timer. If all that other stuff takes longer than 100ms (it likely will when you kick because a motor is involved, and likely won't when you don't kick), then the timer will be long done by the time everything finishes and the outer loop proceeds to the next loop. Look also at the first frame of the flat sequence structure. The solenoid release and the timer start simultaneously. So that frame will only take 10ms to complete before moving on to the next frame. A typical solenoid might take 5ms to open fully, so you'd better verify that 10ms is long enough to wait for a solenoid and cylinder to release a latch. If you have a large cylinder on that latch better up the timer to 20ms. |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
- At time t=0 the CPU encounters the 5ms timer vi so the CPU goes away and does something else. - When the CPU comes back to execute the code it is now t=5ms. - the code takes 1ms to execute. It is now t=6ms. - the task loops back to the beginning and encounters the 5ms timer vi again. The CPU goes away for 5ms, and when it comes back, it is now t=11ms. - the code now starts executing again at t=11ms. Therefore, the period is 11-5 = 6ms, not 5ms. What is wrong with the above argument? ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
The parallelism of the two tasks within the loop task has to be taken into account:
The timer task starts and goes away for 5ms The 1ms task starts and finishes, then it too goes away The loop task rests as all it's internal tasks are not yet satisfied, but it has nothing to do The CPU wakes up the loop task when the 5ms timer expires The loop task sees that all it's tasks are accomplished and moves on The timer task only stops itself. It doesn't stop tasks around it. It really sets a timer interrupt. If the Timer task expires and the loop task is still active because of other independent tasks within it the CPU doesn't have to wake it up and it doesn't get scheduled. |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
So it looks like this (assuming the 5ms task is the only task in the system): - at t=0 the CPU encounters the 5ms timer which re-queues the task to run again at t=5ms (or as soon thereafter as possible) - the CPU then continues on in the task to execute the task's code, which takes 1ms. - the task is finished; it is now t=1ms. the CPU goes idle until t=5ms - at t=5ms, the scheduler gets the task from the queue and runs it again Is the above correct? If so, then the user, when coding a periodic task, should NOT put the task in an infinite loop, as my original pseudo-code did. Instead, the task should be coded as a one-shot, because the timer vi re-queues it each time it is run. Correct? ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
The key here is to understand that both the wait task and the other code in the .vi run in parallel.
If your code took 5 ms to run, and you put a 5 ms wait timer in, absolutely nothing regarding program timing would change. The actual code would finish running just as the wait timer expired and would start running the loop again. If your code takes longer than 5 ms to run, say 7 ms, then your code would finish and start over again. The "wait" function does not mean finish the code then wait. It means to wait 5ms before asking that code to run again - from the time you last asked it to start running. |
Re: switching between Teleoperated enabled and Wathcdog notfed
1 Attachment(s)
Quote:
I think the main hangup is that EVERYTHING is a task to LabVIEW. P.S. Trick question: How many tasks do you see in the attached? I see three. P.S. My mistake, four. |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
A few questions: 1) The "wait" function mentioned above, and the "Timer vi" mentioned by Mark... are you both referring to the same thing? The thing with the icon that looks like a clock? 2) In my post to which you replied, was my conclusion correct that the periodic task should be coded as a one-shot, and not wrapped in an infinite loop? and finally 3) Are you sure that it means to wait 5ms from the time you last asked it to start running? Or is it 5ms from whatever time it is when the CPU encounters the request to re-schedule? ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
i.e. "assuming the 5ms task is the only task in the system" and "the CPU goes idle" etc. By using an extremely simple example I was hoping to be able to frame clear and unambiguous questions. I need a rock to stand on. Once I've got that rock to stand on, I think I can envision how it works in a multi-task environment. Quote:
Thanks for dialoging with me. If I haven't worn out my welcome I would appreciate it if you could hang in here for just a bit longer. I sense that "aha" moment is imminent... ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
I've been reading and re-reading the above post and I think I may have had an epiphany. Is this any closer to the truth: - the 5ms periodic vi has two parallel "tasks" in it: a 5ms timer, and some code that takes 1ms to execute - this 5ms periodic vi gets called once to kick-start it - the first time the 5ms periodic vi gets called, the CPU encounters the 5ms timer task and executes that... which basically just sets a timer interrupt to occur 5ms in the future. - the CPU comes back and starts executing the 1ms "task", and finishes it. - since the 5ms timer task hasn't finished yet, the 5ms periodic vi can't "finish". The CPU goes and does something else. - when the 5ms interrupt occurs, this basically completes the 5ms timer "task", so the periodic vi is now "finished" - in this scenario, it is required to make the periodic vi loop back and start again Is the above even remotely correct? ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
I was not referencing my example, I was referencing your example. Your example, as stated, has more than a single task in it. I think that's where the blind spot lays. Here's the simplest example of a task you can have in LabVIEW:
|
Re: switching between Teleoperated enabled and Wathcdog notfed
I'm playing catchup with crossing posts, but yes I think you've got it.
The only change I'd make to your thinking is the line: - the CPU comes back and starts executing the 1ms "task", and finishes it.Think of both the 5ms Timer and the 1ms Task as starting simultaneously. There is no rule that says one must start before the other, or which starts first. Quote:
|
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
1. Yes 2. Yes 3. To the best of my knowledge that wait timer starts at the same time the vi executes. If it waited to start until after the cpu re-requested it to schedule, your actual wait time would be the vi processing time + the wait time, which isn't the case. Does that make sense? |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
Let's call "the completely blank vi" the "5ms periodic vi" since it's no longer blank. This 5ms periodic vi has inside it an infinite while loop (is that the right way to say it?) Inside the infinite while loop are two tasks: 1) a 5ms timer task, and 2) a 1ms task Assuming the above is correct and I haven't mangled anything yet, Something has to initially "call" (is that the right word?) the 5ms periodic vi to kick-start it. Is that correct? Once started, it will run forever (until some other process stops it) because it contains an infinite loop. OK so far? Both "tasks" within the infinite while loop must complete before the loop can loop back and re-start. Yes? Since the 5ms timer task doesn't "complete" until the 5ms timer expires, that establishes the period of the 5ms periodic vi. How am I doing? The 5ms timer task is implemented as an interrupt (or some other mechanism) that allows the CPU to go do something else while the 5ms is ticking away. That allows the CPU to run the 1ms task while it's waiting for the 5ms timer task to complete. Still OK? When the 5ms timer expires, the 5ms timer task is now complete, and, since the 1ms task has also completed (since there are no other tasks in this simple example which would prevent it from doing so), all two of the tasks in the 5ms periodic vi are complete, so the loop re-starts. Please tell me I'm close. Now, my questions: 1) It seems, in the above example, that it is important that the CPU somehow knows to start the 5ms timer task first, and then go run the 1ms task. If instead it ran the 1ms task first, wouldn't that task have to complete before the 5ms timer task even got started? Then the period of the 5ms periodic task would not be 5ms. Is the location of the graphics within the the diagram the key to telling LabVIEW in what order to execute? 2) Now, if there are other tasks in the system (besides those enumerated in this simple example), and if the CPU happens to be busy with some other task when the 5ms timer task completes, then the loop does not re-start right away, correct? It has to wait until the CPU finishes whatever it is doing? AND... any such delays are cumulative; ie the system doesn't compensate by short-cycling the next loop. So the effect of other tasks is not to create jitter, but rather to reduce the effective frequency of the 5ms periodic vi. True? ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
It's got to start one or the other. Quote:
Does LabVIEW somehow "know" that if a vi contains a timer task, it should be executed first? ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
I've done my best to catch up to this thread, and progress is definitely being made, but let me add in a few points.
LV VIs execute by adding tasks to a queue when they are ready for execution. All tasks on the queue are guaranteed to be safe to execute in any order because they will satisfy the data dependencies in the user's code. OS threads are used to execute the tasks on the queue and to preempt back and forth between them. Using the 5ms wait and 1ms task, when the VI begins, one task will be placed onto the queue -- the while loop itself. The while loop code will test the exit condition, increment i, and will then schedule two additional tasks and remove its task. One of the two tasks will be the 5ms wait, and the other will be the sequence of code that takes 1ms. Since the user didn't specify which to run first, the compiler enqueue the tasks in either order. Graphical location has no impact on the order, but creation order may. The code for the wait will schedule itself with a worker thread to be removed from the queue for 5ms and then queued up again. The 1ms sequence will then be the only code on the queue, and the OS threads will run that task. As each task completes, it decrements a counter and conditionally schedules the end of the while loop when the counter goes to zero. Of course the code is almost never that simple, but it scales quite well. Add many loops or tasks to the queue, and the same system still works. As you noted, the loop with a time delay is not necessarily the most deterministic way to write your code. This is the easy and succinct way to write it, and for FRC, it is likely good enough. A more specific way to write it would be to note the time that the loop begins, then run the task, then subtract to measure the time before the loop should begin again and sleep the delta. Fortunately, this is built into the loop on the palette called the timed loop. It is very capable and even lets you balance priorities, modify loop rates, measure jitter and many other tasks well-suited to writing a realtime task and probably not needed for most FRC tasks. Greg McKaskle |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
Therefore, it doesn't matter what order LabVIEW queues the 5ms timer task and the 1ms task because the OS will "run them both". In the 2010 FRC LabVIEW framework, what algorithm does the OS use to decide what task to run and how long to run it? Is it a simple time-slice with equal slices for all queued tasks? Or does the OS look at deadlines and give priority to tasks whose deadlines are imminent? ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
Typical LV tasks do not have deadlines. The realtime loop may, don't really know the details.
Greg McKaskle |
Re: switching between Teleoperated enabled and Wathcdog notfed
At this point what I think you really want to know about is how the cRIO VxWorks OS handles it's end of things.
http://download-book.net/vxworks-pro...e-pdf-pdf.html |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
Thanks for the link though; I will take a look. It's been many years since I've read any of WindRiver's stuff ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
Ether, I'm still not sure you've got an appropriate context for the way you're trying to understand things. A lot of the questions you ask are fine from a procedural point of view, but that's not really relevant to how a LabVIEW programmer should be looking at it.
This is a data flow language. Each function runs as soon as all of its inputs are available, and provides its outputs when it is finished. Wires carry data from one function to another, and it is the flow of data which determines which functions can run next. Groups of functions collected inside a case or while or other block must all finish before the block is satisfied. That's all you need to know in order to understand the 5ms periodic loop example. |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
Quote:
Having said that, let it be known that I am an avid reader of your posts and have learned much from them, which I freely share with our programmers. A sincere thank you for you willingness to be so helpful. ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
This is a valid lesson in model versus implementation. The model of the LV diagram is the straightforward one given by Alan. The implementation across a wide variety of OSes and architectures will of course vary from the model.
Both POV's are very useful. The simple model view lets you efficiently use the tool to write lots of good code quickly. The underlying knowledge of the RTOS and architectures is useful if you work on the LV team or if you are trying to coax the most from it. Focus too much on the details, and you lose sight of the model. Greg McKaskle |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
The benefit of an underlying knowledge of what is actually happening "under the hood" goes beyond working on the LV team or coaxing the last ounce of performance. It is also useful in understanding the limitations of the model, for example under what conditions will a 5ms task and a 50ms task "play nice". I want the students to come away from this with at least a hint of understanding of how a single computer can (seemingly) be doing two (or more) things at once. ~ |
Re: switching between Teleoperated enabled and Wathcdog notfed
Hopping back and forth between threads, I realize I forgot my main point in writing this. Focus too much on the implementation, .... Good engineering involves jumping between simplistic models and imperfect implementations and using measurements to validate results against the predicted results.
It sounds like you are exposing the students to a very good mix. I hope my info is helping. Ideally, I'd have the time to write VIs that measure and demonstrate the behavior. Greg McKaskle |
Re: switching between Teleoperated enabled and Watchdog notfed
Just to round things out for anonymous readers...
On the cRIO, as LabVIEW sets up all these independent tasks and passes them to the VxWorks operating system, each task gets scheduled for execution based on an assigned priority. LabVIEW allows a fixed enumerated set of priorities, however, VxWorks task priorities are 0-255. "normal priority" is the default for our team code in the LabVIEW framework, but that can be changed on a vi basis if you know what you are doing (don't do this at home! :eek: ). Remember too that LabVIEW tasks are not the only things being scheduled for attention by the CPU. There are standard OS functions, a mixture of high and low priority tasks, that also need their time. Once a task has been started it can execute to completion if it is very short or if the CPU has nothing else to schedule (rare). More often a long task is assigned a fixed slice of time on the CPU, then rotates out to give another task it's share of CPU time, then rotates back in later to get a little more done. That's why multiple tasks appear to the casual observer to run simultaneously, and why we say it's easier to think of them as happening simultaneously. Their execution is actually interleaved with fellow tasks. This gets complicated by interruptions from higher priority tasks, and lower priority tasks are not completely starved by higher priority tasks. Usually, part of the scheduling algorithm includes how long a low priority task has been shutout of the CPU. If the CPU is full up with non-stop high priority tasks, a low priority task that has been waiting and waiting will eventually be allotted some time-essentially by having it's priority temporarily increased for a short time. There are also cases where a low priority task will lock an important system resource that a higher priority task is next in line for. In that case the low priority task will get it's priority temporarily bumped up to match the high priority task until the system resource is released, then it goes back to lowly priority status. On multi-core processors (not the cRIO) the tasks get further scheduled across the multiple processors available. |
Re: switching between Teleoperated enabled and Wathcdog notfed
Quote:
I wonder if what you described above is indeed the way the code generated by LabVIEW sets up the RTOS multitasking, assuming the programmer is using the 2010 FRC LabVIEW framework in the "standard" way (i.e. following the examples of the default code and templates). ~ |
| All times are GMT -5. The time now is 01:33. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi