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 Python bindings for human state-related data structures #379

Merged
merged 5 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
38 changes: 38 additions & 0 deletions CMakeCache.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This is the CMakeCache file.
# For build in directory: /home/ittbmp014lw003/robotology-superbuild/src/HumanDynamicsEstimation
# It was generated by CMake: /usr/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.

########################
# EXTERNAL cache entries
########################


########################
# INTERNAL cache entries
########################

//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=/home/ittbmp014lw003/robotology-superbuild/src/HumanDynamicsEstimation
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=22
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=1
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.22

Copy link
Member

Choose a reason for hiding this comment

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

Please remove the CMakeCache.txt, it is a file that is supposed to be inside the build directory and contains user-specific folders.

Copy link
Member

Choose a reason for hiding this comment

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

The fact that you have this in the root folder indicates that probably you did a in-source build, while we typically always try to do out of source builds, see https://cmake.org/cmake/help/book/mastering-cmake/chapter/Getting%20Started.html#directory-structure :

Out-of-source builds, where the source and binary directories are different, are strongly encouraged. In-source builds where the source and binary directories are the same are supported but should be avoided if possible. Out-of-source builds make it very easy to maintain a clean source tree and allow quick removal of all of the files generated by a build. Having the build tree differ from the source tree also makes it easy to support having multiple builds of a single source tree. This is useful when you want to have multiple builds with different options but just one copy of the source code.

1 change: 1 addition & 0 deletions CMakeFiles/cmake.check_cache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This file is generated by cmake for dependency checking of the CMakeCache.txt file
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
# This file is generated by cmake for dependency checking of the CMakeCache.txt file
# This file is generated by cmake for dependency checking of the CMakeCache.txt file

As CMakeCache.txt .

5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ find_package(YCM REQUIRED)
# Import cmake utilities
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(AddWarningsConfigurationToTarget)
include(AddHDEPythonModule)

# To build shared libraries in Windows, we set CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS to TRUE
# See https://cmake.org/cmake/help/v3.4/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.html
Expand All @@ -51,6 +52,9 @@ endif()

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Flag to enable python bindings
option(HDE_COMPILE_PYTHON_BINDINGS "Flag that enables building the bindings" OFF)

# Plugins are force to be Shared/Dynamic Library
set(YARP_FORCE_DYNAMIC_PLUGINS ON)

Expand Down Expand Up @@ -86,6 +90,7 @@ add_subdirectory(modules)
add_subdirectory(servers)
add_subdirectory(clients)
add_subdirectory(publishers)
add_subdirectory(bindings)
add_subdirectory(HumanDynamicsEstimationLibrary)

include(InstallBasicPackageFiles)
Expand Down
69 changes: 69 additions & 0 deletions bindings/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
# SPDX-License-Identifier: BSD-3-Clause

if(HDE_COMPILE_PYTHON_BINDINGS)

find_package(Python3 3.6 COMPONENTS Interpreter Development REQUIRED)

find_package(pybind11 2.4.3 CONFIG REQUIRED)

set(NEW_LINE "\n")

option(HDE_DETECT_ACTIVE_PYTHON_SITEPACKAGES
"Do you want HDE to detect and use the active site-package directory? (it could be a system dir)"
FALSE)

# Install the resulting Python package for the active interpreter
if(NOT DEFINED HDE_PYTHON_INSTALL_DIR)
if(HDE_DETECT_ACTIVE_PYTHON_SITEPACKAGES)
set(HDE_PYTHON_INSTALL_DIR ${Python3_SITELIB})
else()
execute_process(COMMAND ${Python3_EXECUTABLE} -c "from distutils import sysconfig; print(sysconfig.get_python_lib(1,0,prefix=''))"
OUTPUT_VARIABLE _PYTHON_INSTDIR)
string(STRIP ${_PYTHON_INSTDIR} _PYTHON_INSTDIR_CLEAN)
set(HDE_PYTHON_INSTALL_DIR ${_PYTHON_INSTDIR_CLEAN})
endif()
endif()
set(PYTHON_INSTDIR ${HDE_PYTHON_INSTALL_DIR}/hde)

# Folder of the Python package within the build tree.
# It is used for the Python tests.
set(HDE_PYTHON_PACKAGE "${CMAKE_BINARY_DIR}/hde")

# Add the bindings directory
add_subdirectory(python)

# Create the __init__.py file
file(GENERATE
OUTPUT "${HDE_PYTHON_PACKAGE}/__init__.py"
CONTENT "from .bindings import *${NEW_LINE}")

