Skip to content

Commit

Permalink
Merge branch 'ign-common4' into lock_console
Browse files Browse the repository at this point in the history
  • Loading branch information
mjcarroll committed Nov 9, 2021
2 parents a7e8fed + b337f4e commit f5097ce
Show file tree
Hide file tree
Showing 17 changed files with 704 additions and 52 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
#============================================================================
# Initialize the project
#============================================================================
project(ignition-common4 VERSION 4.2.0)
project(ignition-common4 VERSION 4.4.0)

#============================================================================
# Find ignition-cmake
Expand All @@ -14,7 +14,7 @@ set(IGN_CMAKE_VER ${ignition-cmake2_VERSION_MAJOR})
#============================================================================
# Configure the project
#============================================================================
ign_configure_project(VERSION_SUFFIX)
ign_configure_project()

#============================================================================
# Set project-specific options
Expand Down
31 changes: 30 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
## Ignition Common 4.x

## Ignition Common 4.X.X (202X-XX-XX)
## Ignition Common 4.4.0 (2021-10-15)

1. Add support for animation tension
* [Pull request #256](https://github.com/ignitionrobotics/ign-common/pull/256)

## Ignition Common 4.3.0 (2021-09-27)

1. Remove ign-utils from TempDirectory
* [Pull request #248](https://github.com/ignitionrobotics/ign-common/pull/248)

1. Add functions and objects for Temporary Directories
* [Pull request #244](https://github.com/ignitionrobotics/ign-common/pull/244)

1. Fix memory corruption & leaks in Image
* [Pull request #240](https://github.com/ignitionrobotics/ign-common/pull/240)

1. Fix a typo in VideoEncoder_TEST.
* [Pull request #231](https://github.com/ignitionrobotics/ign-common/pull/231)

1. Fix segfault caused by destruction order of Event and Connection
* [Pull request #234](https://github.com/ignitionrobotics/ign-common/pull/234)

1. Infrastructure
* [Pull request #62](https://github.com/ignitionrobotics/ign-common/pull/62)
* [Pull request #55](https://github.com/ignitionrobotics/ign-common/pull/55)
* [Pull request #241](https://github.com/ignitionrobotics/ign-common/pull/241)

1. Documentation
* [Pull request #252](https://github.com/ignitionrobotics/ign-common/pull/252)
* [Pull request #253](https://github.com/ignitionrobotics/ign-common/pull/253)

## Ignition Common 4.2.0 (2021-08-02)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Refer to the following table for information about important directories and fil
# Contributing

Please see
[CONTRIBUTING.md](https://github.com/ignitionrobotics/ign-gazebo/blob/main/CONTRIBUTING.md).
[CONTRIBUTING.md](https://ignitionrobotics.org/docs/all/contributing).

# Code of Conduct

Expand Down
27 changes: 27 additions & 0 deletions graphics/include/ignition/common/Animation.hh
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,21 @@ namespace ignition
public: PoseAnimation(const std::string &_name,
const double _length, const bool _loop);

/// \brief Constructor
/// \param[in] _name String name of the animation. This should be unique.
/// \param[in] _length Length of the animation in seconds
/// \param[in] _loop True == loop the animation
/// \param[in] _tension The tension of the trajectory spline. The
/// default value of zero equates to a Catmull-Rom spline, which may
/// also cause the animation to overshoot keyframes. A value of one will
/// cause the animation to stick to the keyframes. This value should
/// be in the range 0..1.
/// \todo(nkoenig) Remove this in ign-common5, and use a single
/// consutrctory with a default _tension of 0.
public: PoseAnimation(const std::string &_name,
const double _length, const bool _loop,
double _tension);

/// \brief Create a pose keyframe at the given time
/// \param[in] _time Time at which to create the keyframe
/// \return Pointer to the new keyframe
Expand Down Expand Up @@ -234,6 +249,18 @@ namespace ignition
std::map<std::chrono::steady_clock::time_point, math::Pose3d>
_waypoints);

/// \brief Load all waypoints in the trajectory
/// \param[in] _waypoints Map of waypoints, where the key is the absolute
/// time of the waypoint and the value is the pose.
/// \param[in] _tension The tension of the trajectory spline. The
/// default value of zero equates to a Catmull-Rom spline, which may
/// also cause the animation to overshoot keyframes. A value of one will
/// cause the animation to stick to the keyframes. This value should
/// be in the range 0..1.
public: void SetWaypoints(
std::map<std::chrono::steady_clock::time_point, math::Pose3d>
_waypoints, double _tension);

/// \brief Private data pointer.
IGN_UTILS_IMPL_PTR(dataPtr)
};
Expand Down
9 changes: 9 additions & 0 deletions graphics/include/ignition/common/MeshManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ namespace ignition
/// \param[in] the mesh to add.
public: void AddMesh(Mesh *_mesh);

/// \brief Remove a mesh based on a name.
/// \param[in] _name Name of the mesh to remove.
/// \return True if the mesh was removed, false if the mesh with the
/// provided name could not be found.
public: bool RemoveMesh(const std::string &_name);

/// \brief Remove all meshes.
public: void RemoveAll();

/// \brief Get a mesh by name.
/// \param[in] _name the name of the mesh to look for
/// \return the mesh or nullptr if not found
Expand Down
24 changes: 23 additions & 1 deletion graphics/src/Animation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ class PoseAnimation::Implementation

/// \brief determines if the interpolation splines need building
public: bool build{false};

/// \brief Spline tension parameter.
public: double tension{0.0};
};

/////////////////////////////////////////////////
Expand Down Expand Up @@ -290,6 +293,15 @@ PoseAnimation::PoseAnimation(const std::string &_name, const double _length,
{
}

/////////////////////////////////////////////////
PoseAnimation::PoseAnimation(const std::string &_name, const double _length,
const bool _loop, double _tension)
: Animation(_name, _length, _loop),
dataPtr(ignition::utils::MakeImpl<Implementation>())
{
this->dataPtr->tension = math::clamp(_tension, 0.0, 1.0);
}

/////////////////////////////////////////////////
PoseKeyFrame *PoseAnimation::CreateKeyFrame(const double _time)
{
Expand All @@ -309,6 +321,7 @@ void PoseAnimation::BuildInterpolationSplines()
this->dataPtr->positionSpline->AutoCalculate(false);
this->dataPtr->rotationSpline->AutoCalculate(false);

this->dataPtr->positionSpline->Tension(this->dataPtr->tension);
this->dataPtr->positionSpline->Clear();
this->dataPtr->rotationSpline->Clear();

Expand Down Expand Up @@ -511,6 +524,15 @@ common::PoseAnimation *TrajectoryInfo::Waypoints() const
void TrajectoryInfo::SetWaypoints(
std::map<std::chrono::steady_clock::time_point, math::Pose3d> _waypoints)
{
this->SetWaypoints(_waypoints, 0.0);
}

/////////////////////////////////////////////////
void TrajectoryInfo::SetWaypoints(
std::map<std::chrono::steady_clock::time_point, math::Pose3d> _waypoints,
double _tension)
{
_tension = math::clamp(_tension, 0.0, 1.0);
this->dataPtr->segDistance.clear();

auto first = _waypoints.begin();
Expand All @@ -523,7 +545,7 @@ void TrajectoryInfo::SetWaypoints(
animName << this->AnimIndex() << "_" << this->Id();
std::shared_ptr<common::PoseAnimation> anim =
std::make_shared<common::PoseAnimation>(animName.str(),
std::chrono::duration<double>(this->Duration()).count(), false);
std::chrono::duration<double>(this->Duration()).count(), false, _tension);

auto prevPose = first->second.Pos();
for (auto pIter = _waypoints.begin(); pIter != _waypoints.end(); ++pIter)
Expand Down
24 changes: 24 additions & 0 deletions graphics/src/Animation_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,30 @@ TEST_F(AnimationTest, PoseAnimation)
math::Quaterniond(0.0302776, 0.0785971, 0.109824));
}

/////////////////////////////////////////////////
TEST_F(AnimationTest, PoseAnimationTension)
{
// Test using a tension value of 1.0, which should cause the pose
// animation to hit the key frames.

common::PoseAnimation animTension("test-tension", 10.0, false, 1.0);
common::PoseKeyFrame *keyTension = animTension.CreateKeyFrame(0.0);
keyTension->Translation(math::Vector3d(0, 0, 0));
keyTension->Rotation(math::Quaterniond(0, 0, 0));

animTension.AddTime(5.0);
keyTension->Translation(math::Vector3d(10, 20, 30));
keyTension->Rotation(math::Quaterniond(0.1, 0.2, 0.3));
animTension.Time(4.0);

common::PoseKeyFrame interpolatedKeyTension(-1.0);
animTension.InterpolatedKeyFrame(interpolatedKeyTension);
EXPECT_TRUE(interpolatedKeyTension.Translation() ==
math::Vector3d(10, 20, 30));
EXPECT_TRUE(interpolatedKeyTension.Rotation() ==
math::Quaterniond(0.1, 0.2, 0.3));
}

/////////////////////////////////////////////////
TEST_F(AnimationTest, NumericAnimation)
{
Expand Down
27 changes: 27 additions & 0 deletions graphics/src/MeshManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,33 @@ const Mesh *MeshManager::MeshByName(const std::string &_name) const
return nullptr;
}

//////////////////////////////////////////////////
void MeshManager::RemoveAll()
{
std::lock_guard<std::mutex> lock(this->dataPtr->mutex);
for (auto m : this->dataPtr->meshes)
{
delete m.second;
}
this->dataPtr->meshes.clear();
}

//////////////////////////////////////////////////
bool MeshManager::RemoveMesh(const std::string &_name)
{
std::lock_guard<std::mutex> lock(this->dataPtr->mutex);

auto iter = this->dataPtr->meshes.find(_name);
if (iter != this->dataPtr->meshes.end())
{
delete iter->second;
this->dataPtr->meshes.erase(iter);
return true;
}

return false;
}

//////////////////////////////////////////////////
bool MeshManager::HasMesh(const std::string &_name) const
{
Expand Down
22 changes: 22 additions & 0 deletions graphics/src/MeshManager_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,28 @@ TEST_F(MeshManager, CreateExtrudedPolylineInvalid)
EXPECT_TRUE(!common::MeshManager::Instance()->HasMesh(meshName));
}

/////////////////////////////////////////////////
TEST_F(MeshManager, Remove)
{
auto mgr = common::MeshManager::Instance();

EXPECT_FALSE(mgr->HasMesh("box"));
mgr->CreateBox("box",
ignition::math::Vector3d(1, 1, 1),
ignition::math::Vector2d(0, 0));
EXPECT_TRUE(mgr->HasMesh("box"));

mgr->CreateSphere("sphere", 1.0, 1, 1);
EXPECT_TRUE(mgr->HasMesh("sphere"));

EXPECT_TRUE(mgr->RemoveMesh("box"));
EXPECT_FALSE(mgr->HasMesh("box"));
EXPECT_TRUE(mgr->HasMesh("sphere"));

mgr->RemoveAll();
EXPECT_FALSE(mgr->HasMesh("sphere"));
}

/////////////////////////////////////////////////
int main(int argc, char **argv)
{
Expand Down
111 changes: 111 additions & 0 deletions include/ignition/common/TempDirectory.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright 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.
*
*/

#ifndef IGNITION_COMMON_TEMPDIRECTORY_HH_
#define IGNITION_COMMON_TEMPDIRECTORY_HH_

#include <memory>
#include <string>

#include <ignition/common/Export.hh>
#include <ignition/common/Filesystem.hh>

namespace ignition
{
namespace common
{
class TempDirectoryPrivate;

/// \brief Return the path to a directory suitable for temporary files.
///
/// Calls std::filesystem::temp_directory_path, refer to the standard
/// documentation for your platform for behaviors.
/// \return A directory suitable for temporary files.
std::string IGNITION_COMMON_VISIBLE tempDirectoryPath();

/// \brief Create a directory in the tempDirectoryPath by expanding
/// a name template
///
/// On execution, will create the directory:
/// "_parentPath"/"_baseName" + "XXXXXX", where XXXXXX will be filled
/// out by an OS-appropriate method (eg mkdtmp/_mktemp_s)
///
/// \param[in] _baseName String to be prepended to the expanded template
/// \param[in] _parentPath Location to create the directory
/// \param[in] _warningOp Allow or suppress filesystem warnings
/// \return Path to newly-created temporary directory
std::string IGNITION_COMMON_VISIBLE createTempDirectory(
const std::string &_baseName,
const std::string &_parentPath,
const FilesystemWarningOp _warningOp = FSWO_LOG_WARNINGS);

/// \class TempDirectory TempDirectory.hh ignitin/common/TempDirectory.hh
/// \brief Create a temporary directory in the OS temp location.
/// Upon construction, the current working directory will be set to this
/// new temporary directory.
/// Upon destruction, the current working directory will be restored to the
/// location when the TempDirectory object was constructed.
class IGNITION_COMMON_VISIBLE TempDirectory
{
/// \brief Create a directory in the tempDirectoryPath by expanding
/// a name template. This directory can also be automatically cleaned
/// up when the object goes out of scope.
///
/// The TempDirectory will have the form $TMPDIR/_subdir/_prefixXXXXX/
///
/// \param[in] _prefix String to be expanded for the template
/// \param[in] _subDir Subdirectory in OS $TMPDIR, if desired
/// \param[in] _cleanup True to indicate that the filesystem should
/// be cleaned as part of the destructor
public: TempDirectory(const std::string &_prefix = "temp_dir",
const std::string &_subDir = "ignition",
bool _cleanup = true);

/// \brief Destroy the temporary directory, removing from filesystem
/// if cleanup is true.
public: ~TempDirectory();

/// \brief Indicate if the TempDirectory object is in a valid state
/// and that the folder exists on the filesystem
/// \return true if the TempDirectory is valid
public: bool Valid() const;

/// \brief Set if the folder on disk should be cleaned.
///
/// This is useful if you wish to clean by default during a test, but
/// retain the contents of the TempDirectory if the test fails.
/// \param[in] _doCleanup True to indicate that the filesystem should
/// be cleaned as part of the destructor
public: void DoCleanup(bool _doCleanup);

/// \brief Retrieve the current cleanup flag state
/// \return true if filesystem cleanup will occur
public: bool DoCleanup() const;

/// \brief Retrieve the fully-expanded temporary directory path
/// \return the temporary directory path
public: std::string Path() const;

IGN_COMMON_WARN_IGNORE__DLL_INTERFACE_MISSING
/// \brief Private data pointer
private: std::unique_ptr<TempDirectoryPrivate> dataPtr;
IGN_COMMON_WARN_RESUME__DLL_INTERFACE_MISSING
};
} // namespace common
} // namespace ignition
#endif // IGNITION_COMMON_TEMPDIRECTORY_HH_

2 changes: 1 addition & 1 deletion src/Console.cc
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ void FileLogger::Init(const std::string &_directory,
if (isDirectory(logPath))
this->logDirectory = logPath;
else
this->logDirectory = logPath.substr(0, logPath.rfind(separator("")));
this->logDirectory = common::parentPath(logPath);

this->initialized = true;

Expand Down
Loading

0 comments on commit f5097ce

Please sign in to comment.