-
Notifications
You must be signed in to change notification settings - Fork 38
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
Add dynamic models composing the UKF process model #615
Conversation
af4b6f5
to
66d8547
Compare
Can you rebase the PR on top of master and remove all the commits already merged in past PR? |
2536f32
to
1aae054
Compare
Hi @GiulioRomualdi @S-Dafarra I noticed that the measurement and state dynamics classes are exactly the same. I put the PR in draft in order to change the |
1aae054
to
e721bea
Compare
Changes took less than expected. Changing back to ready. |
5cb64d0
to
442173a
Compare
src/Estimators/include/BipedalLocomotion/RobotDynamicsEstimator/Dynamics.h
Outdated
Show resolved
Hide resolved
src/Estimators/include/BipedalLocomotion/RobotDynamicsEstimator/SubModel.h
Outdated
Show resolved
Hide resolved
src/Estimators/include/BipedalLocomotion/RobotDynamicsEstimator/JointVelocityDynamics.h
Outdated
Show resolved
Hide resolved
src/Estimators/include/BipedalLocomotion/RobotDynamicsEstimator/Dynamics.h
Outdated
Show resolved
Hide resolved
src/Estimators/tests/RobotDynamicsEstimator/UKFModelCreatorTest.cpp
Outdated
Show resolved
Hide resolved
src/Estimators/tests/RobotDynamicsEstimator/FrictionTorqueDynamicsTest.cpp
Outdated
Show resolved
Hide resolved
src/Estimators/tests/RobotDynamicsEstimator/JointVelocityDynamicsTest.cpp
Outdated
Show resolved
Hide resolved
src/Estimators/tests/RobotDynamicsEstimator/ZeroVelocityDynamicsTest.cpp
Outdated
Show resolved
Hide resolved
a547ac4
to
89c4b8a
Compare
89c4b8a
to
8381122
Compare
Hi @GiulioRomualdi and @S-Dafarra, I modified most of the code because using it I noticed that some things were missing or were uncomfortable to use. I also added some missing tests. I'm going to apply the reviews made by Stefano, but you will probably have to do the review again. |
c63afdd
to
084fe1a
Compare
I requested the review again but I found a problem and I'm trying to fix it. Let's wait for the review. Thanks. Maybe I can put the PR in draft until I solve the issue. |
7588848
to
7fb5dc5
Compare
e86444e
to
adbca58
Compare
Hi @S-Dafarra and @GiulioRomualdi, this PR can be reviewed again. Thank you. |
adbca58
to
625d04e
Compare
I rebased the PR on master. Now the CI should run smoothly |
…ss model, the ukfstate model class.
625d04e
to
a193884
Compare
Friendly ping @S-Dafarra @GiulioRomualdi :) |
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.
Some preliminary comments. I haven't gone through all the files yet
*/ | ||
#define BLF_REGISTER_DYNAMICS(_model, _baseModel) \ | ||
static std::shared_ptr<_baseModel> _model##FactoryBuilder() \ | ||
{ \ |
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.
Indentation problem
* @param _model the model of the dynamics | ||
* @param _baseModel the base model from which the _model inherits. | ||
*/ | ||
#define BLF_REGISTER_DYNAMICS(_model, _baseModel) \ |
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.
The term "dynamics" is quite abused and omnipresent. While it is safe to have a class named Dynamics
in a specific namespace, this macro has to be in the root namespace. I would suggest using a more specific name, maybe adding an ESTIMATOR
keyword
{ | ||
|
||
/** | ||
* @brief The UKFInput struct represents the input of the ukf needed to update the dynamics. |
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.
* @brief The UKFInput struct represents the input of the ukf needed to update the dynamics. | |
* @brief The UKFInput struct represents the input of the ukf needed to update the robot dynamics. |
/** | ||
* UkfInputProvider describes the provider for the inputs of the ukf | ||
*/ | ||
class UkfInputProvider : public System::Advanceable<UKFInput, UKFInput> |
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 would suggest adding more details on what this class is needed for. From the documentation only I was not able to understand it.
int m_size; /**< Size of the variable associate to the Dynamics object. */ | ||
Eigen::VectorXd m_updatedVariable; /**< Updated variable computed using the dynamic model. */ | ||
std::string m_description{"Generic Dynamics Element"}; /**< String describing the type of the dynamics */ | ||
std::string m_name; /**< Name of dynamics. */ | ||
Eigen::VectorXd m_covariances; /**< Vector of covariances. */ | ||
std::vector<std::string> m_elements = {}; /**< Elements composing the variable vector. */ | ||
std::string m_dynamicModel; | ||
bool m_isInitialized{false}; /**< True if the dynamics has been initialized. */ | ||
System::VariablesHandler m_stateVariableHandler; /**< Variable handler describing the variables and the sizes in the ukf state/measurement vector. */ | ||
bool m_isStateVariableHandlerSet{false}; /**< True if setVariableHandler is called. */ | ||
UKFInput m_ukfInput; |
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.
Looking at the header only, I find a little suspicious to have all these as protected members. Is it ok for the derived classes to access all these data. I would suggest eventually to keep the data as private as possible, and use protected setters and getters to structure the access to this data.
Then, looking at the implementation, I noticed that almost none of this data is used in the base class. I would suggest leaving the handling of the private attributes directly to the derived class, rather than forcing all the derived classes using some specific variables.
* Set the SubModelKinDynWrapper object. | ||
* @param kinDynWrapper pointer to a SubModelKinDynWrapper object. | ||
* @return True in case of success, false otherwise. |
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.
Missing documentation for the second input
/** | ||
* Set the SubModelKinDynWrapper object. | ||
* @param kinDynWrapper pointer to a SubModelKinDynWrapper object. | ||
* @return True in case of success, false otherwise. | ||
*/ | ||
bool setSubModels(const std::vector<SubModel>& subModelList, const std::vector<std::shared_ptr<SubModelKinDynWrapper>>& kinDynWrapperList) override; |
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.
Same as above, missing doc for the second entry
} | ||
|
||
// Set the dynamic model type | ||
if (!ptr->getParameter("dynamic_model", m_dynamicModel)) |
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.
Is this used anywhere?
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 should have checked all the files now 😊
* Set the SubModelKinDynWrapper object. | ||
* @param kinDynWrapper pointer to a SubModelKinDynWrapper object. | ||
* @return True in case of success, false otherwise. | ||
*/ |
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.
As for the others
if (!ptr->getParameter("dynamic_model", m_dynamicModel)) | ||
{ | ||
log()->error("{} Error while retrieving the dynamic_model variable.", errorPrefix); | ||
return false; | ||
} |
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.
As above
namespace RobotDynamicsEstimator | ||
{ | ||
|
||
struct SubModelDynamics |
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 would suggest converting this to a class with the proper setters/getters
/** | ||
* Set the SubModelKinDynWrapper object. | ||
* @param kinDynWrapper pointer to a SubModelKinDynWrapper object. | ||
* @return True in case of success, false otherwise. | ||
*/ | ||
bool setSubModels(const std::vector<SubModel>& subModelList, const std::vector<std::shared_ptr<SubModelKinDynWrapper>>& kinDynWrapperList) override; |
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.
As above
return true; | ||
} | ||
|
||
bool RDE::ZeroVelocityDynamics::setSubModels(const std::vector<RDE::SubModel>& subModelList, const std::vector<std::shared_ptr<RDE::SubModelKinDynWrapper>>& kinDynWrapperList) |
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.
bool RDE::ZeroVelocityDynamics::setSubModels(const std::vector<RDE::SubModel>& subModelList, const std::vector<std::shared_ptr<RDE::SubModelKinDynWrapper>>& kinDynWrapperList) | |
bool RDE::ZeroVelocityDynamics::setSubModels(const std::vector<RDE::SubModel>& /*subModelList*/, const std::vector<std::shared_ptr<RDE::SubModelKinDynWrapper>>& /*kinDynWrapperList*/) |
When a parameter is not used, the compiler might generate warnings. In these cases it is sufficient to comment the name, thus indicating to the compiler you are not going to use them.
} | ||
} | ||
|
||
void RDE::ZeroVelocityDynamics::setInput(const UKFInput& ukfInput) |
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 here, you could comment out the name of the parameter not used.
System::VariablesHandler getStateVariableHandler(); | ||
|
||
/** | ||
* @brief propagate implements the predict of the ukf |
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.
* @brief propagate implements the predict of the ukf | |
* @brief propagate implements the prediction phase of the ukf |
REQUIRE(inputProvider->setInput(input)); | ||
|
||
stateModel->propagate(currentState, updatedState); | ||
|
||
for (int idx = 0; idx < updatedState.size(); idx++) | ||
{ | ||
REQUIRE(std::abs(updatedState[idx]) < 200); | ||
} | ||
} |
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 would also suggest defining a test case where you expect some specific output, and check that you converge there. You could generate in some way some simple synthetic data (i.e. a set of constant joint torques), and check that the estimator converges to the quantities you used to generate the data (i.e. you check that you are able to reconstruct the initial set of joint torques)
Hi @GiulioRomualdi @S-Dafarra, I'm finally back to this PR. I know that @S-Dafarra has already spent time on the review, but I thought it might make more sense to close the 4 PRs containing the code of the estimator (#615, #640, #646, #649) and open many much smaller ones to simplify and speed up the review process. Consider also that the code of the last PR (#649) changes also many parts of the code contained in the previous three PRs. What do you think? |
Clearly, smaller PRs are much easier to review, but anyway there is always a tradeoff with the development time. Up to you! I did not check the other PRs yet. If you close this, I would just ask you to consider my previous comments in the new PRs before asking me to review them (only if they still apply) 😊 |
Of course, I would have not ignored your comments :) Actually, since the second PR is very similar to this one, they will apply also to that one :D |
As mentioned in #615 (comment), I'm going to close this PR without merging it. |
This PR implements some state dynamics which can be used to build a process model for a UKF.