Hi all,
first of all - while I know enough 'C' to be "dangerous", I am not C++, C#, etc. junkie - so...

I looked over ArduPilot code and at least to me it looks like 'linear execution' - i.e. i don't see anything happening in parallel. For example, while GPS data is being read, code does just that - there is no input being read from other sensors, or acting on any controls, etc. Another example is when PID loop is being updated, nothing else is going on (i.e it would be nice if GPS is acquiring next set of data, etc.).
Is my assessment correct? In this environment, is it possible to do parallel execution (akin to multithread...)? Obviously code works as demonstrated by Chris and Jori...my question goes more into the realm of performance - is it really fast enough for real time performance?

Does code 'works' as i described it (remember I am not 'C' guy and might be reading it wrong)?
I am NOT trying to dis(spl?) the code -it's just a question ! In my day job, for system control purposes I use other environments where parallelism is almost 'given' for tasks....

Views: 192

Reply to This

Replies to This Discussion

No worry. One task is done at a time, serially, and all tasks run in loop. This is so fast that each task gets its time.
For example, GPS reading takes 2ms (if there're new data available). PID computations take ~1ms. So loop runs maybe 500 times/second,
Assuming that GPS sends update at 1Hz, processor needs to act just once each second. So its capacity is more that needed. It can safely do the navigation task in simple loop, one step after another.
That's the big difference between microprocessor programming and programming on systems with an operating system. Here, like most embedded systems of this class, there is no OS, realtime or otherwise, to handle multithreading. We program "straight to the iron", which allows us to use cheap, low-power chips and have total control over timing.
I am glad to see that my question wasn't taken the wrong way.

@MichalB - I see what you mean, and I agree, read operation taking 2ms is not a lot. Maybe GPS was bad example on my part, although it brings a related question - if GPS data is available once per second (1Hz) , that means that it's not available to controller to act upon for slightly more then a second in best case scenario (operations example: "accumulate" GPS data buffer + transfer data from buffer+ parse buffer., etc.), which might (or might not be) a long time...I am thinking in scenarios where rapid course correction would be needed as in strong wind, or gust of wind, etc. Am I completely off-base here (or this is the reason for some of the posts I read regarding GPS at 5Hz.)?

@Chris - I understated that there is no OS, and am somewhat familiar with PICs and their environment (although I want to learn more). I do like "programming straight to the iron" phrase - that should be on a T-shirt.
However with respect to "...and have total control over timing" part I think we might be talking about different timing, if I understand you correctly. I am not talking about OS timing which can play all kind of nasty non-deterministic games. Timing of operations I was referring to is more in the line of linear, or serial, flow - i.e. while controller is doing one thing it does not do something else. Or, it's doing step1 , and after it's done with it then it does step 2, and when it's done with it does step 3, etc. So from time perspective after step 1 is done it has to wait until all subsequent steps are finished until it can "run" again.
That is why I asked if in this environment, is it possible to do parallel execution - and by 'this environment' I mean PIC on ArduPilot board. For example in LabVIEW (since it was brought up few times in different threads), you can put two While loops (do-while) one next to each other and they would execute in parallel independent of each other. I was wondering if same, or similar, can be done here (PIC environment).
Note that on most CPUs, multithreading is done by slicing CPU time to particular thread (or task), so CPU executes just one code path a time, although from program's perspective, multiple tasks are run simultaneously. Advantage of such hardware multithreading is that CPU' state is saved during task switch, so each task runs continuous program flow.

In single thread CPU's such as ATMega168, it's programmer's task to make sure that more tasks run in parallel.
Taking example of GPS data received at 1Hz, don't think that CPU just sleeps in meantime. The program stores GPS reading state, while executing any other tasks.
So although ArduPilot runs in single thread, it runs main loop very fast, and in each loop it performs tasks which are ready to be run. This may be parsing GPS if data are available, computing PIDs and sending servo out if it's time to do, reading IR sensor and providing stabilization, or sending telemetry if it's time to send it. Add anything else that you'd wish it to do, and there's still enough processing power.
As a side effect, it is also very easy to perform a schedulability analysis as the Worst Case Execution Time (WCET) are easy to figure out
Michal answered very well, but I'd just add that we use the AVR's superior hardware to help avoid waiting for stuff. Not just the UART buffer but also the interrupts and registers, in the case of PWM reading and writing. We considered PICs in the early days and decided that the AVRs were a more modern and superior architecture. Plus, it's what Arduino is based on, and that means we can coattail on a terrific open source development environment and big community.
Just to add a little more to the explanation, in your LabVIEW example, the interface gives you the impression that the two while loops are running in "parallel," But a single CPU is still only processing one instruction at a time. LabVIEW is really alternating back and forth between instructions from one while loop, and instructions from the other. As Michal B said, multithreading in a CPU happens by slicing the CPU time, and that only one thread is being processed at a time. On the arduino, we have to slice the CPU time up manually, so we specify the order of things that should be done, which appears to be very linear. This linear section of code loops over and over again though at a rate fast enough so that all the things done appear to happen in "parallel."

After doing Step 1, it does have to wait for the subsequent steps to complete before running Step 1 again, but all of the steps take place is a short enough time that you can look at it like each step is run at a regular interval (on the order of milliseconds). When more steps are added, the rate at which each step is executed slows down a little, so we have to limit the number of steps based on what a reasonable execution rate of each step is.
While there is no OS, there are interrupts and timers which produce interrupts, and so as a consequence, there are many things which can be operating simultaneously. The 6 PWM sub systems are running parallel to other tasks, as are the UARTS etc... The code could be written to service these functions via interrupts, or it can be written to plod through and service every possible event in a loop. It is my opinion that the interrupt-driven solutions can be much faster.

Reply to Discussion


© 2018   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service