-
Notifications
You must be signed in to change notification settings - Fork 466
Add unit testing to robot hardware #109
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
Changes from 12 commits
4f0e844
bfb3b20
14771a0
c96b257
5f78e12
5c47656
b09755d
fdb6354
ca06e6b
13c6a53
4614ce8
32fc92e
c561815
7e4aa2a
30476af
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 |
|---|---|---|
|
|
@@ -55,6 +55,9 @@ class JointCommandHandle | |
| void | ||
| set_cmd(double cmd); | ||
|
|
||
| HARDWARE_INTERFACE_PUBLIC | ||
| bool valid_pointers() const; | ||
|
Contributor
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. that function name should be more precise.
Contributor
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. also, the function states
Member
Author
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. I have the same function implemented in all the other handles and I call this from the template function so they should all be called the same. TBH a proper solution would see inheriting such an interface to really ensure this function existing the same way for all |
||
|
|
||
| private: | ||
| std::string name_; | ||
| double * cmd_; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,202 @@ | ||
| // Copyright 2020 ros2_control development team | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| #include "gmock/gmock.h" | ||
|
|
||
| #include "hardware_interface/robot_hardware.hpp" | ||
| #include "hardware_interface/types/hardware_interface_return_values.hpp" | ||
|
|
||
| namespace hw = hardware_interface; | ||
| using testing::SizeIs; | ||
| using testing::Each; | ||
| using testing::NotNull; | ||
| using testing::UnorderedElementsAre; | ||
| using testing::ElementsAre; | ||
|
|
||
| namespace | ||
| { | ||
| class MyTestRobotHardware : public hw::RobotHardware | ||
| { | ||
| public: | ||
| hw::hardware_interface_ret_t init() override | ||
| { | ||
| return hw::HW_RET_OK; | ||
| } | ||
|
|
||
| hw::hardware_interface_ret_t read() override | ||
| { | ||
| return hw::HW_RET_OK; | ||
| } | ||
|
|
||
| hw::hardware_interface_ret_t write() override | ||
| { | ||
| return hw::HW_RET_OK; | ||
| } | ||
| }; | ||
|
|
||
| constexpr auto JOINT_NAME = "joint_1"; | ||
| constexpr auto NEW_JOINT_NAME = "joint_2"; | ||
| } // namespace | ||
|
|
||
| class TestRobotHardwareInterface : public testing::Test | ||
| { | ||
| protected: | ||
| void SetUp() | ||
| { | ||
| robot_.init(); | ||
| } | ||
|
|
||
| void SetUpHandles() | ||
| { | ||
| robot_.register_joint_command_handle(&pos_command_handle_); | ||
| robot_.register_joint_state_handle(&state_handle_); | ||
| robot_.register_operation_mode_handle(&op_mode_handle_); | ||
| } | ||
|
|
||
| void SetUpNewHandles() | ||
| { | ||
| robot_.register_joint_command_handle(&new_pos_command_handle_); | ||
| robot_.register_joint_state_handle(&new_state_handle_); | ||
| robot_.register_operation_mode_handle(&new_op_mode_handle_); | ||
| } | ||
|
|
||
| MyTestRobotHardware robot_; | ||
| double pos_command_value_ = 0.0; | ||
| hw::JointCommandHandle pos_command_handle_{JOINT_NAME, &pos_command_value_}; | ||
| double velocity_state_value_ = 0.0; | ||
| double effort_state_value_ = 0.0; | ||
| hw::JointStateHandle state_handle_{JOINT_NAME, &pos_command_value_, &velocity_state_value_, | ||
| &effort_state_value_}; | ||
| hw::OperationMode mode_ = hw::OperationMode::ACTIVE; | ||
| hw::OperationModeHandle op_mode_handle_{JOINT_NAME, &mode_}; | ||
|
|
||
| hw::JointCommandHandle new_pos_command_handle_{NEW_JOINT_NAME, &pos_command_value_}; | ||
| hw::JointStateHandle new_state_handle_{NEW_JOINT_NAME, &pos_command_value_, | ||
| &velocity_state_value_, | ||
| &effort_state_value_}; | ||
| hw::OperationModeHandle new_op_mode_handle_{NEW_JOINT_NAME, &mode_}; | ||
| }; | ||
|
|
||
| TEST_F(TestRobotHardwareInterface, can_not_register_broken_handles) | ||
| { | ||
| hw::JointCommandHandle broken_command_handle; | ||
| EXPECT_EQ(hw::HW_RET_ERROR, robot_.register_joint_command_handle(&broken_command_handle)); | ||
| hw::JointStateHandle broken_state_handle; | ||
| EXPECT_EQ(hw::HW_RET_ERROR, robot_.register_joint_state_handle(&broken_state_handle)); | ||
| hw::OperationModeHandle broken_op_mode_handle; | ||
| EXPECT_EQ(hw::HW_RET_ERROR, robot_.register_operation_mode_handle(&broken_op_mode_handle)); | ||
| } | ||
|
|
||
| TEST_F(TestRobotHardwareInterface, can_register_proper_handles) | ||
| { | ||
| EXPECT_EQ(hw::HW_RET_OK, robot_.register_joint_command_handle(&pos_command_handle_)); | ||
| EXPECT_EQ(hw::HW_RET_OK, robot_.register_joint_state_handle(&state_handle_)); | ||
| EXPECT_EQ(hw::HW_RET_OK, robot_.register_operation_mode_handle(&op_mode_handle_)); | ||
| } | ||
|
|
||
| TEST_F(TestRobotHardwareInterface, cannot_double_register_handles) | ||
| { | ||
| SetUpHandles(); | ||
|
|
||
| EXPECT_EQ(hw::HW_RET_ERROR, robot_.register_joint_command_handle(&pos_command_handle_)); | ||
| EXPECT_EQ(hw::HW_RET_ERROR, robot_.register_joint_state_handle(&state_handle_)); | ||
| EXPECT_EQ(hw::HW_RET_ERROR, robot_.register_operation_mode_handle(&op_mode_handle_)); | ||
| } | ||
|
|
||
| TEST_F(TestRobotHardwareInterface, can_get_registered_joint_names) | ||
| { | ||
| SetUpHandles(); | ||
| EXPECT_THAT(robot_.get_registered_joint_names(), ElementsAre(JOINT_NAME)); | ||
|
|
||
| SetUpNewHandles(); | ||
| EXPECT_THAT( | ||
| robot_.get_registered_joint_names(), | ||
| UnorderedElementsAre(JOINT_NAME, NEW_JOINT_NAME)); | ||
| } | ||
|
|
||
| TEST_F(TestRobotHardwareInterface, returned_joint_handles_are_not_null) | ||
| { | ||
| SetUpHandles(); | ||
| SetUpNewHandles(); | ||
|
|
||
| const auto state_handles = robot_.get_registered_joint_state_handles(); | ||
| EXPECT_THAT(state_handles, SizeIs(2)); | ||
| EXPECT_THAT(state_handles, Each(NotNull())); | ||
|
|
||
| const auto command_handles = robot_.get_registered_joint_command_handles(); | ||
| EXPECT_THAT(command_handles, SizeIs(2)); | ||
| EXPECT_THAT(command_handles, Each(NotNull())); | ||
|
|
||
| const auto op_mode_handles = robot_.get_registered_operation_mode_handles(); | ||
| EXPECT_THAT(op_mode_handles, SizeIs(2)); | ||
| EXPECT_THAT(op_mode_handles, Each(NotNull())); | ||
| } | ||
|
|
||
| TEST_F(TestRobotHardwareInterface, can_get_registered_state_handles) | ||
| { | ||
| SetUpHandles(); | ||
| EXPECT_THAT(robot_.get_registered_joint_state_handles(), SizeIs(1)); | ||
|
|
||
| SetUpNewHandles(); | ||
| EXPECT_THAT(robot_.get_registered_joint_state_handles(), SizeIs(2)); | ||
| } | ||
|
|
||
| TEST_F(TestRobotHardwareInterface, can_get_registered_command_handles) | ||
| { | ||
| SetUpHandles(); | ||
| EXPECT_THAT(robot_.get_registered_joint_command_handles(), SizeIs(1)); | ||
|
|
||
| SetUpNewHandles(); | ||
| EXPECT_THAT(robot_.get_registered_joint_command_handles(), SizeIs(2)); | ||
| } | ||
|
|
||
| TEST_F(TestRobotHardwareInterface, can_get_registered_op_mode_handles) | ||
| { | ||
| SetUpHandles(); | ||
| EXPECT_THAT(robot_.get_registered_operation_mode_handles(), SizeIs(1)); | ||
|
|
||
| SetUpNewHandles(); | ||
| EXPECT_THAT(robot_.get_registered_operation_mode_handles(), SizeIs(2)); | ||
| } | ||
|
|
||
| TEST_F(TestRobotHardwareInterface, can_get_handles_by_name) | ||
| { | ||
| SetUpHandles(); | ||
|
|
||
| const hw::JointStateHandle * state_handle = nullptr; | ||
| EXPECT_EQ(hw::HW_RET_OK, robot_.get_joint_state_handle(JOINT_NAME, &state_handle)); | ||
| state_handle = nullptr; | ||
| EXPECT_EQ(hw::HW_RET_ERROR, robot_.get_joint_state_handle(NEW_JOINT_NAME, &state_handle)); | ||
|
|
||
| hw::JointCommandHandle * cmd_handle = nullptr; | ||
| EXPECT_EQ(hw::HW_RET_OK, robot_.get_joint_command_handle(JOINT_NAME, &cmd_handle)); | ||
| cmd_handle = nullptr; | ||
| EXPECT_EQ(hw::HW_RET_ERROR, robot_.get_joint_command_handle(NEW_JOINT_NAME, &cmd_handle)); | ||
|
|
||
| hw::OperationModeHandle * op_mode_handle = nullptr; | ||
| EXPECT_EQ(hw::HW_RET_OK, robot_.get_operation_mode_handle(JOINT_NAME, &op_mode_handle)); | ||
| op_mode_handle = nullptr; | ||
| EXPECT_EQ(hw::HW_RET_ERROR, robot_.get_operation_mode_handle(NEW_JOINT_NAME, &op_mode_handle)); | ||
|
|
||
| SetUpNewHandles(); | ||
| state_handle = nullptr; | ||
| EXPECT_EQ(hw::HW_RET_OK, robot_.get_joint_state_handle(NEW_JOINT_NAME, &state_handle)); | ||
| cmd_handle = nullptr; | ||
| EXPECT_EQ(hw::HW_RET_OK, robot_.get_joint_command_handle(NEW_JOINT_NAME, &cmd_handle)); | ||
| op_mode_handle = nullptr; | ||
| EXPECT_EQ(hw::HW_RET_OK, robot_.get_operation_mode_handle(NEW_JOINT_NAME, &op_mode_handle)); | ||
| } | ||
|
bmagyar marked this conversation as resolved.
|
||
Uh oh!
There was an error while loading. Please reload this page.