Genom3tutorialdemo-genom3 » History » Version 1
Aurélie Clodic, 2014-04-10 13:22
1 | 1 | Aurélie Clodic | h1. Genom3tutorialdemo-genom3 |
---|---|---|---|
2 | |||
3 | {{toc}} |
||
4 | |||
5 | h2. Needs |
||
6 | |||
7 | h2. How to write your first module ? |
||
8 | |||
9 | This section will illustrate a concrete use of genom3. The demo module will control a virtual mobile that can move in a 1D world. Some of the services the module offers are: |
||
10 | * read and set the current speed at any moment |
||
11 | * move the mobile to a given position |
||
12 | * move the mobile of a given distance (from its current position) |
||
13 | * monitor when the mobile passes a given position |
||
14 | * stop the motion |
||
15 | |||
16 | Moreover, the demo module export a port with the current state of the mobile (position and speed). |
||
17 | |||
18 | To implement this, we first create a directory named demo-genom3. |
||
19 | |||
20 | <pre> |
||
21 | mkdir demo-genom3 |
||
22 | cd demo-genom3 |
||
23 | </pre> |
||
24 | |||
25 | h3. Write .gen file |
||
26 | |||
27 | In that directory, we will write the description file demo.gen. The file demo.gen is made up of several parts, each of them being identified with a keyword |
||
28 | * @component@ |
||
29 | * @ids@ |
||
30 | * @port@ |
||
31 | * @exception@ |
||
32 | * @task@ |
||
33 | * @attribute@ |
||
34 | * @function@ |
||
35 | * @activity@ |
||
36 | |||
37 | The easiest way is to start from an existing file, so you can download ".gen" file. We will now explain step by step each part of this file. |
||
38 | |||
39 | h4. @component@ |
||
40 | |||
41 | The component declaration describes the instance of the GenoM component. It is defined by a unique name (an identifier) that also defines an IDL scope for any embedded types. See the "component declaration documentation":http://homepages.laas.fr/mallet/share/doc/genom3/genom3.html/Component-declaration.html#Component-declaration for details. |
||
42 | |||
43 | <pre> |
||
44 | component demo { |
||
45 | version "1.1"; |
||
46 | email "openrobots@laas.fr"; |
||
47 | lang "c"; |
||
48 | require "genom3 >= 2.99.20"; |
||
49 | </pre> |
||
50 | |||
51 | |||
52 | * version : The component version number, as a string |
||
53 | * lang : The programming language of the codels interface |
||
54 | * email : A string containing the e-mail address of the author of the component. |
||
55 | * requires : A list of dependencies of the component. It indicates an external dependency on a software package that is required. It assumes that the package is using the pkg-config utility Each string should contain a package name in pkg-config format. |
||
56 | |||
57 | NB: component declaration is not over, the final } is left for the end @.gen@ file. |
||
58 | |||
59 | h4. @ids@ |
||
60 | |||
61 | @ids@ stands for internal data structure, it contains information that need to be shared all over the module. For example here, we consider: |
||
62 | <pre> |
||
63 | ids { |
||
64 | demo::state state; /* Current state */ |
||
65 | demo::speed speedRef; /* Speed reference */ |
||
66 | double posRef; |
||
67 | }; |
||
68 | </pre> |
||
69 | @demo::state@ and @demo::speed@ are types derived from |
||
70 | |||
71 | h4. @port@ |
||
72 | |||
73 | Ports implement the data flow between components as a publish/subscribe model. Ports have a name and a type and can be either out (for publishing data) or in (for subscribing to a sibling out port). In this example, we choose to export: |
||
74 | <pre> |
||
75 | /* ---- Port declaration ---- */ |
||
76 | port out demo::state Mobile; |
||
77 | </pre> |
||
78 | |||
79 | h4. @exception@ |
||
80 | |||
81 | It is possible to |
||
82 | <pre> |
||
83 | /* ---- exception declaration ---- */ |
||
84 | exception TOO_FAR_AWAY {double overshoot;}; |
||
85 | exception INVALID_SPEED; |
||
86 | </pre> |
||
87 | |||
88 | h4. @execution task@ |
||
89 | |||
90 | Tasks define an execution context suitable for running activities. A task may define a state machine and associated codels. |
||
91 | The state machine starts in the start state when the task is created during component initialization. |
||
92 | Tasks can define the following properties: |
||
93 | * @period@ The granularity of the codel scheduler. Periodic task will sequence the codels they manage at that frequency. |
||
94 | * @delay@ The delay from the beginning of each period after which codels are run. This can be used to delay two tasks running at the same period in the same component. |
||
95 | * @priority@ Can be used to prioritize different tasks whithin the same component. |
||
96 | * @scheduling real-time@ This indicates that the task requires real-time scheduling. This may not be supported by all templates. |
||
97 | * @stack@ Defines the required stack size for this task. The stack size should be big enough to run all codels that the task manages. |
||
98 | |||
99 | |||
100 | In our example, we choose to get the task_period from ... |
||
101 | <pre> |
||
102 | /* ---- Execution task declaration ---- */ |
||
103 | |||
104 | task motion { |
||
105 | period demo::task_period ms; |
||
106 | priority 100; |
||
107 | stack 4000; |
||
108 | codel <start> InitDemoSDI(out ::ids, port out Mobile) yield ether; |
||
109 | }; |
||
110 | </pre> |
||
111 | |||
112 | h4. services declations |
||
113 | |||
114 | h5. @attribute@ |
||
115 | <pre> |
||
116 | attribute SetSpeed(in speedRef = demo::SLOW :"Mobile speed") |
||
117 | { |
||
118 | doc "To change speed"; |
||
119 | validate controlSpeed (local in speedRef); |
||
120 | throw INVALID_SPEED; |
||
121 | }; |
||
122 | |||
123 | attribute GetSpeed(out speedRef = :"Mobile speed") |
||
124 | { |
||
125 | doc "To get current speed value"; |
||
126 | }; |
||
127 | </pre> |
||
128 | |||
129 | h5. @function@ |
||
130 | <pre> |
||
131 | function Stop() |
||
132 | { |
||
133 | doc "Stops motion and interrupts all motion requests"; |
||
134 | interrupts MoveDistance, GotoPosition; |
||
135 | }; |
||
136 | </pre> |
||
137 | |||
138 | h5. @activity@ |
||
139 | <pre> |
||
140 | activity MoveDistance(in double distRef = 0 :"Distance in m") |
||
141 | { |
||
142 | doc "Move of the given distance"; |
||
143 | validate controlDistance(in distRef, in state.position); |
||
144 | |||
145 | codel <start> mdStartEngine(in distRef, in state.position, |
||
146 | out posRef) yield exec, ether; |
||
147 | codel <exec> mdGotoPosition(in speedRef, in posRef, inout state, |
||
148 | port out Mobile) yield exec, end; |
||
149 | codel <end, stop> mdStopEngine() yield ether; |
||
150 | interrupts MoveDistance, GotoPosition; |
||
151 | task motion; |
||
152 | throw TOO_FAR_AWAY; |
||
153 | }; |
||
154 | </pre> |