Skip to content

Commit

Permalink
First version of new model command for ign-gazebo
Browse files Browse the repository at this point in the history
Signed-off-by: Marcos Wagner <[email protected]>
  • Loading branch information
WagnerMarcos committed Jun 29, 2021
1 parent dd9f7b5 commit df9eee1
Show file tree
Hide file tree
Showing 8 changed files with 885 additions and 1 deletion.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ set(IGNITION_GAZEBO_GUI_PLUGIN_INSTALL_DIR
#============================================================================
# Configure the build
#============================================================================
ign_configure_build(QUIT_IF_BUILD_ERRORS)
ign_configure_build(QUIT_IF_BUILD_ERRORS
COMPONENTS model
)

add_subdirectory(examples)

Expand Down
36 changes: 36 additions & 0 deletions model/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
ign_get_libsources_and_unittests(sources gtest_sources)
list(APPEND sources cmd/ModelCommandAPI.cc)

ign_add_component(model SOURCES ${sources} GET_TARGET_NAME model_lib_target)


if (MSVC)
# Warning #4251 is the "dll-interface" warning that tells you when types used
# by a class are not being exported. These generated source files have private
# members that don't get exported, so they trigger this warning. However, the
# warning is not important since those members do not need to be interfaced
# with.
set_source_files_properties(${sources} ${gtest_sources} COMPILE_FLAGS "/wd4251 /wd4146")
endif()

# Unit tests
ign_build_tests(
TYPE "UNIT"
SOURCES ${gtest_sources}
LIB_DEPS ${EXTRA_TEST_LIB_DEPS}
TEST_LIST model_tests
)

if(TARGET UNIT_ModelCommandAPI_TEST)

target_compile_definitions(UNIT_ModelCommandAPI_TEST PRIVATE
"IGN_PATH=\"${IGNITION-TOOLS_BINARY_DIRS}\"")

target_compile_definitions(UNIT_ModelCommandAPI_TEST PRIVATE
"PROJECT_SOURCE_PATH=\"${PROJECT_SOURCE_DIR}\"")

endif()

if(NOT WIN32)
add_subdirectory(cmd)
endif()
160 changes: 160 additions & 0 deletions model/src/ModelCommandAPI_TEST.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* 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 "cmd/ModelCommandAPI.hh"

#include <cstdio>
#include <cstdlib>
#include <string>

#include <gtest/gtest.h>

#include "ignition/gazebo/Server.hh"

static const std::string kIgnModelCommand(std::string(IGN_PATH) +
"/ign model ");

/////////////////////////////////////////////////
std::string customExecStr(std::string _cmd)
{
_cmd += " 2>&1";
FILE *pipe = popen(_cmd.c_str(), "r");

if (!pipe)
return "ERROR";

char buffer[128];
std::string result = "";

while (!feof(pipe))
{
if (fgets(buffer, 128, pipe) != nullptr)
{
result += buffer;
}
}

pclose(pipe);
return result;
}

// Test `ign model` command when no Gazebo server is running.
TEST(ModelCommandAPI, NoServerRunning)
{
const std::string cmd = kIgnModelCommand + "--list ";
const std::string output = customExecStr(cmd);
const std::string expectedOutput{
"\nService call to [/gazebo/worlds] timed out\n"};
EXPECT_EQ(expectedOutput, output);
}

// Tests `ign model` command.
TEST(ModelCommandAPI, Commands)
{
ignition::gazebo::ServerConfig serverConfig;
serverConfig.SetSdfFile(std::string(PROJECT_SOURCE_PATH) +
"/examples/worlds/shapes.sdf");

ignition::gazebo::Server server(serverConfig);
// Run at least one iteration before continuing to guarantee correctly set up.
ASSERT_TRUE(server.Run(true, 5, false));
// Run without blocking.
server.Run(false, 0, false);

// Tested command: ign model --list
{
const std::string cmd = kIgnModelCommand + "--list";
const std::string output = customExecStr(cmd);
const std::string expectedOutput =
"Available models:\n"
" - ground_plane\n"
" - box\n"
" - cylinder\n"
" - sphere\n";
EXPECT_EQ(expectedOutput, output);
}

// Tested command: ign model -m cylinder
{
const std::string cmd = kIgnModelCommand + "-m box";
const std::string output = customExecStr(cmd);
const std::string expectedOutput =

"\nRequesting state for world [shapes] on service [/world/shapes/state]...\n\n"
"Name: box\n"
" - Pose: \n"
" [0.000000 | -0.000000 | 0.500000]\n"
" [0.000000 | 0.000000 | 0.000000]\n\n"
" - Link [9]\n"
" - Name: box_link\n"
" - Parent: box [8]\n"
" - Mass: [1.000000]\n"
" - Inertial Matrix: \n"
" [1.000000 | 0.000000 | 0.000000]\n"
" [0.000000 | 1.000000 | 0.000000]\n"
" [0.000000 | 0.000000 | 1.000000]\n"
" - Pose: \n"
" [0.000000 | 0.000000 | 0.000000]\n"
" [0.000000 | -0.000000 | 0.000000]\n";

// TODO(@wagnermarcos): Implement test.
EXPECT_EQ(expectedOutput, output);
}

// Tested command: ign model -m vehicle_blue --pose
{
const std::string cmd = kIgnModelCommand + "-m box --pose ";
const std::string output = customExecStr(cmd);
const std::string expectedOutput =
"\nRequesting state for world [shapes] on service [/world/shapes/state]...\n\n"
"Name: box\n"
" - Pose: \n"
" [0.000000 | -0.000000 | 0.500000]\n"
" [0.000000 | 0.000000 | 0.000000]\n\n";
EXPECT_EQ(expectedOutput, output);
// TODO(@wagnermarcos): Implement test.
}

// Tested command: ign model -m box --link box_link
{
const std::string cmd = kIgnModelCommand +
"-m box --link box_link";
const std::string output = customExecStr(cmd);
const std::string expectedOutput =
"\nRequesting state for world [shapes] on service [/world/shapes/state]...\n\n"
" - Link [9]\n"
" - Name: box_link\n"
" - Parent: box [8]\n"
" - Mass: [1.000000]\n"
" - Inertial Matrix: \n"
" [1.000000 | 0.000000 | 0.000000]\n"
" [0.000000 | 1.000000 | 0.000000]\n"
" [0.000000 | 0.000000 | 1.000000]\n"
" - Pose: \n"
" [0.000000 | 0.000000 | 0.000000]\n"
" [0.000000 | -0.000000 | 0.000000]\n";
EXPECT_EQ(expectedOutput, output);
// TODO(@wagnermarcos): Implement test.
}
}

//////////////////////////////////////////////////
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
58 changes: 58 additions & 0 deletions model/src/cmd/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#===============================================================================
# Used for the installed version.
# Generate the ruby script that gets installed.
# Note that the major version of the library is included in the name.
set(cmd_model_script_generated "${CMAKE_CURRENT_BINARY_DIR}/cmdmodel${PROJECT_VERSION_MAJOR}.rb")
set(cmd_model_script_configured "${cmd_model_script_generated}.configured")

# Set the model_library_location variable to the relative path to the library file
# within the install directory structure.
set(model_library_location "../../../${CMAKE_INSTALL_LIBDIR}/$<TARGET_FILE_NAME:${model_lib_target}>")

configure_file(
"cmdmodel.rb.in"
"${cmd_model_script_configured}"
@ONLY)

file(GENERATE
OUTPUT "${cmd_model_script_generated}"
INPUT "${cmd_model_script_configured}")

install(FILES ${cmd_model_script_generated} DESTINATION lib/ruby/ignition)

# Used for the installed version.
set(ign_model_ruby_path "${CMAKE_INSTALL_PREFIX}/lib/ruby/ignition/cmdmodel${PROJECT_VERSION_MAJOR}")

set(ignmodel_configured "${CMAKE_CURRENT_BINARY_DIR}/ignmodel${PROJECT_VERSION_MAJOR}.yaml")
configure_file(
"ignmodel.yaml.in"
${ignmodel_configured})

install(FILES ${ignmodel_configured} DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/ignition/)

#===============================================================================
# Generate the ruby script for internal testing.
# Note that the major version of the library is included in the name.
set(cmd_model_ruby_test_dir "${CMAKE_BINARY_DIR}/model/test/lib/ruby/ignition")
set(cmd_model_script_generated_test "${cmd_model_ruby_test_dir}/cmdmodel${PROJECT_VERSION_MAJOR}.rb")
set(cmd_model_script_configured_test "${cmd_model_script_generated_test}.configured")

# Set the model_library_location variable to the full path of the library file
# within the build directory
set(model_library_location "$<TARGET_FILE:${model_lib_target}>")

configure_file(
"cmdmodel.rb.in"
"${cmd_model_script_configured_test}"
@ONLY)

file(GENERATE
OUTPUT "${cmd_model_script_generated_test}"
INPUT "${cmd_model_script_configured_test}")

# Used for internal testing.
set(ign_model_ruby_path "${cmd_model_script_generated_test}")

configure_file(
"ignmodel.yaml.in"
"${cmd_model_ruby_test_dir}/ignmodel${PROJECT_VERSION_MAJOR}.yaml")
Loading

0 comments on commit df9eee1

Please sign in to comment.