# Install the __init__.py file
install(FILES "${HDE_PYTHON_PACKAGE}/__init__.py"
DESTINATION ${PYTHON_INSTDIR})

# Install pip metadata files to ensure that HDE installed via CMake is listed by pip list
# See https://packaging.python.org/specifications/recording-installed-packages/
# and https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata
option(HDE_PYTHON_PIP_METADATA_INSTALL "Use CMake to install Python pip metadata. Set to off if some other tool already installs it." ON)
mark_as_advanced(HDE_PYTHON_PIP_METADATA_INSTALL)
set(HDE_PYTHON_PIP_METADATA_INSTALLER "cmake" CACHE STRING "Specify the string to identify the pip Installer. Default: cmake, change this if you are using another tool.")
mark_as_advanced(HDE_PYTHON_PIP_METADATA_INSTALLER)
if(HDE_PYTHON_PIP_METADATA_INSTALL)
get_filename_component(PYTHON_METADATA_PARENT_DIR ${PYTHON_INSTDIR} DIRECTORY)
if(WIN32)
set(NEW_LINE "\n\r")
else()
set(NEW_LINE "\n")
endif()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/METADATA "")
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/METADATA "Metadata-Version: 2.1${NEW_LINE}")
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/METADATA "Name: hde${NEW_LINE}")
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/METADATA "Version: ${hde_VERSION}${NEW_LINE}")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/INSTALLER "${HDE_PYTHON_PIP_METADATA_INSTALLER}${NEW_LINE}")
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/METADATA" "${CMAKE_CURRENT_BINARY_DIR}/INSTALLER"
DESTINATION ${PYTHON_METADATA_PARENT_DIR}/hde-${hde_VERSION}.dist-info)
endif()

endif()
34 changes: 34 additions & 0 deletions bindings/python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
# SPDX-License-Identifier: BSD-3-Clause

add_subdirectory(msgs)

get_property(pybind_headers GLOBAL PROPERTY pybind_headers)
get_property(pybind_sources GLOBAL PROPERTY pybind_sources)
get_property(pybind_include_dirs GLOBAL PROPERTY pybind_include_dirs)
get_property(pybind_link_libraries GLOBAL PROPERTY pybind_link_libraries)

pybind11_add_module(pybind11_hde MODULE
hde.cpp
${pybind_sources}
${pybind_headers}
)

target_include_directories(pybind11_hde PUBLIC "$<BUILD_INTERFACE:${pybind_include_dirs}>")

target_link_libraries(pybind11_hde PRIVATE
${pybind_link_libraries})

# # The generated Python dynamic module must have the same name as the pybind11
# # module, i.e. `bindings`.
set_target_properties(pybind11_hde PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${HDE_PYTHON_PACKAGE}"
OUTPUT_NAME "bindings")

# Output package is:
#
# bipedal_locomotion
carloscp3009 marked this conversation as resolved.
Show resolved Hide resolved
# |-- __init__.py (generated from main bindings CMake file)
# `-- bindings.<cpython_extension>

install(TARGETS pybind11_hde DESTINATION ${PYTHON_INSTDIR})
18 changes: 18 additions & 0 deletions bindings/python/hde.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
// SPDX-License-Identifier: BSD-3-Clause


#include <pybind11/pybind11.h>

#include <hde/bindings/msgs/Module.h>

// Create the Python module
PYBIND11_MODULE(bindings, m)
{
namespace py = ::pybind11;

m.doc() = "Human dynamics estimation bindings";

py::module msgModule = m.def_submodule("msg");
hde::bindings::msgs::CreateModule(msgModule);
}
11 changes: 11 additions & 0 deletions bindings/python/msgs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
# SPDX-License-Identifier: BSD-3-Clause


set(H_PREFIX include/hde/bindings/msgs)

add_hde_python_module(
NAME MsgsBindings
SOURCES src/HumanState.cpp src/Module.cpp
HEADERS ${H_PREFIX}/HumanState.h ${H_PREFIX}/BufferedPort.h ${H_PREFIX}/Module.h
LINK_LIBRARIES HumanDynamicsEstimation::HumanStateMsg YARP::YARP_os)
44 changes: 44 additions & 0 deletions bindings/python/msgs/include/hde/bindings/msgs/BufferedPort.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
// SPDX-License-Identifier: BSD-3-Clause

#ifndef HDE_BINDINGS_MSGS_BUFFERED_PORT_H
#define HDE_BINDINGS_MSGS_BUFFERED_PORT_H

