Embedded system: How to identify required tasks/threads? - c

I'm studying embedded programming, so I'm new in this field.
Can someone explain how to identify tasks/threads from given system description. Also, how can I estimate timing constraints, execution times... I'm really stuck.
Here is system description I'm working on:
Implement a 2 degree of freedom servo motor system. A two-axis joystick is used for controlling servo motors. Additionally, enable recording and reproducing the user path of the joystick, so that identical movement could be replicated multiple times. It is necessary to support the recording of 3 motion profiles with a length of at least 5 minutes. The profile needs to be recorded to a non-volatile memory, and the recording/playback control via the joystick button. Provide appropriate signalling for the current selected profile and operating mode (recording / playback) using one LED for each profile. In the RT-Thread system realize the necessary drivers on the Raspberry Pi Pico platform as support for the devices used and the application itself that implements the described system with clear separated threads for each of the observed functionalities.

It is tempting to partition functionally, but in practice you should partition based on deadlines, determinism and update rates. For simple systems, that may turn out to be the same as a functional partitioning. The part:
clear separated threads for each of the observed functionalities
May lead you to an inappropriate partitioning. However that may be the partitioning your tutor expects even if it is sub-optimal.
There is probably no single solution, but obvious candidates for tasks are:
Joystick reader,
Servo controller,
Recorder,
Replayer.
Now considering these candidates, it can be seen that the joystick control and replay control are mutually exclusive, and also that replay itself is selected through the joystick button. Therefore it makes sense to make that a single task. Not least because the replayer will communicate with the servo controller in the same way as the joystick. So you might have:
Joystick reader / replayer,
Servo controller,
Recorder.
The recorder is necessarily a separate thread because access to NV memory may be slower and non-deterministic. You would need to feed time and x/y position data in a message queue of sufficient length to ensure the recording does not affect the timing motion control.
It is not clear what king of servo you are using or if your application is responsible for the PID motion control or simply sends a position signal to a servo controller. If the latter, there may be no reason to separate teh servo control from the reader/replayer. In which case you would have:
Joystick reader / replayer / Servo controller,
Recorder.
Other solutions are possible. For example the recorder might record the servo position over time rather the joystick position, and have the servo controller handle replay.
Joystick reader,
Servo controller / replayer,
Recorder.
That makes sense if the Joystick polling and Servo update rates differ, because you'd what to replay what the servo did, not what the joystick did.

Related

How to get specific values (eg. battery2, servo outputs) available in Mission Planner through Dronekit?

