-
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 ContactList and utilities for defining contact phases. #45
Changes from all commits
79ac4fc
ac15e3e
65508eb
d7f7d9c
302ab34
af8d3ef
b909bff
8cf6b97
ab4e9d7
546052a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
/** | ||
* @file ContactList.h | ||
* @authors Stefano Dafarra | ||
* @copyright 2020 Istituto Italiano di Tecnologia (IIT). This software may be modified and | ||
* distributed under the terms of the GNU Lesser General Public License v2.1 or any later version. | ||
*/ | ||
|
||
#ifndef BIPEDAL_LOCOMOTION_PLANNERS_CONTACTLIST_H | ||
#define BIPEDAL_LOCOMOTION_PLANNERS_CONTACTLIST_H | ||
|
||
// BipedalLocomotion | ||
#include <BipedalLocomotion/Planners/Contact.h> | ||
|
||
//iDynTree | ||
#include <iDynTree/Core/Transform.h> | ||
|
||
//std | ||
#include <set> | ||
#include <string> | ||
#include <functional> | ||
|
||
namespace BipedalLocomotion | ||
{ | ||
namespace Planners | ||
{ | ||
|
||
/** | ||
* @brief Class containing a list of contacts. | ||
* The contact are added such that the activation time is strictly growing. In addition, contacts cannot be overlapping. | ||
* It represents a series of contact activations and deactivations of a single entity. | ||
*/ | ||
class ContactList | ||
{ | ||
/** | ||
* @brief Struct used for inserting new contacts in the set. | ||
*/ | ||
struct ContactCompare { | ||
bool operator()(const Contact& lhs, const Contact& rhs) const; | ||
}; | ||
|
||
std::set<Contact, ContactCompare> m_contacts; /** Data structure for inserting and ordering contacts. **/ | ||
std::string m_defaultName{"ContactList"}; /** Default name for the contact list. **/ | ||
ContactType m_defaultContactType{ContactType::FULL}; /** Default contact type. **/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you need this? /**
* Type of contact.
*/
ContactType type {ContactType::FULL}; Is it only an utility required to avoid passing the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it is used here: https://github.com/S-Dafarra/bipedal-locomotion-framework/blob/ab4e9d7a5c4a101ca8630b96af1052bf8a3c95e5/src/Planners/include/BipedalLocomotion/Planners/ContactList.h#L92 In addition, the |
||
|
||
public: | ||
|
||
using const_iterator = std::set<Contact, ContactCompare>::const_iterator; | ||
using const_reverse_iterator = std::set<Contact, ContactCompare>::const_reverse_iterator; | ||
|
||
/** | ||
* @brief Set the default name. | ||
* @param defaultName the default name. | ||
*/ | ||
void setDefaultName(const std::string& defaultName); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only to have symmetry with the std::string& defaultName(); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I would avoid this to prevent stupid mistakes like if (list.defaultName() = "a") In addition, even if it is not the case now, in the future I may need to do some changes when this name or the contact type change. |
||
|
||
/** | ||
* @brief Get the default name. | ||
* @return the default name. | ||
*/ | ||
const std::string& defaultName() const; | ||
|
||
/** | ||
* @brief Set the default contact type. | ||
* @param The default contact type. | ||
*/ | ||
void setDefaultContactType(const ContactType& type); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The same of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above, I would avoid this. |
||
|
||
/** | ||
* @brief Get the default contact type. | ||
* @return the default contact type. | ||
*/ | ||
const ContactType& defaultContactType() const; | ||
|
||
/** | ||
* @brief Add a new contact to the list. | ||
* @param newContact The new contact | ||
* @return false if it was not possible to insert the contact. | ||
* Possible failures: the activation time is greater than the deactivation time, or the new contact ovelaps with an existing contact. | ||
*/ | ||
bool addContact(const Contact& newContact); | ||
|
||
/** | ||
* @brief Add a new contact to the list. | ||
* | ||
* It uses the defaultName and the defaultContactType for the missing informations. | ||
* @param newTransform The contact pose. | ||
* @param activationTime The activation time. | ||
* @param deactivationTime The deactivation time. | ||
* @return false if it was not possible to insert the contact. | ||
* Possible failures: the activation time is greater than the deactivation time, or the new contact ovelaps with an existing contact. | ||
*/ | ||
bool addContact(const iDynTree::Transform& newTransform, double activationTime, double deactivationTime); | ||
|
||
/** | ||
* @brief Erase a contact | ||
* @param iterator to the contact to erase. | ||
* @return an iterator to the contact that follows the one removed. | ||
*/ | ||
const_iterator erase(const_iterator iterator); | ||
|
||
/** | ||
* @brief Return a const iterator to the begin of the contacts. | ||
*/ | ||
const_iterator begin() const; | ||
|
||
/** | ||
* @brief Return a const iterator to the begin of the contacts. | ||
*/ | ||
const_iterator cbegin() const; | ||
|
||
/** | ||
* @brief Return a const reverse iterator to the contacts (basically starting from the last contact going backward). | ||
*/ | ||
const_reverse_iterator rbegin() const; | ||
|
||
/** | ||
* @brief Return a const reverse iterator to the contacts (basically starting from the last contact going backward). | ||
*/ | ||
const_reverse_iterator crbegin() const; | ||
|
||
/** | ||
* @brief Return a const iterator to the end of the list. | ||
* | ||
* This is only a placeholder, it does not reference any contact. | ||
*/ | ||
const_iterator end() const; | ||
|
||
/** | ||
* @brief Return a const iterator to the end of the list. | ||
* | ||
* This is only a placeholder, it does not reference any contact. | ||
*/ | ||
const_iterator cend() const; | ||
|
||
/** | ||
* @brief Return a const reverse iterator to the end of the list. | ||
* | ||
* This is only a placeholder, it does not reference any contact. | ||
*/ | ||
const_reverse_iterator rend() const; | ||
|
||
/** | ||
* @brief Return a const reverse iterator to the end of the list. | ||
* | ||
* This is only a placeholder, it does not reference any contact. | ||
*/ | ||
const_reverse_iterator crend() const; | ||
|
||
/** | ||
* @brief Access contacts by index. | ||
* @warning This method in a for loop is much less efficient than using iterators. | ||
* @param index of the phase to be accessed. | ||
* @return A const reference to the desired contact. | ||
*/ | ||
const Contact& operator[](size_t index) const; | ||
|
||
/** | ||
* @brief Get the size of the list. | ||
* @return The number of contacts. | ||
*/ | ||
size_t size() const; | ||
|
||
/** | ||
* @brief Iterator pointing to the first contact. | ||
*/ | ||
const_iterator firstContact() const; | ||
|
||
/** | ||
* @brief Iterator pointing to the last contact. | ||
*/ | ||
const_iterator lastContact() const; | ||
|
||
/** | ||
* @brief Edit an existing contact. | ||
* @param element Iterator to the element to edit. | ||
* @param newContact The new contact | ||
* @return false if the element is not valid or if the new contact timing would require a reordering of the list. | ||
*/ | ||
bool editContact(const_iterator element, const Contact& newContact); | ||
|
||
/** | ||
* @brief Get the contact given the time. | ||
* | ||
* It returns the contact with the highest activation time lower than time. | ||
* If no contacts have an activation time lower than time, it returns an iterator to the end. | ||
* Notice that the contact may not be active, i.e. the deactivationTime may be lower than time. | ||
* @param time The present time. | ||
* @return an iterator to the last contact having an activation time lower than time. | ||
* If no contact satisfy this condition, it returns a pointer to the end. | ||
*/ | ||
const_iterator getPresentContact(double time) const; | ||
|
||
/** | ||
* @brief Clear all the steps, except the one returned by getPresentContact | ||
* @param time The present time. | ||
* @return false if no contact is available at this time. | ||
*/ | ||
bool keepOnlyPresentContact(double time); | ||
|
||
/** | ||
* @brief Clear the contacts. | ||
*/ | ||
void clear(); | ||
|
||
/** | ||
* @brief Remove only the last contact. | ||
*/ | ||
void removeLastContact(); | ||
|
||
}; | ||
|
||
} //namespace Planners | ||
} //namespace BipedalLocomotion | ||
|
||
|
||
|
||
#endif // BIPEDAL_LOCOMOTION_PLANNERS_CONTACTLIST_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/** | ||
* @file ContactPhase.h | ||
* @authors Stefano Dafarra | ||
* @copyright 2020 Istituto Italiano di Tecnologia (IIT). This software may be modified and | ||
* distributed under the terms of the GNU Lesser General Public License v2.1 or any later version. | ||
*/ | ||
|
||
#ifndef BIPEDAL_LOCOMOTION_PLANNERS_CONTACT_PHASE_H | ||
#define BIPEDAL_LOCOMOTION_PLANNERS_CONTACT_PHASE_H | ||
|
||
#include <BipedalLocomotion/Planners/Contact.h> | ||
#include <BipedalLocomotion/Planners/ContactList.h> | ||
#include <unordered_map> | ||
#include <string> | ||
|
||
namespace BipedalLocomotion | ||
{ | ||
namespace Planners | ||
{ | ||
|
||
/** | ||
* @brief Struct defining a contact phase. | ||
* Each phase is characterized by a set of contacts which remain active for the entirety of the phase. | ||
*/ | ||
struct ContactPhase | ||
{ | ||
/** | ||
* @brief The phase initial time. | ||
**/ | ||
double beginTime {0.0}; | ||
|
||
/** | ||
* @brief The phase end time. | ||
**/ | ||
double endTime {0.0}; | ||
|
||
/** | ||
* @brief The set of contacts active during the phase. | ||
*/ | ||
std::unordered_map<std::string, ContactList::const_iterator> activeContacts; | ||
|
||
/** | ||
* @brief Utility function to check if a list is present amongst the active contacts. | ||
* @param key The label of the list to be checked. | ||
* @return True if key is present amongst the active contacts. | ||
**/ | ||
bool isListIncluded(const std::string& key) const; | ||
}; | ||
|
||
} | ||
} | ||
|
||
#endif // BIPEDAL_LOCOMOTION_PLANNERS_CONTACT_PHASE_H |
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.
Correct me if I'm mistaken. You are using an
std::set
because you are sure that theContact
key is unique.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.
Yes, indeed I make sure of that with
ContactCompare
. I basically needed a container to store all the contacts in a custom order. In addition, the insertion of a new contact fails if the new one is "intersecting" some contact already added. For example, see here for an attempt of invalid insertion.p3
is "intersecting"p2
.