#include <string>

#include <pybind11/detail/common.h>
#include <pybind11/pybind11.h>

#include <yarp/os/BufferedPort.h>

namespace hde {
namespace bindings {
namespace msgs {

template <typename T>
void CreateBufferedPort(pybind11::module& module, const std::string& name)
{
namespace py = ::pybind11;
py::class_<::yarp::os::BufferedPort<T>>(module, name.c_str())
.def(py::init())
.def("open",
py::overload_cast<const std::string&>(&::yarp::os::BufferedPort<T>::open),
py::arg("name"))
.def("close", &::yarp::os::BufferedPort<T>::close)
.def("isClosed", &::yarp::os::BufferedPort<T>::isClosed)
.def("prepare",
&::yarp::os::BufferedPort<T>::prepare,
py::return_value_policy::reference_internal)
.def("write",
&::yarp::os::BufferedPort<T>::write,
py::arg("forceStrict") = false)
.def("read",
&::yarp::os::BufferedPort<T>::read,
py::arg("shouldWait") = true,
py::return_value_policy::reference_internal);
}
} // namespace msgs
} // namespace bindings
} // namespace hde

#endif // HDE_BINDINGS_MSGS_BUFFERED_PORT_H
19 changes: 19 additions & 0 deletions bindings/python/msgs/include/hde/bindings/msgs/HumanState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
// SPDX-License-Identifier: BSD-3-Clause

#ifndef HDE_BINDINGS_MSGS_HUMAN_STATE_H
#define HDE_BINDINGS_MSGS_HUMAN_STATE_H

#include <pybind11/pybind11.h>

namespace hde {
namespace bindings {
namespace msgs {

void CreateHumanState(pybind11::module& module);

} // namespace msgs
} // namespace bindings
} // namespace hde

#endif // HDE_BINDINGS_MSGS_HUMAN_STATE_H
19 changes: 19 additions & 0 deletions bindings/python/msgs/include/hde/bindings/msgs/Module.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
// SPDX-License-Identifier: BSD-3-Clause

#ifndef HDE_BINDINGS_MSGS_MODULE_H
#define HDE_BINDINGS_MSGS_MODULE_H

#include <pybind11/pybind11.h>

namespace hde {
namespace bindings {
namespace msgs {

void CreateModule(pybind11::module& module);

} // namespace msgs
} // namespace bindings
} // namespace hde

#endif // HDE_BINDINGS_MSGS_MODULE_H
38 changes: 38 additions & 0 deletions bindings/python/msgs/src/HumanState.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
// SPDX-License-Identifier: BSD-3-Clause

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <string>
#include <hde/msgs/HumanState.h>

#include <hde/bindings/msgs/BufferedPort.h>
#include <hde/bindings/msgs/HumanState.h>

namespace hde {
namespace bindings {
namespace msgs {

void CreateHumanState(pybind11::module& module)
{
namespace py = ::pybind11;
using namespace ::hde::msgs;

py::class_<HumanState>(module, "HumanState")
.def(py::init())
.def_readwrite("jointNames", &HumanState::jointNames)
.def_readwrite("positions", &HumanState::positions)
.def_readwrite("velocities", &HumanState::velocities)
.def_readwrite("baseName", &HumanState::baseName)
.def_readwrite("baseOriginWRTGlobal", &HumanState::baseOriginWRTGlobal)
.def_readwrite("baseOrientationWRTGlobal", &HumanState::baseOrientationWRTGlobal)
.def_readwrite("baseVelocityWRTGlobal", &HumanState::baseVelocityWRTGlobal)
.def_readwrite("CoMPositionWRTGlobal", &HumanState::CoMPositionWRTGlobal)
.def_readwrite("CoMVelocityWRTGlobal", &HumanState::CoMVelocityWRTGlobal);

CreateBufferedPort<HumanState>(module, "BufferedPortHumanState");
}
} // namespace msgs
} // namespace bindings
} // namespace hde
20 changes: 20 additions & 0 deletions bindings/python/msgs/src/Module.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
// SPDX-License-Identifier: BSD-3-Clause

#include <pybind11/pybind11.h>

#include <hde/bindings/msgs/HumanState.h>

namespace hde {
namespace bindings {
namespace msgs {

void CreateModule(pybind11::module& module)
{
module.doc() = "YarpUtilities module.";

CreateHumanState(module);
}
} // namespace msgs
} // namespace bindings
} // namespace hde
Loading