Eclipse SUMO - Simulation of Urban MObility
sumo2fmi_bridge.c
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2020-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
19 // Implementation of the FMI to SUMO bridge features
20 /****************************************************************************/
21 
22 #ifdef _MSC_VER
23 // Avoid warnings in windows build because of strcpy instead of strcpy_s,
24 // because the latter is not available on all platforms
25 #define _CRT_SECURE_NO_WARNINGS
26 #pragma warning(disable:4820 4514 5045 4710)
27 #endif
28 
30 #include <string.h>
31 #include "libsumocpp2c.h"
32 #include "sumo2fmi_bridge.h"
33 
34 /* Explicit definition of unused parameters to avoid compiler warnings */
35 #define UNREFERENCED_PARAMETER(P) (P)
36 
37 #define BUFFER_SIZE 256
38 
39 void
41  char sumoHomePath[BUFFER_SIZE];
42  /* check if $SUMO_HOME exists */
43  if (!getenv("SUMO_HOME")) {
44  sumo2fmi_logError(comp, "$SUMO_HOME was not found.");
45  return;
46  }
47  /* check if BUFFER_SIZE is large enough */
48  if (snprintf(sumoHomePath, BUFFER_SIZE, "%s", getenv("SUMO_HOME")) >= BUFFER_SIZE) {
49  sumo2fmi_logError(comp, "$SUMO_HOME path is longer than %d chars.", BUFFER_SIZE);
50  return;
51  }
52 
53  comp->freeMemory(comp->libsumoCallOptions);
54 
55  char defaultCallOptions[BUFFER_SIZE * 2];
56  snprintf(defaultCallOptions, BUFFER_SIZE * 2, "-c %s/tools/game/grid6.sumocfg", sumoHomePath);
57  comp->libsumoCallOptions = (char*)comp->allocateMemory(1 + strlen(defaultCallOptions), sizeof(char));
58  strcpy((char*)comp->libsumoCallOptions, (char*)defaultCallOptions);
59 }
60 
61 void
62 sumo2fmi_logEvent(ModelInstance* comp, const char* message, ...) {
63  if (!comp->logEvents) {
64  return;
65  }
66 
67  va_list args;
68  va_start(args, message);
69  sumo2fmi_logMessage(comp, fmi2OK, "logEvents", message, args);
70  va_end(args);
71 }
72 
73 void
74 sumo2fmi_logError(ModelInstance* comp, const char* message, ...) {
75  if (!comp->logErrors) {
76  return;
77  }
78 
79  va_list args;
80  va_start(args, message);
81  sumo2fmi_logMessage(comp, fmi2Error, "logStatusError", message, args);
82  va_end(args);
83 }
84 
85 void
86 sumo2fmi_logMessage(ModelInstance* comp, int status, const char* category, const char* message, va_list args) {
87  va_list args1;
88  size_t len = 0;
89  char* buf = "";
90 
91  va_copy(args1, args);
92  len = vsnprintf(buf, len, message, args1);
93  va_end(args1);
94 
95  va_copy(args1, args);
96  buf = comp->allocateMemory(len + 1, sizeof(char));
97  vsnprintf(buf, len + 1, message, args);
98  va_end(args1);
99 
100  comp->logger(comp->componentEnvironment, comp->instanceName, status, category, buf);
101 
102  comp->freeMemory(buf);
103 }
104 
105 // Retrieve the integer value for a single variable
109 
110  switch (vr) {
111  case 2:
112  *value = libsumo_vehicle_getIDCount();
113  return fmi2OK;
114  default:
115  return fmi2Error;
116  }
117 }
118 
121  switch (vr) {
122  case 0:
123  *value = comp->libsumoCallOptions;
124  return fmi2OK;
125  case 1:
126  *value = comp->getterParameters;
127  return fmi2OK;
128  case 4:
130  return fmi2OK;
131  case 5:
132  libsumo_vehicle_getLaneID(comp, value);
133  return fmi2OK;
134  case 6:
135  libsumo_vehicle_getPosition(comp, value);
136  return fmi2OK;
137  default:
138  return fmi2Error;
139  }
140 }
141 
144  switch (vr) {
145  case 0:
146  comp->freeMemory(comp->libsumoCallOptions);
147  comp->libsumoCallOptions = (char*)comp->allocateMemory(1 + strlen(value), sizeof(char));
148  strcpy(comp->libsumoCallOptions, value);
149  return fmi2OK;
150  case 1:
151  comp->freeMemory(comp->getterParameters);
152  comp->getterParameters = (char*)comp->allocateMemory(1 + strlen(value), sizeof(char));
153  strcpy(comp->getterParameters, value);
154  return fmi2OK;
155  case 3:
157  return fmi2OK;
158  default:
159  return fmi2Error;
160  }
161 }
162 
164 sumo2fmi_step(ModelInstance* comp, double tNext) {
166 
167  libsumo_step(tNext);
168  return fmi2OK;
169 }
fmi2Status
@ fmi2OK
@ fmi2Error
unsigned int fmi2ValueReference
const fmi2Char * fmi2String
void libsumo_vehicle_moveToXY(const char *paramString)
void libsumo_vehicle_getLaneID(ModelInstance *comp, const char **result)
void libsumo_vehicle_getPosition(ModelInstance *comp, const char **result)
void libsumo_vehicle_getParameterWithKey(ModelInstance *comp, const char **result)
void libsumo_step(double time)
int libsumo_vehicle_getIDCount(void)
void * componentEnvironment
char * getterParameters
Parameters stored for the next (libsumo) getter call. Workaround for FMIv2 not allowing input values ...
allocateMemoryType allocateMemory
const char * instanceName
freeMemoryType freeMemory
loggerType logger
char * libsumoCallOptions
fmi2Status sumo2fmi_getString(ModelInstance *comp, const fmi2ValueReference vr, fmi2String *value)
void sumo2fmi_set_startValues(ModelInstance *comp)
fmi2Status sumo2fmi_step(ModelInstance *comp, double tNext)
fmi2Status sumo2fmi_getInteger(ModelInstance *comp, const fmi2ValueReference vr, int *value)
#define BUFFER_SIZE
void sumo2fmi_logError(ModelInstance *comp, const char *message,...)
#define UNREFERENCED_PARAMETER(P)
fmi2Status sumo2fmi_setString(ModelInstance *comp, fmi2ValueReference vr, fmi2String value)
void sumo2fmi_logMessage(ModelInstance *comp, int status, const char *category, const char *message, va_list args)
void sumo2fmi_logEvent(ModelInstance *comp, const char *message,...)