I am currently using dronekit-python to implement somewhat of a Mission Planner clone, as an API. I've generally been able to replicate most important features from Mission Planner; however, some features don't seem to be present.
One such feature is reading live servo outputs, which can be done in Setup > Mandatory Hardware > Servo Output (image below). I have been able to emulate getting/setting the output's function, min, trim, max, and reversed values through parameters. However, I cannot seem to access the live position values through dronekit. How would you go about this?
A second feature is reading specific values from the plane, beyond the class attributes present. This is available in Mission Planner when double-clicking a value in the Quick pane in order to change what measurement is displayed (image below). For my use case, I'd like to specifically access battery_voltage2 and battery_remaining2, as these are vital measurements for our system. I tried using vehicle.battery in dronekit, but this seems to only display data from battery 1. Any ideas?
Thank You so much for the help!
It might be possible to get the battery information and other information from the drone by using Mavlink messages. For battery information, look at the BATTERY_STATUS (#147) Mavlink message. For servo information, look at the SERVO_OUTPUT_RAW (#36) message.
In order to receive these messages, look into using message listeners from dronekit-python. You should be able to receive and parse the Mavlink message.
In general, you can use message listeners and the dronekit-python message factory to receive and send Mavlink messages, which allows you more control than some of the built-in dronekit functions. If you decide to control the drone this way, though, be careful because it's pretty easy to mess up your logic and have the drone behave unexpectedly.
Hope this helps!

What scheduling should I choose for my program on a FreeRTOS system?

I have a project (a 2-player game) made in FreeRTOS. The game has 3 tasks
(Game Render, Joystick Task and a PC Serial Communication).
Shared resources include:
Player 1 and Player 2 locations/coordinates. They are manipulated by Serial and Joystick task respectively. The game render reads both of these locations and displays them. (Player 1 location is shared with Game Render and Player 2 with Game Render).
A queue that is shared between the game render and the serial task (sending data and getting acks); the queue has been protected with a mutex on all write operations.
My question is which of these 2 scheduling is more suitable for this project: Rate Monotonic or Deadline Monotonic?
The tasks are not independent in a way that the serial communication uses acks? I think it should be Deadline Monotonic but not entirely sure?
To choose between DMS and RMS you need to know periods and deadlines for each task. From my experience it is better to focus on good overall design first and then measure and tweak the priorities to achieve best response times.
On of best summaries of good design principles I've encountered is this. In your case I would represent the two players as 'active objects' with own input event queues. Send event to the players from serial task, or even directly from ISR. The game render would then also be an AO receiving events from players, or a mutex-protected resource - it depends on what the render output is (how long does it take mostly). Serial input and serial output should be considered two separate things - in most cases it doesn't make sense to conflate the two.
Here is another link that might be useful - look at '1.4 The Design of the “Fly ‘n’ Shoot” Game'
Also, you don't need a mutex lock for xQueueSend and for sending from ISR you only need to use xQueueSendFromISR.

ArduPilot, Dronekit-Python, Mavproxy and Mavlink - Hunt for the Bottleneck

I have Ardupilot on plane, using 3DR Radio back to Raspberry Pi on the ground doing some advanced geo and attitude based maths, and providing audio feedback to pilot (rather than looking to screen).
I am using Dronekit-python, which in turn uses Mavproxy and Mavlink. What I am finding is that I am only getting new attitude data to the Pi at about 3hz - and I am not sure where the bottleneck is:
3DR is running at 57.6 khz and all happy
I have turned off the automatic push of logs from Ardupilot down to Pi (part of Mavproxy)
The Pi can ask for Attitude data (roll, yaw etc.) through the DroneKit Python API as often as it likes, but only gets new data (ie, a change in value) about every 1/3 second.
I am not deep enough inside the underlying architecture to understand what the bottleneck may be -- can anyone help? Is it likely a round trip message response time from base to plan and back (others seem to get around 8hz from Mavlink from what I have read)? Or latency across the combination of Mavproxy, Mavlink and Drone Kit? Or is there some setting inside Ardupilot or Telemetry that copuld be driving this.
I am aware this isn't necessarily a DroneKit issue, but not really sure where it goes as it spans quite a few components.
Requesting individual packets should work, but that was never meant to be requested lots of times per second.
In order to get a certain packet many times per second, set up streams. A stream will trigger a certain number of times per second, and will then send whichever packet is associated with it, automatically. The ATTITUDE message is in the group called EXTRA1.
Let's suppose you want to receive 10 ATTITUDE messages per second. The relevant parameter is called SR0_EXTRA1. This defines the number of Attitude packets sent per second. The default is 4. Try increasing that parameter to 10.

Charging Indicator for Battery (Battery Monitor)

We see in all today electronic devices like mobile a Visual battery charging indicator,that a graphical Container composed of bars that increases one by one when the battery is charged for long, and decreases one by one when the mobile is used for long time.
I see the same thing laptop in every GUI operating system like windows and Linux.
I am not sure whether i am posting in the right place, because this requires a System Programmer and Electrical Engineer.
A Visual view of my Question is here:
http://gickr.com/results4/anim_eaccb534-1b58-ec74-697d-cd082c367a25.gif
I am thinking from long long ago , under what logic this works?
How the Program is managed to Monitor the battery.
I made a simple logic based on Amps-hour, that how much time the bar should increase when the battery is in charging mode.??? But that does not work perfectly for me.
Also i read a battery indicator Android application source code of my fried, but the function he used were System Calls based on Andriod Kernel (Linux Kernel).
I need the thing from the scratch....
I need this logic to know............. Because i am working on an Operating system kernel project, which later on will need battery charging monitor.
But the thing i will implement right now is to show just percentage on the Console Screen.
Please give me an idea how i can do it.... Thanks in Advance
Integrating amps over time is not a reliable way to code a battery meter. Use voltage instead.
Refer to the battery's datasheet for a graph of (approximate) voltage vs. charge level.
Obtain an analog input to your CPU. If it's a microcontroller with a built-in ADC, then hopefully that's sufficient.
Plug a reference voltage (e.g. a zener diode) into the analog input. As the power supply voltage decreases, the reference will appear to increase because the ADC only measures voltage proportionally. The CPU may include a built-in reference voltage generator that you can mux to the ADC, or the ADC might always measure relative to a fixed reference instead of rail-to-rail. Consult the ADC manual (or ADC section of micro controller manual) for details.
Ensure that the ADC provides sufficient accuracy.
Sample the battery level and run a simple low-pass filter to eliminate noise, like displayed_level = (displayed_level * 0.95) + (measured_level * 0.05). Run that through an approximate function mapping the apparent reference voltage to the charge level.
Display the charge level.

Send game controller message to a race game use Xinput

I have a steering wheel game controller.Now I am trying to write a driver for playing a race game such as NFS-17.I knew the game is using Xinput.I will write the driver in C.
My questions:
1) How to send message to the game when I turned the steering wheel.
2) Is it using SendMessage().
3) If use SendMessage(), how to get the game window's handle and which wParam and lParam should I send.
XInput is for xbox360 controllers. For the steering wheel X axis you can use the two Triggers of the gamepad. XInput is a getter/setter nothing more :P It gets you the state of the connected controller and reports if there is something connected or not at your request only, it doesn't monitor or save anything anywhere nor does it send messages to apps that have input focus. Sending messages is your job with an app that you could build.
Now, down to what you actually need. You could write a simple C++ app that would scan the state of the controller, but wait...you don't have a xbox360 controller :P So first test how your app would respond to your steering wheel with its oem driver. If you can't read it as connected on any usb port (check on MSDN the GetInputState()) then try using a windows generic driver (let it install whatever suits it, it might even perceive your steering wheel as a xbox360 they are very similar to a point, difference being the number of axis and buttons with more expensive wheels).
Then when you achieved actually reading the state of your controller (steering wheel), use GetHDC( windowhandle), where windowhandle is retrieved via (I don't remember for sure)FindWindow(name/title of the window). Use alt-tab to check with mouseover whatever title is used for the game's window.
When you are in possession of the window handle and the device context you can send messages to its call back WndProc function corespondent via the window handle and even display texts/draw images/shapes via the device context. The messages should be the according virtualkey codes (VK_UP for UP arrow for instance...look it up) that would be pushed on the keyboard if there wasn't a wheel available. The trick is to simulate a PWM for every degree of the wheel rotation. Just send a high frequency messages of alternating push/release of the VK_LEFT key code for a high degree of wheel turn to the left and for steering lock just send one KEY_DOWN message until the steering lock is removed and then a KEY_UP message followed by the corresponding frequency of alternations again. For low degrees of wheel make larger pauses between the key press/release messages.
A bonus of making a driver is that you can adjust the sensitivity, button correlations, dead zones for your own liking.
On the other hand there are simulators like this already and then again you could build your own steering wheel with 6+1 transmision using just a usb comunication API(read/write data from/to USB port, nothing fancy :) ) from windows, a microcontroller (PIC,atmega, nxp, etc whatever cheaper and with hardware USB at the ready or plus a usb controller), variable resistors for the X,Y, etc axis and some parts for the driving system. Good luck and post on youtube :P!
P.S. Hell it is way too late now, but hey...I felt I needed to write some mambo-jambo I have never done, but which would work... if I wasn't that lazy. :)
Update: xInput may work if compatible (probably high end wheels and joys), but directx knows of steering wheels too, all of them. For me it was the only solution. Microsoft says both XInput and directX should be used as XINput offers audio and more stuff for compatible products.
The algorythm is sound, though open to many implementations. I implemented it successfully for GTA SA, since dedicated tools didn't support my version. Now I have Acc and Brake from the pedals, finally:) I used a timer to achieve a certain frequency (of own choice, empiric stuff), and modulated the pulse width from near 0s to full period (light touch of the pedal and continuously applied pedal to the metal). On every pulse I sent two messages: W/S keys down at the start of the pulse and W/S keys up when the calculated pulse width has reached its end value. The formula for Pulse Width is percentage of total width, the same percentage or modified by a sensitivity setting for instance the pedal had traveled from its max travel distance (DirectInput reports a integer number in[-1000,1000] I think. [-fullbrake,fullacceleration]).

Resources