-
-
Notifications
You must be signed in to change notification settings - Fork 144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH: Alternative for State History #507
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work, Stano. Overall you reduced the total number of code line, that's always a good improvement.
I wonder why the tests are not passing... Could you take a look please?
and modified by the controller function. | ||
interactable_objects : list | ||
A collection of objects that the controller function can access and | ||
potentially modify. This list is flexible and can include any Python |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"This list is flexible and can include any Python object"
this sentence let me a bit lost here. What would be examples of "any Python object"? What do you mean by that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the user can pass any type of object in this list. If they want to use an object of a class that they defined they can.
Since these are passed directly to the controller_function, and the controller_function is completely defined by the user, he can pass whatever he wants in here.
I will try to improve the docs a bit here
5. A list containing the objects to be acted upon by the controller. | ||
The objects in this list are the same as the objects in the | ||
observed_objects list, but they can be modified by the controller. | ||
4. `state_history` (list): A record of the rocket's state at each |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the state_history
works like the same as the Flight.solution
attribute, right?
I wonder if each state could/should be an instance of a class, so we would be saving a list of objects of such class, instead of saving a list of lists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is an interesting idea. Maybe being a named tuple would be more fitting
It is something to consider whenever we work on some refactoring in the Flight class
controller_function=controller_function, | ||
sampling_rate=sampling_rate, | ||
initial_observed_variables=initial_observed_variables, | ||
name=controller_name, | ||
) | ||
self.air_brakes.append(air_brakes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't we have a self.add_air_brakes(air_brakes) method? These two rows (1263 and 1264) does the same thing but in two different ways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think I understood what you were saying here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you have used these two code lines:
self.air_brakes.append(air_brakes)
and
self.add_controllers(controller)
My question is: why do you append airbakes but you add controllers? Shouldn't they follow the same architecture? The code could be more intuitive
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add_controllers
is a separate method that can be used by itself to add any type of controller to the rocket
the add_air_brakes
is specific for adding air_brakes. It also adds the controller because it just makes sense for air brakes to be added together with their controller
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add_controllers
is a separate method that can be used by itself to add any type of controller to the rocketthe
add_air_brakes
is specific for adding air_brakes. It also adds the controller because it just makes sense for air brakes to be added together with their controller
Now I'm the one who thinks you didn't understand...
The point is that in your code you didn't use add_air_brakes
at all, instead you are mutating a list using the self.airbrakes.append()
.
Imagine when we are on the Rocket class, we don't do this: calisto.aero_surfaces.append(...)
.
Instead, we do calisto.add_surface(...)
.
This is important because there are some function calls inside the add_surface method that make the first approach not valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add_air_brakes
creates the air brakes and their related controller
and saves them in their appropriate lists.
Air brakes do not generate any lift, so there is no reason for it to be included in aerodynamic_surfaces
or make any center of pressure-related calculations. So it does not call add_surface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, air brakes have no position, so it only needs to be saved in a normal list. No need to create a Component
object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR offers much improved flexibility for controlling different rocket components, well done. I will approve it after some comments I have raised are considered.
Every implementation has advantages and disadvantages, the main comments I made concern these:
Advantages:
- Greater flexibility and scalability, does not require history parameters in the controlled objects;
- Support for much deeper/complex control.
Disadvantages:
- There are no automatically generated plots for control results;
- (Perhaps) A bit harder to use/understand when creating a controller from scratch.
Co-authored-by: Pedro Henrique Marinho Bressan <87212571+phmbressan@users.noreply.github.com>
To sum up, I think we can always add the air brakes plots somehow later. It would have to be something similar to the old implementation (which is not ideal) but without making it necessary for any object that can be controlled to have it as well. Also, with a good documentation (specially in a usage .rst docs page) the user should not have a problem handling the data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your replies @MateusStano this solves the comments I had about this PR. Good job!
@MateusStano, can we merge this PR and then I'll do a final review of #426 directly? |
Pull request type
Checklist
black rocketpy/ tests/
) has passed locallypytest --runslow
) have passed locallyCHANGELOG.md
has been updated (if relevant)Current behavior
The
AirBrakes
implementation had some questionable handling of thestate
attributes. They made theController
Class work only with air brakes, and their implementation was not scalable to the other classesNew behavior
All air brakes'
state
related attributes and functions were deleted.Now, logging of changes is handled inside the
Controller
class:Controller
class now has an attributeobserved_variables
, which is a list passed as an argument for thecontroller_function
observed_variables
is initialized with theinitial_observed_variables
in the class' constructorobserved_variables
gets appended to with whatever thecontroller_function
returns.These changes make it so no information of the simulation is stored in the Air Brakes class. If the user wanted to see the change of deployed level through time, he would have to return time and the deployed level inside the
controller_function
and then make the plot himself.This makes the
Controller
class much more flexible in terms of usability.Additional information
I have not updated the docs page yet, but there is an updated example in the notebook
This current implementation makes me question the need for the
state_history
argument of thecontroller_function
, since the user could just keep what it needs in theobserved_variables
Need opinions on this @giovaniceotto @phmbressan