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

Multi switch #391

Merged
merged 34 commits into from
Nov 30, 2019
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1dd623e
Added tests for ControllerManager update
jordan-palacios Apr 11, 2019
755503f
Mocks for controllers and controller loader in update test
jordan-palacios Apr 11, 2019
8bb8151
Divided in tests with and without controllers
jordan-palacios Apr 11, 2019
f04a964
Controller state initialized in mock
jordan-palacios Apr 12, 2019
0efb52b
Moved mocks to test class
jordan-palacios Apr 12, 2019
c3483ba
All tests using mock class
jordan-palacios Apr 12, 2019
48d2cc1
Test for multiple updates in a single controller
jordan-palacios Apr 12, 2019
f1d1e47
Added new switchResult() function to RobotHW interface
jordan-palacios Apr 12, 2019
506347e
Using ranged based loops
jordan-palacios Apr 15, 2019
c3c487e
Switch is now managed in a separate function
jordan-palacios Apr 15, 2019
86be606
Option to start controllers as soon as their joints are ready after a…
jordan-palacios Apr 15, 2019
f17e332
Tests for controller_interface API
jordan-palacios Apr 23, 2019
a43e18a
Added new STOPPED, WAITING and ABORTED states to ControllerBase
jordan-palacios Apr 24, 2019
d07d925
Split manageSwitch() into smaller functions
jordan-palacios Apr 24, 2019
efd7f2b
Abort pending controllers in case of switch error
jordan-palacios Apr 29, 2019
3901941
Changed default behaviour of new switch param
jordan-palacios May 2, 2019
1b54a1e
Added timeout parameter to switch controller
jordan-palacios May 2, 2019
94430c3
Removed unnecessary includes
jordan-palacios May 6, 2019
79d72ef
Fixed lincenses
jordan-palacios May 6, 2019
f7ed36e
Cosmetics
jordan-palacios May 6, 2019
8ce44db
Using target_include_directories for the test
jordan-palacios May 6, 2019
7b0e99c
std::all_of instead of std::count_if
jordan-palacios May 6, 2019
8123bc2
Deleted autogenerated file
jordan-palacios May 6, 2019
16b5095
Adapted tests to changes in controller_manager
jordan-palacios May 6, 2019
26f089e
Adapted python implementation to new parameters in SwitchController
jordan-palacios May 6, 2019
1254df4
Added missing parameter description docstring
jordan-palacios May 6, 2019
d8628cf
Moved all parameters used for switching to a separate object
jordan-palacios May 6, 2019
e523b6d
Moved error messages to controller_base
jordan-palacios May 6, 2019
919c4a1
State check functions are now const
jordan-palacios May 6, 2019
f13273c
Removed unnecessary comments
jordan-palacios May 6, 2019
5d7e6dd
Added constants for start_asap and timeout default parameters values
jordan-palacios May 6, 2019
677833a
Adding Pal Robotics to copyright notice
jordan-palacios Nov 26, 2019
3c63e29
Adding Pal Robotics to copyright notice
jordan-palacios Nov 26, 2019
db84881
Remove extra {
bmagyar Nov 30, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion combined_robot_hw_tests/test/cm_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ TEST(CMTests, listControllers)
EXPECT_EQ(state1.claimed_resources[0].resources[1], "hiDOF_joint2");

EXPECT_EQ(state2.name, "vel_eff_controller");
EXPECT_EQ(state2.state, "stopped");
EXPECT_EQ(state2.state, "initialized");
EXPECT_EQ(state2.type, "controller_manager_tests/VelEffController");
EXPECT_EQ(state2.claimed_resources.size(), 2);
EXPECT_EQ(state2.claimed_resources[0].hardware_interface, "hardware_interface::VelocityJointInterface");
Expand Down
17 changes: 17 additions & 0 deletions controller_interface/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ catkin_package(
INCLUDE_DIRS include
)

if(CATKIN_ENABLE_TESTING)

find_package(rosunit REQUIRED)

catkin_add_gmock(controller_base_test
test/controller_base_test.cpp
)

target_include_directories(controller_base_test PRIVATE include)
target_include_directories(controller_base_test SYSTEM PRIVATE ${catkin_INCLUDE_DIRS})

target_link_libraries(controller_base_test
${catkin_LIBRARIES}
)

endif()

# Install
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION})
Expand Down
114 changes: 102 additions & 12 deletions controller_interface/include/controller_interface/controller_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class ControllerBase
*
* \param time The current time
*/
virtual void starting(const ros::Time& /*time*/) {};
virtual void starting(const ros::Time& /*time*/) {}

/** \brief This is called periodically by the realtime thread when the controller is running
*
Expand All @@ -74,47 +74,137 @@ class ControllerBase
*
* \param time The current time
*/
virtual void stopping(const ros::Time& /*time*/) {};
virtual void stopping(const ros::Time& /*time*/) {}

/** \brief This is called from within the realtime thread while the controller is
* waiting to start
*
* \param time The current time
*/
virtual void waiting(const ros::Time& /*time*/) {}

/** \brief This is called from within the realtime thread when the controller needs
* to be aborted
*
* \param time The current time
*/
virtual void aborting(const ros::Time& /*time*/) {}

/** \brief Check if the controller is initialized
* \returns true if the controller is initialized
*/
bool isInitialized() const
{
return state_ == INITIALIZED;
}

/** \brief Check if the controller is running
* \returns true if the controller is running
*/
bool isRunning()
bool isRunning() const
{
return state_ == RUNNING;
}

/** \brief Check if the controller is stopped
* \returns true if the controller is stopped
*/
bool isStopped() const
{
return (state_ == RUNNING);
return state_ == STOPPED;
}

/** \brief Check if the controller is waiting
* \returns true if the controller is waiting
*/
bool isWaiting() const
{
return state_ == WAITING;
}

/** \brief Check if the controller is aborted
* \returns true if the controller is aborted
*/
bool isAborted() const
{
return state_ == ABORTED;
}

/// Calls \ref update only if this controller is running.
void updateRequest(const ros::Time& time, const ros::Duration& period)
{
if (state_ == RUNNING)
{
update(time, period);
}
}

/// Calls \ref starting only if this controller is initialized or already running
/// Calls \ref starting unless this controller is just constructed
bool startRequest(const ros::Time& time)
{
// start succeeds even if the controller was already started
if (state_ == RUNNING || state_ == INITIALIZED){
// start works from any state, except CONSTRUCTED
if (state_ != CONSTRUCTED)
{
starting(time);
state_ = RUNNING;
return true;
}
else
{
ROS_FATAL("Failed to start controller. It is not initialized.");
return false;
}
}

/// Calls \ref stopping only if this controller is initialized or already running
/// Calls \ref stopping unless this controller is just constructed
bool stopRequest(const ros::Time& time)
{
// stop succeeds even if the controller was already stopped
if (state_ == RUNNING || state_ == INITIALIZED){
// stop works from any state, except CONSTRUCTED
if (state_ != CONSTRUCTED)
{
stopping(time);
state_ = INITIALIZED;
state_ = STOPPED;
return true;
}
else
{
ROS_FATAL("Failed to stop controller. It is not initialized.");
return false;
}
}

/// Calls \ref waiting unless this controller is just constructed
bool waitRequest(const ros::Time& time)
{
// wait works from any state, except CONSTRUCTED
if (state_ != CONSTRUCTED)
{
waiting(time);
state_ = WAITING;
return true;
}
else
{
ROS_FATAL("Failed to wait controller. It is not initialized.");
return false;
}
}

/// Calls \ref abort unless this controller is just constructed
bool abortRequest(const ros::Time& time)
{
// abort works from any state, except CONSTRUCTED
if (state_ != CONSTRUCTED)
{
aborting(time);
state_ = ABORTED;
return true;
}
else
{
ROS_FATAL("Failed to abort controller. It is not initialized.");
return false;
}
}

/*\}*/
Expand Down Expand Up @@ -148,7 +238,7 @@ class ControllerBase
/*\}*/

/// The current execution state of the controller
enum {CONSTRUCTED, INITIALIZED, RUNNING} state_;
enum {CONSTRUCTED, INITIALIZED, RUNNING, STOPPED, WAITING, ABORTED} state_;


private:
Expand Down
2 changes: 2 additions & 0 deletions controller_interface/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@
<depend>hardware_interface</depend>
<depend>pluginlib</depend>
<depend>roscpp</depend>

<test_depend>rosunit</test_depend>
</package>
Loading