Skip to content
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

Closed
wants to merge 2 commits into from

Conversation

isorrentino
Copy link
Collaborator

@isorrentino isorrentino commented Mar 2, 2023

This PR implements some state dynamics which can be used to build a process model for a UKF.

@isorrentino isorrentino self-assigned this Mar 2, 2023
@isorrentino isorrentino marked this pull request as draft March 2, 2023 11:54
@isorrentino isorrentino force-pushed the feature/StateDynamics branch 4 times, most recently from af4b6f5 to 66d8547 Compare March 2, 2023 13:54
@isorrentino isorrentino marked this pull request as ready for review March 2, 2023 15:29
@GiulioRomualdi
Copy link
Member

GiulioRomualdi commented Mar 2, 2023

Can you rebase the PR on top of master and remove all the commits already merged in past PR?

@isorrentino isorrentino force-pushed the feature/StateDynamics branch 2 times, most recently from 2536f32 to 1aae054 Compare March 2, 2023 18:58
@isorrentino
Copy link
Collaborator Author

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 StateDynamics class name into Dynamics and apply all the needed modifications. I'll ping you as soon as the modifications are pushed and the PR is again ready to be reviewed.

@isorrentino isorrentino marked this pull request as draft March 3, 2023 11:09
@isorrentino isorrentino force-pushed the feature/StateDynamics branch from 1aae054 to e721bea Compare March 3, 2023 11:28
@isorrentino
Copy link
Collaborator Author

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 StateDynamics class name into Dynamics and apply all the needed modifications. I'll ping you as soon as the modifications are pushed and the PR is again ready to be reviewed.

Changes took less than expected. Changing back to ready.

@isorrentino isorrentino marked this pull request as ready for review March 3, 2023 11:29
@isorrentino isorrentino force-pushed the feature/StateDynamics branch 2 times, most recently from 5cb64d0 to 442173a Compare March 3, 2023 11:33
@isorrentino
Copy link
Collaborator Author

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.

@isorrentino isorrentino force-pushed the feature/StateDynamics branch from c63afdd to 084fe1a Compare March 16, 2023 13:18
@isorrentino
Copy link
Collaborator Author

isorrentino commented Mar 16, 2023

Sounds good @isorrentino, when you are ready you can re-request the review

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.

@isorrentino isorrentino force-pushed the feature/StateDynamics branch from 7588848 to 7fb5dc5 Compare March 22, 2023 17:38
@isorrentino isorrentino force-pushed the feature/StateDynamics branch 7 times, most recently from e86444e to adbca58 Compare March 24, 2023 12:26
@isorrentino
Copy link
Collaborator Author

Hi @S-Dafarra and @GiulioRomualdi, this PR can be reviewed again. Thank you.

@GiulioRomualdi GiulioRomualdi force-pushed the feature/StateDynamics branch from adbca58 to 625d04e Compare March 29, 2023 08:28
@GiulioRomualdi
Copy link
Member

I rebased the PR on master. Now the CI should run smoothly

@isorrentino isorrentino force-pushed the feature/StateDynamics branch from 625d04e to a193884 Compare March 29, 2023 10:27
@isorrentino
Copy link
Collaborator Author

Friendly ping @S-Dafarra @GiulioRomualdi :)

Copy link
Member

@S-Dafarra S-Dafarra left a 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() \
{ \
Copy link
Member

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) \
Copy link
Member

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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @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.

Comment on lines +57 to +60
/**
* UkfInputProvider describes the provider for the inputs of the ukf
*/
class UkfInputProvider : public System::Advanceable<UKFInput, UKFInput>
Copy link
Member

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.

Comment on lines +98 to +108
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;
Copy link
Member

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.

Comment on lines +135 to +137
* Set the SubModelKinDynWrapper object.
* @param kinDynWrapper pointer to a SubModelKinDynWrapper object.
* @return True in case of success, false otherwise.
Copy link
Member

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

Comment on lines +97 to +102
/**
* 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;
Copy link
Member

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))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this used anywhere?

Copy link
Member

@S-Dafarra S-Dafarra left a 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 😊

Comment on lines +62 to +65
* Set the SubModelKinDynWrapper object.
* @param kinDynWrapper pointer to a SubModelKinDynWrapper object.
* @return True in case of success, false otherwise.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for the others

Comment on lines +131 to +135
if (!ptr->getParameter("dynamic_model", m_dynamicModel))
{
log()->error("{} Error while retrieving the dynamic_model variable.", errorPrefix);
return false;
}
Copy link
Member

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
Copy link
Member

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

Comment on lines +72 to +77
/**
* 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;
Copy link
Member

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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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)
Copy link
Member

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @brief propagate implements the predict of the ukf
* @brief propagate implements the prediction phase of the ukf

src/Estimators/src/UkfState.cpp Show resolved Hide resolved
Comment on lines +184 to +192
REQUIRE(inputProvider->setInput(input));

stateModel->propagate(currentState, updatedState);

for (int idx = 0; idx < updatedState.size(); idx++)
{
REQUIRE(std::abs(updatedState[idx]) < 200);
}
}
Copy link
Member

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)

@isorrentino
Copy link
Collaborator Author

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?

@S-Dafarra
Copy link
Member

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) 😊

@isorrentino
Copy link
Collaborator Author

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

@isorrentino
Copy link
Collaborator Author

As mentioned in #615 (comment), I'm going to close this PR without merging it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants