![]() |
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? ~ |
| All times are GMT -5. The time now is 04:33. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi