The wind power architecture consists of the wind power digital twin, the physical twin, and their interaction (as shown in Fig. 1). The digital twin contains the following main elements:
-
Environment (e.g., wind, land) used for visualising the area
-
Connection to Physical Twin
-
Physical Twin
-
Wind turbine plugin
-
Wind
-
Input interface
-
Prediction
Environment
The physical twin of wind power is a software application created as a stand-in for the real-world environment. The environment utilises the MQTT plugin for receiving changes of state in the physical twin and publishing information for storage. It should be noted that MQTT stands for MQ Telemetry Transport, and the protocol is a set of rules that defines how IoT devices can publish and subscribe to data over the Internet.
In this study, the environment is modelled to match the selected area by first creating an empty world partition level. This creates an empty black world without lighting or a landscape. Hereafter, the lighting and atmosphere were created using the Environment Light Mixer. The Environment Light Mixer eases the process of creating the atmosphere and lighting. The mixer (see Fig. 2) was used to create the sky light, atmospheric light, sky atmosphere, volumetric clouds, and height fog resulting in a naturally lighted environment—see Fig. 3.
The landscape was created using the landscaping tool provided by Unreal Engine. The texture for the landscape was selected using Quixel Bridge, which provided access to the Quixel MegaScan library. The library contains assets, surfaces, etc. categorized into collections such as broadleaf forest, American sidewalk, wetland, etc. For the landscape, the surface “Beach Sand” was chosen and imported into the project, resulting in the landscape seen in Fig. 4. Hereafter, The water was created using the Water plugin provided by Epic Games—see Fig. 5.
After the environment was created, the wind turbines from the wind turbine plugin could be placed—see Figs. 6 and 7.
Connection to physical twin
The MQTT connection to the physical twin was implemented in Blueprints using the MQTT Utilities Plugin developed by Nineva Studios (Studios N 2022). The implementation was placed in the Environment level blueprint. This allowed the environment to connect and receive the state of the physical twin. Figure 8 shows the blueprint implementation of the connection to the MQTT broker. First, an MQTT client is created based on an MQTT client configuration containing the host, port and the ID of the client application. Hereafter, the message handler is defined. The message handler is set to the function “HandleMessage” where the MQTT message is passed as an argument (See Fig. 9). After the message handler is configured the client connects to the broker. Lastly, the client is set to subscribe to the topic used by the physical twin to publish its state.
When a message is received from the broker, the function “Handle Message” is executed. The function breaks the message object to examine the topic of the message. Based on the topic, the message is processed accordingly. Figure 9 shows that the topic “wind” triggers the function “Wind Speed Received” followed by “Print Message”, whereas messages from other topics only are processed by “Print Message”.
The “Wind Speed Received” function extracts the wind speed from the MQTT message object and calls the “Notify Wind Observers” function seen in Fig. 10. The function utilizes the observer pattern by finding all Actors and Widgets in the world implementing the WindSpeedObserver interface and notifying them of the new wind speed and altitude.
Physical twin
To simplify the creation of the digital twin, the physical twin was mocked using a python application allowing the user to notify the digital twin with new wind speeds via MQTT. The python script connects to the MQTT broker and publishes the wind speed before disconnecting again.
Wind turbine plugin
The wind turbine plugin is a UE5 plugin which enables the use of the wind turbine implementations in multiple projects. The plugin consists of visual models and their associated wind turbine implementations.
The implementations of the wind turbines were designed to allow for fast future additions of new wind turbines to the plugin. The class hierarchy in Fig. 11 shows the wind turbine interface. This interface allows the components in the Planning Application that only require the functionality of the wind turbine to depend on a generalised type, allowing for reusability in the application.
The abstract implementation expands this by having fields for the wind turbine specs. Like the interface, the abstract class allows for reusability when working with the wind turbine plugin by ensuring that each wind turbine implementation contains the required specs to function in the environment. The abstract class also implement the two methods IsWithinOperational-Speed and RotationPerSecond dictated by the interface. This allows the concrete implementations to use or override the implementations. If implementations in the abstract class are used, the concrete applications only need to define the specs via the fields and implement the EnergyProduced method.
The wind turbine hierarchy was implemented in C + + . The implementation of IWindTubine- see Listing 1—defined the functions. Unreal Engine generated the interface template inheriting from UInterface. The template was extended with the three functions. Each function is annotated with UFUNCTION to let UE interpret the functions. Furthermore, the tag BlueprintCallable allows blueprints to call the function, while BlueprintNativeEvent allows blueprints to implement the function.
The implementation of the AbstractWindTurbine class was annotated with the tags Abstract and Blueprintable—see Listing 2. Abstract defines that the class can not be initialized during runtime. Blueprintable allows for blueprint implementations of the class. The AbstractWindTurbine implements the IWindturbine interface. Furthermore, the class inherits from the UActorComponent class provided by UE. By inheriting from UActorComponent, the wind turbine implementations can be used as logic components by actors in the environment.
The AbstractWindTurbine class defined the properties of a wind turbine. This was implemented as floating point variables on the class with the UPROPERTY annotation—see Listing 3.
In addition to the properties, the abstract class implemented the functions IsWithinOperationalSpeed and RotationPerSecond. The implementation of the functions in the abstract class allowed for the reuse of the implementations for all wind turbines inheriting the abstract class. The functions were implemented firstly in the header file—see Listing 4—and thereafter in the C + + file. The header file defined that the functions had to be implemented by the abstract class. In addition, the EnergyProduced function had to be implemented to throw an error if not extended due to how inheritance is implemented in UE.
The C + + file contained the implementations for the two functions – see Listing 5. The function IsWithinOperationalSpeed checks if the wind speed is within the operational speed and returns a Boolean based on the check. The function RotationPerSecond calculates the number of rotations of the wind turbine rotor based on the wind speed. First, the tip speed in m/s is calculated based on the wind speed and the tip speed ratio of the wind turbine. The speed is ensured that it can not be greater than the max tip speed. Hereafter the rotor circumference is calculated in meters. The two values are thereafter used to calculate the number of rotations per second.
The AbstractWindTurbine is implemented by the classes VestasV164 and EnerconE126. The implementation of a wind turbine shown here is based on the Vestas V164. Listing 6 shows that the properties from the abstract class are initialized with the wind turbine specifications. In addition to the properties, the EnergyProduced function is implemented accordingly to the power curve found for the specific model.
Wind
The built-in wind system in Unreal Engine only affects foliage objects. Therefore the wind turbine was not affected. To solve the problem, the wind was stored in an invisible object in the environment and the wind turbines could receive the current wind speed from this object. Due to the difference in the height of the wind turbines, the wind speed is adjusted to the height of the wind turbine hub using the wind profile power law. Equation 1 shows the rearranged wind profile power law, where u is the wind speed at height z and ur is the known wind speed at height zr. Lastly, the exponent α is the coefficient of the stability in the atmosphere (Touma 1977).
$$u={u}_{r}{\left(\frac{z}{{z}_{r}}\right)}^{\mathrm{\alpha }}$$
(1)
Equation 1. Wind profile power law.
The adjustment of the wind speed was performed by each of the observers implementing the WindSpeedObserver interface. This allows each wind turbine model to adjust the new wind speed to the height of the hub. To allow for code reuse, a blueprint function library was created. The library contained an implementation of the rearranged wind power law—see Fig. 12.
Input interface
The interface for receiving and sending messages was based on MQTT topics and the messages were formatted as JSON strings. Listing 7 is an example of a message sent from the physical twin containing the latest wind speed. The JSON object contains the following:
-
timestamp—int64—Unix timestamp of when the message is sent.
-
wind_speed—float—Wind speed in meters per second.
-
altitude—int32—The altitude of the wind speed reading in meters.
Prediction
The prediction mechanism in the digital twin was implemented as a series of functions in a blueprint function library able to calculate:
-
Number of hours where the wind turbine produces energy
-
Max wind speed the wind turbine experiences
-
Number of hours at rated energy production
-
Hourly production
-
The total amount of energy produced for a period
All functions take an object of the abstract wind turbine, a list of hourly wind speeds, and the altitude of the measured wind speeds as input.
The number of hours with production was implemented as seen in Fig. 13. When the function is called the list of wind speed values is converted to the altitude of the wind turbine hub using the wind profile power law. The new wind speeds are iterated, checking if the value is within the cut-in and cut-out values of the wind turbine. If the check is true, an integer variable is incremented. When the list has been iterated, the variable is returned as the number of hours with production.
The function for finding the highest wind speed the wind turbine experiences was implemented as seen in Fig. 14. When the function is called, the wind speeds are converted to match the height of the wind turbine hub. Hereafter, the largest value is found and returned.
The function for calculating the hours where the wind turbine is at its rated production was implemented as seen in Fig. 15. When the function is called, the wind speeds are converted to match the height of the wind turbine hub. Hereafter, the wind speeds are iterated and used to calculate the power output from the wind turbine. If the produced power is equal to the rated power of the wind turbine, an integer variable is incremented. When the array has been iterated, the integer variable is returned.
The function for calculating the hourly production for a wind turbine was implemented as seen in Fig. 16. First, the wind speeds are converted to the height of the wind turbine hub. The wind speeds are thereafter looped and used to calculate the production using the power curve of the wind turbine. The production value is added to an array which is returned when the loop is completed.
The function for calculating the total production for a wind turbine was implemented as seen in Fig. 17. The function uses the Hourly Production function described above. The sum of the array is thereafter found and returned.