PW_Controller.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /* ---------------------------------------------------------------------------*
  2. * Sample implementation of an FMU - a power window controller
  3. * The code is generated from a Yakindu SC
  4. * ---------------------------------------------------------------------------*/
  5. /*
  6. Template for a sc FMU
  7. */
  8. #define MODEL_IDENTIFIER PW_Controller
  9. #define MODEL_GUID "{f4893318-1565-4931-b8c8-8a19fb3fcfda}"
  10. #define FMI2_FUNCTION_PREFIX PW_Controller
  11. #include <stdio.h>
  12. #include <math.h>
  13. #include "string.h"
  14. #include "fmi2Functions.h"
  15. #include <float.h>
  16. #include "PW_Controller.h"
  17. #include "PowerwindowRequired.h"
  18. #define NUMBER_OF_REALS 0
  19. #define NUMBER_OF_STRINGS 0
  20. #define NUMBER_OF_BOOLEANS 11
  21. #define NUMBER_OF_INTEGERS 0
  22. /*
  23. * The input events:
  24. * */
  25. #define _in_obj_detected 0
  26. #define _in_driver_up 1
  27. #define _in_driver_up_stop 2
  28. #define _in_driver_down 3
  29. #define _in_driver_down_stop 4
  30. #define _in_passenger_up 5
  31. #define _in_passenger_up_stop 6
  32. #define _in_passenger_down 7
  33. #define _in_passenger_down_stop 8
  34. /*
  35. * The output events
  36. */
  37. #define _motor_up 9
  38. #define _motor_down 10
  39. fmi2Status fmi2SetDebugLogging(fmi2Component fc, fmi2Boolean loggingOn, size_t nCategories, const fmi2String categories[])
  40. {
  41. return fmi2OK;
  42. }
  43. fmi2Status fmi2SetString(fmi2Component fc, const fmi2ValueReference vr[], size_t nvr, const fmi2String value[])
  44. {
  45. return fmi2Error;
  46. }
  47. fmi2Status fmi2GetString(fmi2Component fc, const fmi2ValueReference vr[], size_t nvr, fmi2String value[])
  48. {
  49. return fmi2Error;
  50. }
  51. fmi2Status fmi2SetReal(fmi2Component fc, const fmi2ValueReference vr[], size_t nvr, const fmi2Real value[])
  52. {
  53. return fmi2Error;
  54. }
  55. fmi2Status fmi2GetReal(fmi2Component fc, const fmi2ValueReference vr[], size_t nvr, fmi2Real value[])
  56. {
  57. return fmi2Error;
  58. }
  59. fmi2Status fmi2SetBoolean(fmi2Component fc, const fmi2ValueReference vr[], size_t nvr, const fmi2Boolean value[])
  60. {
  61. FMUInstance* comp = (FMUInstance *)fc;
  62. int i;
  63. for (i = 0; i < nvr; i++)
  64. {
  65. comp->b[vr[i]] = value[i];
  66. }
  67. return fmi2OK;
  68. }
  69. fmi2Status fmi2GetBoolean(fmi2Component fc, const fmi2ValueReference vr[], size_t nvr, fmi2Boolean value[])
  70. {
  71. FMUInstance* comp = (FMUInstance *)fc;
  72. int i;
  73. for (i = 0; i < nvr; i++)
  74. {
  75. value[i] = comp->b[vr[i]];
  76. }
  77. return fmi2OK;
  78. }
  79. fmi2Component fmi2Instantiate(fmi2String instanceName, fmi2Type fmuType, fmi2String fmuGUID, fmi2String fmuLocation, const fmi2CallbackFunctions* functions, fmi2Boolean visible, fmi2Boolean loggingOn)
  80. {
  81. //Declare data structure for fmu instance
  82. FMUInstance* fi;
  83. printf("%s in fmiInstantiate\n",instanceName);
  84. //Perform checks on passed callback functions
  85. if (loggingOn) {
  86. if (!functions->logger);
  87. //return NULL;
  88. }
  89. //Check for instanceName
  90. if (!instanceName || strlen(instanceName)==0) {
  91. // print (and/or log) instanceName is missing
  92. //return NULL;
  93. }
  94. //Check passed GUID to defined model GUID
  95. if (strcmp(fmuGUID, MODEL_GUID))
  96. {
  97. // print (and/or log) GUID doesn't match
  98. //return NULL;
  99. }
  100. //Allocate fmu instance Memory
  101. // TODO check if "canNotUseMemoryManagementFunctions == true/false". If false memory allocation not possible
  102. fi = (FMUInstance *)functions->allocateMemory(1, sizeof(FMUInstance));
  103. fi->functions = functions;
  104. if (fi) {
  105. // Think about what to do with variable values. Using these structs and pointers slows down simulation computations. Maybe only necessary for input, output and tunable parameters??
  106. fi->r = functions->allocateMemory(NUMBER_OF_REALS, sizeof(fmi2Real));
  107. fi->i = functions->allocateMemory(NUMBER_OF_INTEGERS, sizeof(fmi2Integer));
  108. fi->b = functions->allocateMemory(NUMBER_OF_BOOLEANS, sizeof(fmi2Boolean));
  109. fi->s = functions->allocateMemory(NUMBER_OF_STRINGS, sizeof(fmi2String));
  110. fi->Handle = functions->allocateMemory(1,sizeof(Powerwindow));
  111. fi->thePWTimer = functions->allocateMemory(1,sizeof(fmi_timer));
  112. } // variables in predefined arrays (performance issue) --> makes multiple instances of fmu impossible
  113. fi->thePWTimer->callback = &powerwindow_raiseTimeEvent;
  114. powerwindow_initTimer(fi->thePWTimer);
  115. fi->instanceName = functions->allocateMemory(1 + strlen(instanceName), sizeof(char));
  116. fi->GUID = functions->allocateMemory(1 + strlen(fmuGUID), sizeof(char));
  117. strcpy((char*)fi->instanceName, instanceName);
  118. strcpy((char*)fi->GUID, fmuGUID);
  119. fi->loggingOn = loggingOn;
  120. fi->isVisible = visible;
  121. fi->state = fmuInstantiated;
  122. return fi;
  123. }
  124. fmi2Status fmi2SetupExperiment(fmi2Component fc, fmi2Boolean toleranceDefined, fmi2Real tolerance,
  125. fmi2Real startTime, fmi2Boolean stopTimeDefined, fmi2Real stopTime) {
  126. FMUInstance* fi = (FMUInstance*) fc;
  127. printf("%s in fmiSetupExperiment\n",fi->instanceName);
  128. if (fi->state != fmuInstantiated)
  129. {
  130. printf("fmu: %s was not instatiated before calling fmiSetupExperiment\n", fi->instanceName);
  131. return fmi2Error;
  132. }
  133. fi->currentTime = startTime;
  134. fi->stopTimeDefined = stopTimeDefined;
  135. fi->toleranceDefined = toleranceDefined;
  136. if (stopTimeDefined)
  137. {
  138. fi->stopTime = stopTime;
  139. }
  140. if (toleranceDefined)
  141. {
  142. fi->tolerance = tolerance;
  143. }
  144. //TODO
  145. //fi->stepSize = getStepSize();
  146. fi->state = fmuExperimentSettedUp;
  147. fi->next_timer_event = -1;
  148. return fmi2OK;
  149. }
  150. fmi2Status fmi2EnterInitializationMode(fmi2Component fc)
  151. {
  152. FMUInstance* fi = (FMUInstance*) fc;
  153. printf("%s in fmiEnterInitializationMode\n",fi->instanceName);
  154. if (fi->state != fmuExperimentSettedUp)
  155. {
  156. printf("fmu: %s experiment was not set-up before calling fmiEnterInitializationMode\n", fi->instanceName);
  157. return fmi2Error;
  158. }
  159. fi->state = fmuInitMode;
  160. powerwindow_init(fi->Handle);
  161. return fmi2OK;
  162. }
  163. fmi2Status fmi2ExitInitializationMode(fmi2Component fc)
  164. {
  165. FMUInstance* fi = (FMUInstance*) fc;
  166. fmi2Status initStatus = fmi2OK;
  167. printf("%s in fmiExitInitializationMode\n",fi->instanceName);
  168. if (fi->state != fmuInitMode)
  169. {
  170. printf("fmu: %s did not enter Initialization Mode before calling fmiExitInitializationMode\n", fi->instanceName);
  171. return fmi2Error;
  172. }
  173. // TODO
  174. //initStatus = calculateInitialUnknownValues();
  175. //initialize();
  176. powerwindow_enter(fi->Handle);
  177. fi->state = fmuInitialized;
  178. return initStatus;
  179. }
  180. fmi2Status fmi2DoStep(fmi2Component fc , fmi2Real currentCommPoint, fmi2Real commStepSize, fmi2Boolean noPrevFMUState)
  181. {
  182. FMUInstance* fi = (FMUInstance *)fc;
  183. fmi2Status simStatus = fmi2OK;
  184. printf("%s in fmiDoStep(), ct: %f, h:%f\n",fi->instanceName, currentCommPoint, commStepSize);
  185. /*
  186. */
  187. int isfin = fi->next_timer_event > 0;
  188. if(fi->next_timer_event > 0){
  189. if (is_close(fi->next_timer_event, currentCommPoint+commStepSize, 1e-3, 1e-7)){
  190. powerwindow_timeradvance(fi->thePWTimer, (currentCommPoint+commStepSize)*1000); // yakindu in ms not in s
  191. }else{
  192. if (fi->next_timer_event < currentCommPoint + commStepSize){
  193. simStatus = fmi2Discard;
  194. fi->currentTime = fi->next_timer_event;
  195. return simStatus;
  196. }else{
  197. powerwindow_timeradvance(fi->thePWTimer, (currentCommPoint+commStepSize)*1000);
  198. }
  199. }
  200. }else{powerwindow_timeradvance(fi->thePWTimer, (currentCommPoint+commStepSize)*1000);}
  201. if (fi->b[_in_driver_up]){
  202. powerwindowIfaceInput_raise_driver_up(fi->Handle);
  203. printf("raise up driver\n");
  204. }
  205. if(fi->b[ _in_driver_down]){
  206. powerwindowIfaceInput_raise_driver_down(fi->Handle);
  207. printf("raise down driver\n");
  208. }
  209. if(fi->b[_in_driver_up_stop]){
  210. powerwindowIfaceInput_raise_stop(fi->Handle);
  211. printf("raise up stop\n");
  212. }
  213. if(fi->b[ _in_driver_down_stop]){
  214. powerwindowIfaceInput_raise_stop(fi->Handle);
  215. printf("raise driver down stop\n");
  216. }
  217. if(fi->b[_in_passenger_up]){
  218. powerwindowIfaceInput_raise_passenger_up(fi->Handle);
  219. printf("raise up passenger\n");
  220. }
  221. if(fi->b[_in_passenger_down]){
  222. powerwindowIfaceInput_raise_passenger_down(fi->Handle);
  223. printf("raise passenger down\n");
  224. }
  225. if(fi->b[_in_passenger_up_stop]){
  226. powerwindowIfaceInput_raise_stop(fi->Handle);
  227. printf("raise passenger up stop\n");
  228. }
  229. if(fi->b[_in_passenger_down_stop]){
  230. powerwindowIfaceInput_raise_stop(fi->Handle);
  231. printf("raise passenger down stop\n");
  232. }
  233. if(fi->b[_in_obj_detected]){
  234. powerwindowIfaceInput_raise_obj_detected(fi->Handle);
  235. }
  236. powerwindow_runCycle(fi->Handle);
  237. fi->b[_motor_up] = powerwindowIfaceOutput_get_down(fi->Handle);
  238. fi->b[_motor_down] = powerwindowIfaceOutput_get_up(fi->Handle);
  239. /*
  240. * Check timers and set
  241. */
  242. if(fi->thePWTimer->active){
  243. fi->next_timer_event = fi->thePWTimer->nextTime/1000; // yakindu in ms not in s
  244. }else{
  245. fi->next_timer_event = -1;
  246. }
  247. fi->currentTime = currentCommPoint + commStepSize;
  248. return fmi2OK;
  249. }
  250. fmi2Status fmi2Terminate(fmi2Component fc)
  251. {
  252. FMUInstance* fi = (FMUInstance *)fc;
  253. printf("%s in fmiTerminate\n",fi->instanceName);
  254. // do check if fi may be terminated
  255. fi->state = fmuTerminated;
  256. return fmi2OK;
  257. }
  258. void fmi2FreeInstance(fmi2Component fc)
  259. {
  260. FMUInstance* fi = (FMUInstance*) fc;
  261. printf("%s in fmiFreeInstance\n",fi->instanceName);
  262. if (fi) {
  263. fi->functions->freeMemory(fi->r);
  264. fi->functions->freeMemory(fi->i);
  265. fi->functions->freeMemory(fi->b);
  266. fi->functions->freeMemory(fi->Handle);
  267. fi->functions->freeMemory(fi->s);// TODO has to be done with loop
  268. fi->functions->freeMemory((void*)fi->instanceName);
  269. fi->functions->freeMemory((void*)fi->GUID);
  270. fi->functions->freeMemory((void*)fi);
  271. }
  272. }
  273. //To be implemented
  274. const char* fmi2GetVersion() {
  275. printf("Function fmiGetVersion not supported\n");
  276. return NULL;
  277. }
  278. const char* fmi2GetTypesPlatform() {
  279. printf("Function fmiGetTypesPlatform not supported\n");
  280. return NULL;
  281. }
  282. fmi2Status fmi2Reset(fmi2Component fc)
  283. {
  284. printf("Function fmiReset not supported\n");
  285. return fmi2Error;
  286. }
  287. fmi2Status fmi2SetInteger(fmi2Component fc, const fmi2ValueReference vr[], size_t nvr, const fmi2Integer value[])
  288. {
  289. printf("Function fmiSetInteger not supported\n");
  290. return fmi2Error;
  291. }
  292. fmi2Status fmi2GetInteger(fmi2Component fc, const fmi2ValueReference vr[], size_t nvr, fmi2Integer value[])
  293. {
  294. printf("Function fmiGetInteger not supported\n");
  295. return fmi2Error;
  296. }
  297. /*******OWN IMPLEMENTATION OF Get/Set FMU state*******/
  298. fmi2Status fmi2GetFMUstate (fmi2Component c, fmi2FMUstate* FMUstate) {
  299. FMUInstance* orig = (FMUInstance*)c;
  300. FMUInstance* fi = (FMUInstance *)FMUstate;
  301. fi = orig->functions->allocateMemory(1, sizeof(FMUInstance));
  302. *FMUstate = fi;
  303. if (fi) {
  304. // Think about what to do with variable values. Using these structs and pointers slows down simulation computations. Maybe only necessary for input, output and tunable parameters??
  305. fi->r = orig->functions->allocateMemory(NUMBER_OF_REALS, sizeof(fmi2Real));
  306. fi->i = orig->functions->allocateMemory(NUMBER_OF_INTEGERS, sizeof(fmi2Integer));
  307. fi->b = orig->functions->allocateMemory(NUMBER_OF_BOOLEANS, sizeof(fmi2Boolean));
  308. fi->s = orig->functions->allocateMemory(NUMBER_OF_STRINGS, sizeof(fmi2String));
  309. fi->Handle = orig->functions->allocateMemory(1,sizeof(Powerwindow));
  310. } // variables in predefined arrays (performance issue) --> makes multiple instances of fmu impossible
  311. fi->instanceName = orig->functions->allocateMemory(1 + strlen(orig->instanceName), sizeof(char));
  312. fi->GUID = orig->functions->allocateMemory(1 + strlen(orig->GUID), sizeof(char));
  313. strcpy((char *)fi->instanceName, (char *)orig->instanceName);
  314. strcpy((char *)fi->GUID, (char *)orig->GUID);
  315. fi->functions = orig->functions;
  316. fi->loggingOn = orig->loggingOn;
  317. fi->isVisible = orig->isVisible;
  318. fi->state = orig->state;
  319. fi->stepSize = orig->stepSize;
  320. fi->startTime = orig->startTime;
  321. fi->stopTime = orig->stopTime;
  322. fi->currentTime = orig->currentTime;
  323. fi->next_timer_event = orig->next_timer_event;
  324. powerwindow_copy(orig->Handle, fi->Handle);
  325. //copy r
  326. int i=0;
  327. for (i=0; i< NUMBER_OF_REALS;i++){
  328. printf("Setting real: %i %f\n", i, orig->r[i]);
  329. fi->r[i] = orig->r[i];
  330. printf("Setted real: %i %f\n", i, fi->r[i]);
  331. }
  332. //copy s
  333. for (i=0; i< NUMBER_OF_STRINGS;i++){
  334. fi->s[i] = orig->s[i];
  335. }
  336. //copy i
  337. for (i=0; i< NUMBER_OF_INTEGERS;i++){
  338. fi->i[i] = orig->i[i];
  339. }
  340. //copy b
  341. for (i=0; i< NUMBER_OF_BOOLEANS;i++){
  342. fi->b[i] = orig->b[i];
  343. }
  344. // copy pw
  345. return fmi2OK;
  346. }
  347. fmi2Status fmi2SetFMUstate (fmi2Component c, fmi2FMUstate FMUstate) {
  348. FMUInstance* orig = (FMUInstance*)FMUstate;
  349. FMUInstance* fi = (FMUInstance*)c;
  350. //set time etc correct, name and GUID should still be ok ;-)
  351. printf("setting time values from %f to %f\n", fi->currentTime, orig->currentTime);
  352. fi->state = orig->state;
  353. fi->stepSize = orig->stepSize;
  354. fi->startTime = orig->startTime;
  355. fi->stopTime = orig->stopTime;
  356. fi->currentTime = orig->currentTime;
  357. fi->next_timer_event = orig->next_timer_event;
  358. printf("setting real values\n");
  359. //copy r
  360. int i=0;
  361. for (i=0; i< NUMBER_OF_REALS;i++){
  362. fi->r[i] = orig->r[i];
  363. }
  364. printf("setting string values\n");
  365. //copy s
  366. for (i=0; i< NUMBER_OF_STRINGS;i++){
  367. fi->s[i] = orig->s[i];
  368. }
  369. //copy i
  370. for (i=0; i< NUMBER_OF_INTEGERS;i++){
  371. fi->i[i] = orig->i[i];
  372. }
  373. //copy b
  374. for (i=0; i< NUMBER_OF_BOOLEANS;i++){
  375. fi->b[i] = orig->b[i];
  376. }
  377. powerwindow_copy(orig->Handle,fi->Handle);
  378. return fmi2OK;
  379. }
  380. /****************************************************/
  381. fmi2Status fmi2FreeFMUstate(fmi2Component c, fmi2FMUstate* FMUstate) {
  382. printf("Function fmiFreeFMUstate not supported\n");
  383. return fmi2Error;
  384. }
  385. fmi2Status fmi2SerializedFMUstateSize(fmi2Component c, fmi2FMUstate FMUstate, size_t *size) {
  386. printf("Function fmiSerializedFMUstateSize not supported\n");
  387. return fmi2Error;
  388. }
  389. fmi2Status fmi2SerializeFMUstate (fmi2Component c, fmi2FMUstate FMUstate, fmi2Byte serializedState[], size_t size) {
  390. printf("Function fmiSerializeFMUstate not supported\n");
  391. return fmi2Error;
  392. }
  393. fmi2Status fmi2DeSerializeFMUstate (fmi2Component c, const fmi2Byte serializedState[], size_t size, fmi2FMUstate* FMUstate) {
  394. printf("Function fmiDeSerializeFMUstate not supported\n");
  395. return fmi2Error;
  396. }
  397. fmi2Status fmi2GetDirectionalDerivative(fmi2Component c, const fmi2ValueReference vUnknown_ref[], size_t nUnknown,
  398. const fmi2ValueReference vKnown_ref[] , size_t nKnown, const fmi2Real dvKnown[], fmi2Real dvUnknown[]) {
  399. printf("Function fmiGetDirectionalDerivative not supported\n");
  400. return fmi2Error;
  401. }
  402. fmi2Status fmi2SetRealInputDerivatives(fmi2Component c, const fmi2ValueReference vr[], size_t nvr,
  403. const fmi2Integer order[], const fmi2Real value[]) {
  404. printf("Function fmiGetDirectionalDerivative not supported\n");
  405. return fmi2Error;
  406. }
  407. fmi2Status fmi2GetRealOutputDerivatives(fmi2Component c, const fmi2ValueReference vr[], size_t nvr,
  408. const fmi2Integer order[], fmi2Real value[]) {
  409. printf("Function fmiGetDirectionalDerivative not supported\n");
  410. return fmi2Error;
  411. }
  412. fmi2Status fmi2CancelStep(fmi2Component c) {
  413. printf("Function fmiGetDirectionalDerivative not supported\n");
  414. return fmi2Error;
  415. }
  416. fmi2Status fmi2GetStatus(fmi2Component c, const fmi2StatusKind s, fmi2Status *value) {
  417. printf("Function fmiGetStatus not supported\n");
  418. return fmi2Error;
  419. }
  420. fmi2Status fmi2GetRealStatus(fmi2Component c, const fmi2StatusKind s, fmi2Real *value) {
  421. if(s == fmi2LastSuccessfulTime){
  422. FMUInstance* comp = (FMUInstance*) c;
  423. *value = comp->currentTime;
  424. return fmi2OK;
  425. }
  426. printf("Function fmiGetRealStatus not supported\n");
  427. return fmi2Error;
  428. }
  429. fmi2Status fmi2GetIntegerStatus(fmi2Component c, const fmi2StatusKind s, fmi2Integer *value) {
  430. printf("Function fmiGetIntegerStatus not supported\n");
  431. return fmi2Error;
  432. }
  433. fmi2Status fmi2GetBooleanStatus(fmi2Component c, const fmi2StatusKind s, fmi2Boolean *value) {
  434. printf("Function fmiGetBooleanStatus not supported\n");
  435. return fmi2Error;
  436. }
  437. fmi2Status fmi2GetStringStatus(fmi2Component c, const fmi2StatusKind s, fmi2String *value) {
  438. printf("Function fmiGetStringStatus not supported\n");
  439. return fmi2Error;
  440. }