neural_body package¶
Submodules¶
neural_body.BenrulesRealTimeSim_v3 module¶
Real-Time basic simulator for planetary motions with neural network inference for prediction of an arbitrary number of satellites.
This module contains the BenrulesRealTimeSim class, which creates a real time simulator of the sun, planets, pluto, and an arbitrary number of satellites. The initial simulation was forked from benrules2 on Github at the below link. https://gist.github.com/benrules2/220d56ea6fe9a85a4d762128b11adfba This simulator simulated a system for a fixed number of time steps and output the results to a custom class and dictionary.
v2 of the simulator converted it to a real time simulator using a Pandas dataframe to track simulation history and rewind back in time. It also used a feed-forward neural network that predicted the location of a specifically trained body given the positions of every other body. It also used dictionaries to store current simulation states and calculated steps from acceleration to velocity to displacement using loops. Overall, this presented the below challenges: 1. High memory usage. Since the simulation for all time was stored to a
Pandas Dataframe in memory, this meant that as the simulation ran, the memory usage would continually grow.
- Slow simulation computations. Many of the calculations used double and triple nested loops to calculte gravitational influence on a body and convert from the acceleration to velocity and velocity to displacement domains.
- CPU idle time. Since all calculations were done at run time, the simulator would sit at idle rather than continuing to perform calculations in the background.
v3, while taking inspiration from the original benrules simulator, no longer resembles the original. v3 is extensible to an arbitrary number of satellites in the simulation. The LSTM neural net it uses relies on the body acceleration and current velocities to predict where the body will go for the next 20 time steps. The current behavior of the neural net is strange, which is why in the config files, there is an option to turn it off and rely on the simulator only. Much more feature engineering, data generation, and hyperparameter tuning is needed to accurately mimic orbital behavior. One of the main challenges that arose as well with the LSTM network is slower inference time. Without background processing and predicting multiple time steps at each inference, performance would be sub 3 fps. Because of this challenge and the v2 challenges, the below changes were made to v3. 1. Instead of using a Pandas dataframe that could require large amounts of
memory with longer simulation durations, a new cache-archive system was developed to exchange simulation tracking between a numpy array that stores a sequence of 100 values in memory and an hdf5 file that stores a total record of the simulation so far. As time jumps are performed, trackers and functions handle the flushing of new values from the cache to the archive and loading of time steps from the archive. Having a history stored in numpy arrays also helps with vectorized computation since time steps don’t need to be copied to other data structures for use in calculations.
- Slow simulation computations were addressed by fully vectorizing all simulation computations using numpy linear algebra and getting rid of all computation loops. This vectorization was done while maintaining the capability to add an arbitrary number of bodies to the simulation. Slow inference time with the neural network was addressed by trying to predict 20 time steps ahead given a sequence of 4 time steps as input to an LSTM network. This enabled 1 inference cycle to produce 20 time steps.
- Since the simulator is inherently a serial problem (in order to predict the next state, we must know the previous stat), the best option to address performance was to ensure a producer/consumer model was uses to continually run a producer in a background process that calculated future time steps even while the simulation is paused or when there is available CPU time on another processor. Main simulation calculations were moved to an external process that calculates future time steps. This process maintains a pre-queue of about 5000 future time steps. It feeds a queue of 100 time steps between the background process and the main simulator that provides positions to the front end. In order to reliably keep the main queue filled, the background process continually tries to keep the main queue filled with values from the pre-queue. It is able to continually perform this task since the calculations filling the pre-queue are launched and performed in a separate thread. This help mitigate the degradation of the buffer that the main queue provides.
In addition to the above improvements, benchmarking and queue monitoring occur to ensure that the system runs at a steady pace that the simulator can keep up with. The user can burst to 2X or 1X, but if the queue begins to degrade, the simulator will automatically revert back to 1X. This is mainly for when the neural network is used. When not using the neural network, the simulator will usually revert to a max framerate of 50 fps and even when running at faster speeds, keep up without throttling back.
-
class
neural_body.BenrulesRealTimeSim_v3.BenrulesRealTimeSim(sat_config_file)¶ Bases:
objectClass containing real-time simulator for planet motions an an arbitrary number of satellites. Can operate with and without a neural net to predict the motions of the satellites.
Instance Variables: :ivar lock: Shared lock for stdout when troubleshooting or printing
messages from background processes.Variables: - time_step – Duration of time step the simulator is running on.
- current_working_directory – Current location of simuator script.
- nn_path – Path to the .h5 file containing the LSTM neural net.
- len_lstm_in_seq – Number of time steps in the input sequence to the LSTM network.
- len_lstm_out_seq – Number of time steps that can be predicted by the LSTM network in a single inference.
- num_processes – Max number of processes the CPU can handle.
- out_queue_max_size – Max size of the queue carrying information from the background simulation process and the functions that serve position data to the front end.
- output_queue – The queue that receives data from the background simulation process as the producer and the functions that serve position data to the front end as consumers.
- keep_future_running – Shared state integer that signals the while loop that runs the background simulation to stop, close out all threads and flush all queues.
- in_planet_df – Dataframe containing the initial planet data to launch the simulator.
- sim_archive_location – Location to store the .hdf5 file that contains all the cache data from the simulator for the entire simulation.
- latest_ts_in_archive – The latest time step stored currently in the hdf5 archive file.
- current_time_step – The current time step required to be served by the simulator. Controls whether to grab data from archive, queue, or the future queue.
- max_time_step_reached – The maximum time step the simulator has ever served to the front end.
- curr_cache_size – Current size of the in-memory caches.
- max_cache_size – Max allowed size of the in-memory caches.
- latest_ts_in_cache – Latest time step stored in the current cache state.
- num_planets – Number of planets being simulated.
- num_sats – Number of satellites loaded into the simualtion.
- planet_pos_cache – Numpy array that caches the positions of all planets for the max size of the cache.
- planet_vel_cache – Numpy array that caches the velocities of all planets for the max size of the cache.
- sat_pos_cache – Numpy array that caches the positions of all satellites for the max size of the cache.
- sat_vel_cache – Numpy array that caches the velocities of all satellites for the max size of the cache.
- sat_acc_cache – Numpy array that caches the accelerations of all satellites for the max size of the cache.
- masses – Numpy array containing the masses of all bodies in the system.
- body_names – A list containing the names of all bodies in the system.
- future_queue_process – Object containing the background process that is continually calculating future time steps.
- max_fps – After simulation initialization, contains the maximum framerate the current system running the simulation can run at.
-
body_names¶ Getter that returns a list of the names of all bodies in the simualtion.
Return body_names: List with the names of all bodies in the system.
-
current_time_step¶ Getter that retrieves the current time step the simulator is at.
Return current_time_step: Current time step the simulator is at.
-
get_next_sim_state_v2()¶ Function that serves the positions of all bodies in the next time step based on the internally tracked time step.
Based on the current time step, this function will either retrieve values from the future queue that has new, calculated time steps, retrieve values from the cache directly, or fill the cache with values from the archive file and retrieve from the new, filled cache.
Returns: - Numpy array with positions of all bodies in the simulation.
- Boolean variable telling the front end to slow down request rate to allow background simulation process to fill back up.
-
max_fps¶ Getter that returns the calculated max framerate the current system can run at safely while maintaining future time step calculations.
Return max_fps: Max framerate the current simulation can run at steadily.
-
time_step_duration¶ Getter that retrieves the duration of the time step in seconds that the simulation uses to calculate new positions.
Return time_step_duration: Duration of the simulation time step in seconds.
neural_body.grav2 module¶
-
neural_body.grav2.boxes(screen, scr_width, scr_height)¶ Function that places UI divider boxes on the screen Function to draw the boundries of the three areas of the application. These being the menu, solar system view, and inner planet view. These views are static and rendered first, putting them at the bottom of the visual instnaces List of input parameters: :param screen: the usable area for drawing within the application
windowParameters: - scr_width – the width of the screen in pixels. This will always be an integer used for object placement math.
- scr_height – the height of the screen in pixels. This will always be an integer used for object placement math.
- scr_height – the height of the screen in pixels. This will always be an integer used for object placement math.
-
neural_body.grav2.click_handler(click_now)¶ Function to capture characteristics of user clicks Function to easily capture mouse location and actions. click_now is used to prevent clicks from being repeated each time the simulation screen is re-rendered. List of input parameters: :param click_now: contains an integer of either 0 or 1 that denotes
whether or not the mouse was pressed down during the previous program cycle in order to handle sustained pressesList of returned values: :returns: - action_flag - Flag is set to 0 if the click is a continued press,
1 if the click is new- click_now - Set to 0 if the left mouse button is released, 1 if pressed
- click_x - The inetger x-coordinate of the mouse
- click_y - The integer y-coordinate of the mouse
-
neural_body.grav2.main()¶ Main function of the program, where all of the fun begins. Basic environment attributes are set such as the screen dimensions, number of planets (total on screen, main view plus inner planet view), the planet tail length, and the program clock
Method that will display main menu, as well as handles actions to the menu. If mouse is hovering over menu item the text for that menu item will change from grey to white. If clicked on or hovered over, menu item will activate. Methods used: - text_handler - displays text on the screen - pygame.draw - draws rectangles on the screen to separate parts of
the application.List of input parameters: :param screen: window created by pygame used to display application :param states: A list of the current states of the system, see list
of states belowParameters: - scr_width – An in that represents the width of the screen
- scr_height – An int that represents the height of the screen
- numDays – An int that represents how many Earth days have passed in the simulation
List of Menu Selection Areas: - play_pause - List that contains the length and width parameters
for the play/pause menu option- toggle - List that contains the length and width parameters for
- the view toggle menu option
- adjust - List that contains the length and width parameters for
- the speed adjustment menu option
- upload - List that contains the length and width parameters for
- the file upload menu option
- nasa_right - List that contains the length and width parameters
- for the display pluto menu option
- key_menu_option - List that contains the length and width
- parameters for the display key menu option
- day_select - List that contains the length and width parameters
- for the point in time selection menu option
List of states of the application: - pause - An int that specifies whether or not the simulation runs,
0 means it’s running, 1 means it is paused- view - An int that determines what view is displayed, 0 for
- overhead view, 1 for side view
- speed - An int that determines the speed of the simulation,
- 1x, 2x, 4x, etc
- rev - An int that would determine if the simulation is running
- in reverse or not, not currently implemented
- click_now - An int that determines whether the mouse is being
- clicked, 0 means no click, 1 means click
- input_active - An int that determines whether the file input
- text box shows, 0, means no show, 1 means it will show
- nasa - String that activates pluto, Yes, means NASA is correct,
- and pluto is not a planet, No means NASA is incorrect and pluto is a planet
- input2_active - An int that displays the travel to a day
- textbox, 0 means no show, 1 means it shows
- textbox2_active - An int that determines whether the travel to
- textbox is showing, 0 means no, 1 means yes
- input2_text - String that determines what day will be traveled
- to after the travel to day is determined
Returns: returns the above list of states to feed information to the program for control of specific features
Function to place menu option text on the screen Function to display the base text of the menu on the screen. All values start out as light grey but are overlaid with white text by another method when moused over List of input parameters: :param screen: the usable area for drawing within the application
windowParameters: - scr_width – the width of the screen in pixels. This will always be an integer used for object placement math.
- scr_height – the height of the screen in pixels. This will always be an integer used for object placement math.
-
neural_body.grav2.orbits(screen, num_planets, tail_length, clock, scr_width, scr_height)¶ Function that runs the simulation. Handles function calls to display all visual elements and determine orbital locations. This class operates as the master of the program, containing the infinite loop that the program relies on in order to function. All important interactions between the various components of the program are routed through this class, and many vital mathematic operations reside within it. Because global variables are not used, this class acts as an intermediate to pass variables as parameters and receive them back as returned values. Methods used: - pygame.draw.circle - replicates the planets drawn on the screen - text_handler - names each of the replicated planets - BenrulesRealTimeSim - creates a real time simulator of the sun,
planets, and pluto.- pygame.image.load - loads an image from a file
- pygame.transform.scale - scales an image to a specified width and height
- get_next_sim_state_v2 - updates the dictionary of current simulation data to the next time_step
- screen.fill - changes the color of the entire pygame canvas
- screen.blit - method to display a supplied image on the scren as output
- pygame.draw.line - pygame method used to draw a line, here is used to draw the trails
- pygame.draw.circle - pygame method used to draw circles, here used to represent the planets
- current_time_step - Setter function used to change the point in time of the simulation
- pygame.event.get() - method to handle a user interaction event
- pygame.quit() - Pygame method used to quit running pygame
- sys.exit() - Method used to exit the program
- pygame.display.flip() - method to refresh the pygame display
- clock.tick(60) - method used to set a frame rate of 60 frames per second
List of input parameters: :param num_planets: Int representing the number of planet bodies on the
entire screen, inner planets view + solar system viewParameters: - tail_length – Int representing the length of the tail to follow behind the orbiting planets
- clock – a local variable storing a copy of the pygame clock time
- screen – window created by pygame used to display application
- scr_width – An in that represents the width of the screen
- scr_height – An int that represents the height of the screen
List of internal variables: - input_text - string containing user-entered filepath for a new init
file- past_input - string used to store input_text between when it is reset and when it needs to be used to call a file
- textbox_active - Int that determines whether the input textbox is to be displayed, 0 if no, 1 if yes
- pause - An int that specifies whether or not the simulation runs, 0 means it’s running, 1 means it is paused
- view - An int that determines what view is displayed, 0 for overhead view, 1 for side view
- speed - An int that determines the speed of the simulation, 1x, 2x, 4x, etc
- click_now - An int that determines whether the mouse is being clicked , 0 means no click, 1 means click
- input_active - An int that determines whether the file input text box shows, 0, means no show, 1 means it will show
- nasa - String that activates pluto, Yes, means NASA is correct, and pluto is not a planet, No means NASA is incorrect and pluto is a planet
- input2_active - An int that displays the travel to a day textbox, 0 means no show, 1 means it shows
- textbox2_active - An int that determines whether the travel to textbox is showing, 0 means no, 1 means yes
- input2_text - String that determines what day will be traveled to after the travel to day is determined
- zoom - Int used to scaled the planets to fit on the screen
- zoom_factor - Int used to scale the zoom to give varying views of the solar system if changed
- zoom_i - Int used to scale the inner planets coordinates to fit on the screen
- num_planets - Number of total bodies being displayed on the screen, whole solar system view + inner planets view
- time_step - Int used to determine length of time between
- curr_time_step - Int that represents how many time steps have passed in the simulation
- start_string - String containing the default path for an init file
- simulation - An object encompassing an n-body simulation that predicts a single body dependent on the state of all other simulated bodies in the system.
- sunx - Int representing the x coordinate of the sun image
- suny - Int representing the y coordinate of the sun image
- sun_i_x - Int representing the x coordinate of the sun image for the inner planets view
- sun_i_y - Int representing the x coordinate of the sun image for the inner planets view
- sun_img - Object used to hold the image of the sun that is printed to the screen
- current_positions - Dictionary that contains the name and a list of x, y coordinates for each non-predicted planet
- current_positions - Dictionary that contains the name and list of x, y coordinates for the predicted planet(s)
- x1 - X coordinate relative to the printed sun image for Mercury
- xi1 - X coordinate relative to the printed sun image for Mercury for the inner planets view
- y1 - Y coordinate relative to the printed sun image for Mercury
- yi1 - Y coordinate relative to the printed sun image for Mercury for the inner planets view
- x2 - X coordinate relative to the printed sun image for Venus
- xi2 - X coordinate relative to the printed sun image for Venus for the inner planets view
- y2 - Y coordinate relative to the printed sun image for Venus
- yi2 - Y coordinate relative to the printed sun image for Venus for the inner planets view
- x3 - X coordinate relative to the printed sun image for Earth
- xi3 - X coordinate relative to the printed sun image for Earth for the inner planets view
- y3 - Y coordinate relative to the printed sun image for Earth
- yi3 - Y coordinate relative to the printed sun image for Earth for the inner planets view
- x4 - X coordinate relative to the printed sun image for Mars
- xi4 - X coordinate relative to the printed sun image for Mars for the inner planets view
- y4 - Y coordinate relative to the printed sun image for Mars
- yi4 - X coordinate relative to the printed sun image for Mars for the inner planets view
- x5 - X coordinate relative to the printed sun image for Jupiter
- y5 - Y coordinate relative to the printed sun image for Jupiter
- x6 - X coordinate relative to the printed sun image for Saturn
- y6 - Y coordinate relative to the printed sun image for Saturn
- x7 - X coordinate relative to the printed sun image for Uranus
- y7 - Y coordinate relative to the printed sun image for Uranus
- x8 - X coordinate relative to the printed sun image for Pluto
- y8 - Y coordinate relative to the printed sun image for Pluto
- x9 - X coordinate relative to the printed sun image for Neptune
- y9 - Y coordinate relative to the printed sun image for Neptune
- x_track[] - List that contains the x coordinates for the planets to print the trails
- y_track[] - List that contains the y coordinates fot the planets to print the trails
-
neural_body.grav2.print_key(screen)¶ Method to display a planet key Method that displays a key of planet colors and names when selected in order to aid in user planet idenntification List of input parameters: :param screen: window created by pygame used to display application
-
neural_body.grav2.sun(screen, x, y)¶ Function to place the sun image on the screen A simple function for loading the sun image and placing it on the screen at a given coordinate. The size is static List of input parameters: :param screen: window created by pygame used to display application :param x: the integer x-coordinate pixel value where the sun should be
placedParameters: y – the integer y-coordinate pixel value where the sun should be placed
-
neural_body.grav2.text_handler(screen, text, scr_x, scr_y, size, color)¶ Function to place text on the screen at a desired location Function to place custom text on the screen at any desired location. The color of the text is currently restricted to shades of grey and white to match the visual theme we are pursuing. List of input parameters: :param screen: the usable area for drawing within the application
windowParameters: - text – string of text to be displayed on the screen. One line only.
- scr_x – the x coordinate for the text to be located at. Must be an integer
- scr_y – the y coordinate for the text to be located at. Must be an integer
- size – the size of the text to be displayed, in pixels (height). Must be an integer
- color – grey shade of the output. Must be an integer between 0 and 255.