The water tank application is a process control-inspired demonstration of the slider, progress bar and command button widgets in the Widget toolkit; bitmaps of the Graphics display system; and basic use of the Window toolkit. More...
|
Data Structures | |
| struct | tank_context |
| Context for the water tank application. More... | |
Enumerations | |
| enum | tank_loader_state { LOAD_RED_LIGHT, LOAD_GREEN_LIGHT, LOAD_BACKGROUND, LOAD_FINISHED } |
States for the application loader task. More... | |
| enum | tank_bitmap_id { BITMAP_RED_LIGHT, BITMAP_GREEN_LIGHT, NR_OF_BITMAPS } |
Enumeration of bitmaps to load to hugemem. More... | |
| enum | tank_command_id { CMD_NONE, CMD_EXIT } |
Event command ID for application widgets. More... | |
Functions | |
| static bool | tank_frame_handler (struct wtk_basic_frame *basic_frame, win_command_t command_data) |
| Command event handler for the application's frame. | |
| static int32_t | tank_logistic_map (int32_t rand) |
| Compute new random value via a logistic map. | |
| static void | tank_worker (struct workqueue_task *task) |
| Application worker function. | |
| static void | tank_timer_callback (struct timer *timer) |
| Application timer callback function. | |
| static void | tank_loader (struct workqueue_task *task) |
| Application loader. | |
| void | app_tank_launch (struct workqueue_task *task) |
| Launch the water tank application. | |
Variables | |
| static hugemem_ptr_t | tank_bitmap_data [NR_OF_BITMAPS] |
| Pointers to bitmap data in hugemem. | |
| static struct tank_context * | tank_ctx |
| Pointer to water tank application context. | |
Color scheme | |
|
| |
| #define | COLOR_WIN_BACKGROUND GFX_COLOR(0, 0, 0) |
| Color to initially fill screen with. | |
| #define | COLOR_LEVEL_FILL GFX_COLOR(0, 0, 255) |
| Fill color for tank level indicator. | |
| #define | COLOR_LEVEL_BACKGROUND GFX_COLOR(32, 32, 32) |
| Background color for tank level indicator. | |
| #define | COLOR_DEMAND_NORMAL GFX_COLOR(64, 192, 64) |
| Normal fill color for demand indicator. | |
| #define | COLOR_DEMAND_CRITICAL GFX_COLOR(192, 64, 64) |
| Critical fill color for demand indicator. | |
| #define | COLOR_DEMAND_BACKGROUND GFX_COLOR(32, 32, 32) |
| Background color for demand indicator. | |
Maximum and initial values of process parameters | |
|
| |
| #define | VALUE_LEVEL_MAXIMUM 127 |
| Maximum level of tank. | |
| #define | VALUE_LEVEL_INITIAL 0 |
| Initial level of tank. | |
| #define | VALUE_SUPPLY_MAXIMUM VALUE_LEVEL_MAXIMUM |
| Maximum value of supply. | |
| #define | VALUE_SUPPLY_INITIAL (VALUE_SUPPLY_MAXIMUM / 2) |
| Initial value of supply. | |
| #define | VALUE_DEMAND_MAXIMUM VALUE_LEVEL_MAXIMUM |
| Maximum value of demand. | |
| #define | VALUE_DEMAND_INITIAL 0 |
| Initial value of demand. | |
Widget sizes and positions | |
|
| |
| #define | WIDGET_LEVEL_SIZE_X 52 |
| Height of progress bar for tank level. | |
| #define | WIDGET_LEVEL_SIZE_Y 121 |
| Width of progress bar for tank level. | |
| #define | WIDGET_LEVEL_POSITION_X 134 |
| X coordinate of progress bar for tank level. | |
| #define | WIDGET_LEVEL_POSITION_Y 59 |
| Y coordinate of progress bar for tank level. | |
| #define | WIDGET_SUPPLY_SIZE_X 37 |
| Height of slider for supply. | |
| #define | WIDGET_SUPPLY_SIZE_Y 105 |
| Width of slider for supply. | |
| #define | WIDGET_SUPPLY_POSITION_X 39 |
| X coordinate of slider for supply. | |
| #define | WIDGET_SUPPLY_POSITION_Y 85 |
| Y coordinate of slider for supply. | |
| #define | WIDGET_DEMAND_SIZE_X 20 |
| Height of progress bar for demand indication. | |
| #define | WIDGET_DEMAND_SIZE_Y 45 |
| Width of progress bar for demand indication. | |
| #define | WIDGET_DEMAND_POSITION_X 250 |
| X coordinate of progress bar for demand indication. | |
| #define | WIDGET_DEMAND_POSITION_Y 100 |
| Y coordinator of progress bar for demand indication. | |
Bitmap filenames, sizes and positions | |
|
| |
| #define | BITMAP_BACKGROUND_FILENAME "p_tankbg" |
| Filename of background bitmap. | |
| #define | BITMAP_BACKGROUND_SIZE_X 320 |
| Width of background bitmap. | |
| #define | BITMAP_BACKGROUND_SIZE_Y 240 |
| Height of background bitmap. | |
| #define | BITMAP_BACKGROUND_POSITION_X 0 |
| X coordinate of background bitmap. | |
| #define | BITMAP_BACKGROUND_POSITION_Y 0 |
| Y coordinate of background bitmap. | |
| #define | BITMAP_RED_LIGHT_FILENAME "p_lgtred" |
| Filename of red alarm light bitmap. | |
| #define | BITMAP_GREEN_LIGHT_FILENAME "p_lgtgrn" |
| Filename of green alarm light bitmap. | |
| #define | BITMAP_LIGHT_SIZE_X 38 |
| Width of alarm light bitmap. | |
| #define | BITMAP_LIGHT_SIZE_Y 38 |
| Height of alarm light bitmap. | |
| #define | BITMAP_LIGHT_POSITION_X 241 |
| X coordinate of alarm light bitmap. | |
| #define | BITMAP_LIGHT_POSITION_Y 26 |
| Y coordinate of alarm light bitmap. | |
Application timing configuration | |
|
| |
| #define | TICK_RATE 30 |
| Application tick rate. | |
| #define | TICKS_PER_RANDOM_UPDATE 9 |
| Application ticks between each update of random variable. | |
The water tank application is a process control-inspired demonstration of the slider, progress bar and command button widgets in the Widget toolkit; bitmaps of the Graphics display system; and basic use of the Window toolkit.
The application consists of a slider for controlling the supply (flow in) of water to a tank, and two progress bars for indicating the level of the water tank and the time-varying demand (flow out) for water, respectively. An alarm light changes color from green to red whenever the tank overflows, and the indicator for demand changes color if the demand exceeds the supply and available water in the tank.
This application makes use of the Timer driver for maintaining a constant update rate regardless of the workqueue load. The Fileloader utility is used to load the alarm light bitmaps to hugemem, allowing for synchronous drawing of them.
The process in this application was created simply to get a time-varying system, and is not meant to represent a real-world one. This section explains how the process is computed.
At iteration n, the process parameters are:
First, the random value is computed by use of the logistic map with scaling:
r(n) = q * (r(n-1) * (k - r(n-1))) / k
If r(0) is in the range [1 , k - 1], this function will return a value in the same range. The factor q affects how chaotic the logistic function behaves: For values close to the upper bound of 4, the function will seem quite random. In the implementation, q has been set to 3.95 and is represented by the ratio 79 / 20 since integer multiplications must be used. The maximum value k is set to the same as the maximum level of the tank: 127.
The demand is then computed from a weighted mean:
d(n) = (2 * d(n-1) + l(n-1) + r(n)) / 4
Disregarding the random component, this will essentially give a low-pass filtered response to changes in demand and tank level.
The flow of the system is then computed as:
f(n) = (s(n) - d(n)) / t
The factor t can be used to "time-stretch" the simulated process, and has been set to 4 in the implementation. The maximum value of supply is the same as the maximum level of the tank: 127.
Finally, the level of the tank is then computed as:
l(n) = l(n-1) + f(n)
However, the level of the tank is bounded by 0 and its maximum value. If the tank's level reaches 0, the demand indicator will change color to indicate that the supply is insufficient. If it reaches the maximum, the overflow alarm light will change color to indicate that the supply is too great. As stated above, the maximum level of the tank is set to 127.
| #define BITMAP_BACKGROUND_FILENAME "p_tankbg" |
Filename of background bitmap.
Definition at line 145 of file app_tank.c.
Referenced by tank_loader().
| #define BITMAP_BACKGROUND_POSITION_X 0 |
X coordinate of background bitmap.
Definition at line 151 of file app_tank.c.
Referenced by tank_loader().
| #define BITMAP_BACKGROUND_POSITION_Y 0 |
Y coordinate of background bitmap.
Definition at line 153 of file app_tank.c.
Referenced by tank_loader().
| #define BITMAP_BACKGROUND_SIZE_X 320 |
| #define BITMAP_BACKGROUND_SIZE_Y 240 |
Height of background bitmap.
Definition at line 149 of file app_tank.c.
Referenced by tank_loader().
| #define BITMAP_GREEN_LIGHT_FILENAME "p_lgtgrn" |
Filename of green alarm light bitmap.
Definition at line 158 of file app_tank.c.
Referenced by tank_loader().
| #define BITMAP_LIGHT_POSITION_X 241 |
X coordinate of alarm light bitmap.
Definition at line 164 of file app_tank.c.
Referenced by tank_worker().
| #define BITMAP_LIGHT_POSITION_Y 26 |
Y coordinate of alarm light bitmap.
Definition at line 166 of file app_tank.c.
Referenced by tank_worker().
| #define BITMAP_LIGHT_SIZE_X 38 |
Width of alarm light bitmap.
Definition at line 160 of file app_tank.c.
Referenced by app_tank_launch(), and tank_worker().
| #define BITMAP_LIGHT_SIZE_Y 38 |
Height of alarm light bitmap.
Definition at line 162 of file app_tank.c.
Referenced by app_tank_launch(), and tank_worker().
| #define BITMAP_RED_LIGHT_FILENAME "p_lgtred" |
Filename of red alarm light bitmap.
Definition at line 156 of file app_tank.c.
Referenced by tank_loader().
| #define COLOR_DEMAND_BACKGROUND GFX_COLOR(32, 32, 32) |
Background color for demand indicator.
Definition at line 78 of file app_tank.c.
Referenced by app_tank_launch(), and tank_worker().
| #define COLOR_DEMAND_CRITICAL GFX_COLOR(192, 64, 64) |
Critical fill color for demand indicator.
Definition at line 76 of file app_tank.c.
Referenced by tank_worker().
| #define COLOR_DEMAND_NORMAL GFX_COLOR(64, 192, 64) |
Normal fill color for demand indicator.
Definition at line 74 of file app_tank.c.
Referenced by app_tank_launch(), and tank_worker().
| #define COLOR_LEVEL_BACKGROUND GFX_COLOR(32, 32, 32) |
Background color for tank level indicator.
Definition at line 72 of file app_tank.c.
Referenced by app_tank_launch().
| #define COLOR_LEVEL_FILL GFX_COLOR(0, 0, 255) |
Fill color for tank level indicator.
Definition at line 70 of file app_tank.c.
Referenced by app_tank_launch().
| #define COLOR_WIN_BACKGROUND GFX_COLOR(0, 0, 0) |
Color to initially fill screen with.
Definition at line 68 of file app_tank.c.
Referenced by app_tank_launch().
| #define TICK_RATE 30 |
Application tick rate.
This configures how often the application timer enqueues the application task, i.e., how often the application is updated.
Definition at line 182 of file app_tank.c.
Referenced by app_tank_launch().
| #define TICKS_PER_RANDOM_UPDATE 9 |
Application ticks between each update of random variable.
To get a smoother process simulation, the random variable is not updated with every application update. This defines how many ticks should pass before this variable is also updated.
Definition at line 190 of file app_tank.c.
Referenced by app_tank_launch(), and tank_worker().
| #define VALUE_DEMAND_INITIAL 0 |
| #define VALUE_DEMAND_MAXIMUM VALUE_LEVEL_MAXIMUM |
Maximum value of demand.
Definition at line 97 of file app_tank.c.
Referenced by app_tank_launch(), tank_logistic_map(), and tank_worker().
| #define VALUE_LEVEL_INITIAL 0 |
| #define VALUE_LEVEL_MAXIMUM 127 |
Maximum level of tank.
Definition at line 89 of file app_tank.c.
Referenced by app_tank_launch(), and tank_worker().
| #define VALUE_SUPPLY_INITIAL (VALUE_SUPPLY_MAXIMUM / 2) |
| #define VALUE_SUPPLY_MAXIMUM VALUE_LEVEL_MAXIMUM |
| #define WIDGET_DEMAND_POSITION_X 250 |
X coordinate of progress bar for demand indication.
Definition at line 132 of file app_tank.c.
Referenced by app_tank_launch().
| #define WIDGET_DEMAND_POSITION_Y 100 |
Y coordinator of progress bar for demand indication.
Definition at line 134 of file app_tank.c.
Referenced by app_tank_launch().
| #define WIDGET_DEMAND_SIZE_X 20 |
Height of progress bar for demand indication.
Definition at line 128 of file app_tank.c.
Referenced by app_tank_launch().
| #define WIDGET_DEMAND_SIZE_Y 45 |
Width of progress bar for demand indication.
Definition at line 130 of file app_tank.c.
Referenced by app_tank_launch().
| #define WIDGET_LEVEL_POSITION_X 134 |
X coordinate of progress bar for tank level.
Definition at line 114 of file app_tank.c.
Referenced by app_tank_launch().
| #define WIDGET_LEVEL_POSITION_Y 59 |
Y coordinate of progress bar for tank level.
Definition at line 116 of file app_tank.c.
Referenced by app_tank_launch().
| #define WIDGET_LEVEL_SIZE_X 52 |
Height of progress bar for tank level.
Definition at line 110 of file app_tank.c.
Referenced by app_tank_launch().
| #define WIDGET_LEVEL_SIZE_Y 121 |
Width of progress bar for tank level.
Definition at line 112 of file app_tank.c.
Referenced by app_tank_launch().
| #define WIDGET_SUPPLY_POSITION_X 39 |
X coordinate of slider for supply.
Definition at line 123 of file app_tank.c.
Referenced by app_tank_launch().
| #define WIDGET_SUPPLY_POSITION_Y 85 |
Y coordinate of slider for supply.
Definition at line 125 of file app_tank.c.
Referenced by app_tank_launch().
| #define WIDGET_SUPPLY_SIZE_X 37 |
Height of slider for supply.
Definition at line 119 of file app_tank.c.
Referenced by app_tank_launch().
| #define WIDGET_SUPPLY_SIZE_Y 105 |
Width of slider for supply.
Definition at line 121 of file app_tank.c.
Referenced by app_tank_launch().
| enum tank_bitmap_id |
Enumeration of bitmaps to load to hugemem.
This enum is used for indexing in tank_bitmap_data when loading and drawing bitmaps.
| BITMAP_RED_LIGHT |
ID and index of bitmap for red alarm light. |
| BITMAP_GREEN_LIGHT |
ID and index of bitmap for green alarm light. |
| NR_OF_BITMAPS |
Total number of bitmaps loaded to hugemem. |
Definition at line 212 of file app_tank.c.
| enum tank_command_id |
Event command ID for application widgets.
| CMD_NONE |
Command event value to use for supply-slider. |
| CMD_EXIT |
Command event value to use for exit-button. |
Definition at line 237 of file app_tank.c.
| enum tank_loader_state |
States for the application loader task.
Definition at line 195 of file app_tank.c.
| void app_tank_launch | ( | struct workqueue_task * | task | ) |
Launch the water tank application.
This function allocates memory, creates the application frame and widgets, initializes the timer and initiates loading of the required bitmaps.
One basic frame is created, along with four widgets: one slider, two progress bars and a command button. These are not shown until the background image has been loaded.
If the alarm light bitmaps have already been loaded, i.e., the application has already been run, the application will skip directly to loading of the background image.
If memory for the application context cannot be allocated or the frame or widgets cannot be created, the application will exit immediately.
| task | Workqueue task to use for the application's worker functions. |
Definition at line 618 of file app_tank.c.
References app_desktop_restart(), APP_EXIT_BUTTON_POS_X, APP_EXIT_BUTTON_POS_Y, APP_EXIT_BUTTON_SIZE_X, APP_EXIT_BUTTON_SIZE_Y, APP_EXIT_BUTTON_TEXT, win_attributes::area, assert, BITMAP_GREEN_LIGHT, BITMAP_LIGHT_SIZE_X, BITMAP_LIGHT_SIZE_Y, BITMAP_RED_LIGHT, tank_context::bitmaps, CMD_EXIT, CMD_NONE, COLOR_DEMAND_BACKGROUND, COLOR_DEMAND_NORMAL, COLOR_LEVEL_BACKGROUND, COLOR_LEVEL_FILL, COLOR_WIN_BACKGROUND, tank_context::demand, tank_context::flow_alarm, tank_context::frame, gfx_draw_filled_rect, gfx_get_height(), gfx_get_width(), gfx_set_clipping(), gfx_bitmap::height, tank_context::level, tank_context::level_alarm, LOAD_BACKGROUND, LOAD_RED_LIGHT, tank_context::loader_state, main_workqueue, membag_alloc(), membag_free(), memcpy(), tank_context::old_sysfont, win_area::pos, tank_context::rand, tank_context::rand_ticks, font::scale, win_area::size, tank_context::supply, sysfont, tank_bitmap_data, tank_frame_handler(), tank_loader(), tank_timer_callback(), tank_context::task, TICK_RATE, TICKS_PER_RANDOM_UPDATE, tank_context::timer, tank_context::timer_delay, timer_get_resolution, timer_init, timer_set_resolution, timer_write_resolution, gfx_bitmap::type, VALUE_DEMAND_INITIAL, VALUE_DEMAND_MAXIMUM, VALUE_LEVEL_INITIAL, VALUE_LEVEL_MAXIMUM, VALUE_SUPPLY_INITIAL, VALUE_SUPPLY_MAXIMUM, WIDGET_DEMAND_POSITION_X, WIDGET_DEMAND_POSITION_Y, WIDGET_DEMAND_SIZE_X, WIDGET_DEMAND_SIZE_Y, WIDGET_LEVEL_POSITION_X, WIDGET_LEVEL_POSITION_Y, WIDGET_LEVEL_SIZE_X, WIDGET_LEVEL_SIZE_Y, WIDGET_SUPPLY_POSITION_X, WIDGET_SUPPLY_POSITION_Y, WIDGET_SUPPLY_SIZE_X, WIDGET_SUPPLY_SIZE_Y, gfx_bitmap::width, win_destroy(), win_get_root(), win_show(), workqueue_add_task(), workqueue_task_set_work_func(), wtk_basic_frame_as_child(), wtk_basic_frame_create(), wtk_button_as_child(), wtk_button_create(), wtk_progress_bar_as_child(), wtk_progress_bar_create(), WTK_PROGRESS_BAR_INVERT, WTK_PROGRESS_BAR_VERTICAL, wtk_slider_as_child(), wtk_slider_create(), WTK_SLIDER_INVERT, and WTK_SLIDER_VERTICAL.
| static bool tank_frame_handler | ( | struct wtk_basic_frame * | basic_frame, | |
| win_command_t | command_data | |||
| ) | [static] |
Command event handler for the application's frame.
This function handles the relevant command events for the application's frame. In this application, only the exit-button requires handling, and will cause an immediate exit from the application.
| basic_frame | Pointer to the application frame. | |
| command_data | Data for the command event. |
Definition at line 298 of file app_tank.c.
References app_desktop_restart(), CMD_EXIT, membag_free(), memcpy(), tank_context::old_sysfont, sysfont, tank_context::timer, and timer_stop.
Referenced by app_tank_launch().
| static void tank_loader | ( | struct workqueue_task * | task | ) | [static] |
Application loader.
This worker function loads the alarm light bitmaps, then loads the background image before showing all the widgets and starting the process simulation.
If memory for bitmaps cannot be allocated, or the background image cannot be loaded, the application will exit immediately.
| task | Workqueue task for this worker function. |
Definition at line 506 of file app_tank.c.
References app_desktop_restart(), BITMAP_BACKGROUND_FILENAME, BITMAP_BACKGROUND_POSITION_X, BITMAP_BACKGROUND_POSITION_Y, BITMAP_BACKGROUND_SIZE_X, BITMAP_BACKGROUND_SIZE_Y, BITMAP_GREEN_LIGHT, BITMAP_GREEN_LIGHT_FILENAME, BITMAP_RED_LIGHT, BITMAP_RED_LIGHT_FILENAME, tank_context::bitmaps, tank_context::frame, HUGEMEM_NULL, LOAD_BACKGROUND, load_file_to_hugemem(), load_file_to_screen(), LOAD_FINISHED, LOAD_GREEN_LIGHT, LOAD_RED_LIGHT, tank_context::loader_state, membag_free(), memcpy(), tank_context::old_sysfont, STATUS_OK, sysfont, tank_bitmap_data, tank_worker(), tank_context::timer, tank_context::timer_delay, timer_set_alarm, timer_start, unhandled_case, win_destroy(), win_show(), workqueue_task_set_work_func(), and wtk_basic_frame_as_child().
Referenced by app_tank_launch().
Compute new random value via a logistic map.
This function computes a pseudo-random value by use of a scaled logistic map.
Refer to the detailed description of Water tank application for information on how this is computed.
| rand | Current random value to map. |
Definition at line 333 of file app_tank.c.
References max_s, min_s, and VALUE_DEMAND_MAXIMUM.
Referenced by tank_worker().
| static void tank_timer_callback | ( | struct timer * | timer | ) | [static] |
Application timer callback function.
This callback function is used with the Timer driver and will enqueue the task for application updates.
| timer | Pointer to timer struct associated with the callback. |
Definition at line 488 of file app_tank.c.
References main_workqueue, tank_context::task, tank_context::timer, tank_context::timer_delay, timer_set_alarm, and workqueue_add_task().
Referenced by app_tank_launch().
| static void tank_worker | ( | struct workqueue_task * | task | ) | [static] |
Application worker function.
This task worker updates the parameters of the simulated process and the display unless the application context has been cleared, in which case the function returns immediately.
Refer to the detailed description of Water tank application for information on the simulated process.
If the tank level reaches 0, the indicator for demand will change color to indicate that the supply is insufficient. If, on the other hand, it reaches VALUE_LEVEL_MAXIMUM, the alarm light changes color to indicate that the supply is too great.
| task | Workqueue task for this worker function. |
Definition at line 371 of file app_tank.c.
References BITMAP_GREEN_LIGHT, BITMAP_LIGHT_POSITION_X, BITMAP_LIGHT_POSITION_Y, BITMAP_LIGHT_SIZE_X, BITMAP_LIGHT_SIZE_Y, BITMAP_RED_LIGHT, tank_context::bitmaps, COLOR_DEMAND_BACKGROUND, COLOR_DEMAND_CRITICAL, COLOR_DEMAND_NORMAL, tank_context::demand, tank_context::flow_alarm, gfx_draw_bitmap(), gfx_set_clipping(), tank_context::level, tank_context::level_alarm, min_u, tank_context::rand, tank_context::rand_ticks, tank_context::supply, tank_logistic_map(), TICKS_PER_RANDOM_UPDATE, VALUE_DEMAND_MAXIMUM, VALUE_LEVEL_MAXIMUM, wtk_progress_bar_get_value(), wtk_progress_bar_set_colors(), wtk_progress_bar_set_value(), and wtk_slider_get_value().
Referenced by tank_loader().
hugemem_ptr_t tank_bitmap_data[NR_OF_BITMAPS] [static] |
Pointers to bitmap data in hugemem.
Definition at line 227 of file app_tank.c.
Referenced by app_tank_launch(), and tank_loader().
struct tank_context* tank_ctx [static] |
Pointer to water tank application context.
Definition at line 283 of file app_tank.c.
1.6.3