hyb_5_controlB.cpp
Go to the documentation of this file.
1/** @file hyb_5_controlB.cpp
2
3Tutorial, hybrid systems plugin. This tutorial demonstrates
4how to compute a finite abstraction for the purpose of
5control.
6
7@ingroup Tutorials
8
9@include hyb_5_ControlB.cpp
10
11*/
12
13#include "libfaudes.h"
14
15// make the faudes namespace available to our program
16using namespace faudes;
17
18/**
19 * In this example, dynamics are given programtically, i.e. by
20 * a customised instance of CompatibleStates as opposed to the
21 * ready-to-use versions for DES or LHA.
22 *
23 * The plant we implement consits simple tank with two input
24 * symbols for fill '+' and drain '-' and two output symbols for
25 * full 'F' and and empty 'E'. Inputs symbols and output symbols
26 * alternate.
27 */
28
30
31protected:
32 /** one single "real" interval of compatible continuous states */
33 double mXmin;
34 double mXmax;
35 bool mLopen;
36 bool mHopen;
37 /** recent input as discrete state, values "+", "-", none "~", init "0" */
38 char mU;
39 /** transition result */
40 std::map<Idx, ExbCompatibleStates*> mReachSets;
41 /** event symbol table (cosmetic) */
43
44public:
45
46 /** construct/destruct */
49 rAlphabet(alph) {
50 };
52 Clear();
53 };
54
55 /** allway initialisation with no constraints, i.e., time invariant system */
56 void InitialiseFull(void) {
57 mXmin=0; mXmax=30; mLopen=false; mHopen=false; mU='0';
58 };
62
63 /** debug dump */
64 void DWrite(void) const {
65 std::cout << "continuous state set: ";
66 if(mLopen) std::cout << "(";
67 else std::cout << "[";
68 std::cout << mXmin << ", " << mXmax;
69 if(mHopen) std::cout << ")";
70 else std::cout << "]";
71 std::cout << " last input " << mU << std::endl;
72 }
73
74 /** implement dynamics */
75 virtual void ExecuteTransitions(void) {
76 FD_DF("ExampleB: execute dynamics");
77 Clear();
79 switch(mU) {
80 // last event was an input symbol, thus we generate an output sybol
81 case '+':
82 case '-':
83 case '0':
84 // can we generate 'E'?
85 if( mXmin < 15 || ((mXmin == 15) && (mLopen == false)) ) {
86 ncs=new ExbCompatibleStates(rAlphabet);
87 ncs->mXmin=mXmin;
88 ncs->mLopen = mLopen;
89 ncs->mXmax = (mXmax <= 15 ? mXmax : 15);
90 ncs->mHopen = (mXmax <= 15 ? mHopen : false);
91 ncs->mU='~';
92 mReachSets[rAlphabet.Index("E")]=ncs;
93 }
94 // can we generate 'F'?
95 if(mXmax > 15) {
96 ncs=new ExbCompatibleStates(rAlphabet);
97 ncs->mXmax=mXmax;
98 ncs->mHopen = mHopen;
99 ncs->mXmin = (mXmin > 15 ? mXmin : 15);
100 ncs->mLopen = (mXmin > 15 ? mLopen : true);
101 mReachSets[rAlphabet.Index("F")]=ncs;
102 ncs->mU='~';
103 }
104 break;
105 // last event was an output symbol, this we accept and execute any input symbol
106 case '~':
107 // perform '+'
108 ncs=new ExbCompatibleStates(rAlphabet);
109 ncs->mXmax =mXmax+10;
110 ncs->mHopen = mHopen;
111 ncs->mXmin = mXmin+10;
112 ncs->mLopen = mLopen;
113 if(ncs->mXmax>=30) {ncs->mXmax=30; ncs->mHopen=false;}
114 if(ncs->mXmin>=30) {ncs->mXmin=30; ncs->mLopen=false;}
115 mReachSets[rAlphabet.Index("+")]=ncs;
116 ncs->mU='+';
117 // perform '-'
118 ncs=new ExbCompatibleStates(rAlphabet);
119 ncs->mXmax =mXmax-10;
120 ncs->mHopen = mHopen;
121 ncs->mXmin = mXmin-10;
122 ncs->mLopen = mLopen;
123 if(ncs->mXmax<=0) {ncs->mXmax=0; ncs->mHopen=false;}
124 if(ncs->mXmin<=0) {ncs->mXmin=0; ncs->mLopen=false;}
125 mReachSets[rAlphabet.Index("-")]=ncs;
126 ncs->mU='-';
127 }
128 FD_DF("ExampleB: execute dynamics: ok.");
129 }
130
131 // read out
133 std::map<Idx, ExbCompatibleStates*>::iterator sit=mReachSets.find(ev);
134 if(sit==mReachSets.end()) return 0;
135 ExbCompatibleStates* res= sit->second;
136 sit->second=0;
137 return res;
138 }
139
140 // support
141 void Clear(void) {
142 std::map<Idx, ExbCompatibleStates*>::iterator sit=mReachSets.begin();
143 std::map<Idx, ExbCompatibleStates*>::iterator sit_end=mReachSets.end();
144 for(;sit!=sit_end;++sit) {
145 if(sit->second) delete sit->second;
146 }
147 mReachSets.clear();
148 }
149
150};
151
152
153
154/** Run the tutorial */
155int main() {
156
157 // have alphabet
158 EventSet alph;
159 alph.FromString("<A> F E \"+\" \"-\" </A>");
160
161 // compile l-complete abstraction
163 comp->InitialiseFull();
164 Experiment* exp = new Experiment(alph);
165 exp->InitialStates(comp);
166 LbdAbstraction tivabs;
167 tivabs.Experiment(exp);
168 tivabs.RefineUniformly(4);
169 tivabs.Experiment().DWrite();
170 Generator lcabs = tivabs.TivAbstraction();
171 lcabs.StateNamesEnabled(false);
172 //StateMin(lcabs,lcabs);
173 lcabs.GraphWrite("tmp_hyb_5tiv2.png");
174
175 // have a specification
176 Generator spec;
177 spec.FromString(
178 "<Generator> <T> 1 E 2 1 F 2 2 \"+\" 3 2 \"-\" 3 3 E 4 3 F 4 4 - 5 4 \"+\" 5 5 F 5 5 \"+\" 5 5 \"-\" 5 </T> <I> 1 </I></Generator>");
179
180 // set up uncontrollable events
181 EventSet ucevents;
182 ucevents.FromString("<A> E F </A>");
183
184 // learning by doing
185 while(1) {
186
187 // synthesise controller
188 Generator loop;
189 loop.StateNamesEnabled(true);
190 spec.StateNamesEnabled(true);
191 lcabs.StateNamesEnabled(true);
193 Parallel(lcabs,spec,psmap,loop);
194 while(1) {
195 Idx sz =loop.Size();
196 loop.Complete();
197 loop.Accessible();
198 StateSet fail;
199 StateSet::Iterator sit=loop.StatesBegin();
200 StateSet::Iterator sit_end=loop.StatesEnd();
201 for(;sit!=sit_end;++sit) {
202 Idx pstate = psmap.Arg1State(*sit);
203 EventSet penabled=lcabs.ActiveEventSet(pstate);
204 EventSet lenabled=loop.ActiveEventSet(*sit);
205 if(penabled * ucevents <= lenabled) continue;
206 fail.Insert(*sit);
207 }
208 loop.DelStates(fail);
209 if(loop.Size()==sz) break;
210 }
211 if(loop.Size()>0) {
212 std::cout << " Synthesis succeeded ";
213 loop.GraphWrite("tmp_hyb_5sup.png");
214 break;
215 }
216
217
218 // refinement candidates
219 StateSet leaves = tivabs.Experiment().Leaves();
220 std::cout << "refinement candidates (leaves)" << std::endl;
221 leaves.Write();
222
223 // search for refinement candidates, "Step 1/2"
224 Generator loop12;
225 Generator spec12;
226 spec12.StateNamesEnabled(false);
227 Parallel(lcabs,spec,psmap,spec12);
228 StateSet::Iterator sit=spec12.StatesBegin();
229 StateSet::Iterator sit_end=spec12.StatesEnd();
230 for(;sit!=sit_end;++sit) {
231 if(!leaves.Exists(psmap.Arg1State(*sit))) continue;
232 spec12.ClrTransitions(*sit);
233 EventSet::Iterator eit=spec12.AlphabetBegin();
234 EventSet::Iterator eit_end=spec12.AlphabetEnd();
235 for(;eit!=eit_end;++eit) spec12.SetTransition(*sit,*eit,*sit);
236 }
237 spec12.Accessible();
238 spec12.GraphWrite("tmp_hyb_5spec12.png");
239 loop12.StateNamesEnabled(true);
240 spec12.StateNamesEnabled(true);
241 lcabs.StateNamesEnabled(true);
242 Parallel(lcabs,spec12,psmap,loop12);
243 //loop12.GraphWrite("tmp_hyb_5ctrllp.png");
244 while(1) {
245 Idx sz =loop12.Size();
246 loop12.Complete();
247 loop12.Accessible();
248 StateSet fail;
249 sit=loop12.StatesBegin();
250 sit_end=loop12.StatesEnd();
251 for(;sit!=sit_end;++sit) {
252 Idx pstate = psmap.Arg1State(*sit);
253 EventSet penabled=lcabs.ActiveEventSet(pstate);
254 EventSet lenabled=loop12.ActiveEventSet(*sit);
255 if(penabled * ucevents <= lenabled) continue;
256 fail.Insert(*sit);
257 }
258 loop12.DelStates(fail);
259 if(loop12.Size()==sz) break;
260 }
261 loop12.GraphWrite("tmp_hyb_5ctrl12.png");
262 StateSet step12;
263 sit=loop12.StatesBegin();
264 sit_end=loop12.StatesEnd();
265 for(;sit!=sit_end;++sit)
266 if(leaves.Exists(psmap.Arg1State(*sit))) step12.Insert(psmap.Arg1State(*sit));
267 std::cout << "refinement candidates (step12)" << std::endl;
268 step12.Write();
269
270
271 // search for refinement candidates, "cpx"
272 Generator loopcpx;
273 loopcpx.StateNamesEnabled(false);
274 Parallel(lcabs,spec,psmap,loopcpx);
275 while(1) {
276 Idx sz =loopcpx.Size();
277 loopcpx.Complete();
278 StateSet fail;
279 StateSet::Iterator sit=loopcpx.StatesBegin();
280 StateSet::Iterator sit_end=loopcpx.StatesEnd();
281 for(;sit!=sit_end;++sit) {
282 Idx pstate = psmap.Arg1State(*sit);
283 EventSet penabled=lcabs.ActiveEventSet(pstate);
284 EventSet lenabled=loopcpx.ActiveEventSet(*sit);
285 if(penabled * ucevents <= lenabled) continue;
286 fail.Insert(*sit);
287 }
288 loopcpx.DelStates(fail);
289 if(loopcpx.Size()==sz) break;
290 }
291 loopcpx.GraphWrite("tmp_hyb_5ctrlcpx.png");
292 StateSet qcpx;
293 sit=loopcpx.StatesBegin();
294 sit_end=loopcpx.StatesEnd();
295 for(;sit!=sit_end;++sit)
296 qcpx.Insert(psmap.Arg1State(*sit));
297 StateSet stepcpx = leaves - qcpx;
298 std::cout << "refinement candidates (cpx)" << std::endl;
299 stepcpx.Write();
300
301
302
303 // do refinement
304 StateSet refine = stepcpx * step12;
305 if(refine.Size()==0) break;
306 sit=refine.Begin();
307 sit_end=refine.End();
308 for(;sit!=sit_end;++sit)
309 tivabs.RefineAt(*sit);
310 lcabs = tivabs.TivAbstraction();
311
312
313 }
314
315
316 // done
317 return 0;
318}
319
320
321
#define FD_DF(message)
#define FAUDES_API
virtual void ExecuteTransitions(void)
void DWrite(void) const
ExbCompatibleStates * TakeByEvent(Idx ev)
std::map< Idx, ExbCompatibleStates * > mReachSets
ExbCompatibleStates(const EventSet &alph)
const EventSet & rAlphabet
virtual void InitialiseFull(void)=0
void InitialStates(CompatibleStates *istates)
void RefineUniformly(unsigned int depth)
const Generator & TivAbstraction(void)
void Experiment(faudes::Experiment *exp)
Idx Index(const std::string &rName) const
void FromString(const std::string &rString, const std::string &rLabel="", const Type *pContext=0)
void Write(const Type *pContext=0) const
StateSet::Iterator StatesBegin(void) const
bool SetTransition(Idx x1, Idx ev, Idx x2)
EventSet ActiveEventSet(Idx x1) const
void ClrTransitions(Idx x1, Idx ev)
EventSet::Iterator AlphabetBegin(void) const
StateSet::Iterator StatesEnd(void) const
void DelStates(const StateSet &rDelStates)
bool StateNamesEnabled(void) const
void GraphWrite(const std::string &rFileName, const std::string &rOutFormat="", const std::string &rDotExec="dot") const
EventSet::Iterator AlphabetEnd(void) const
Idx Size(void) const
bool Exists(const T &rElem) const
Iterator End(void) const
Iterator Begin(void) const
Idx Size(void) const
void Parallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
int main()
uint32_t Idx

libFAUDES 2.34e --- 2026.03.16 --- c++ api documentaion by doxygen