Giter Club home page Giter Club logo

farm-ng-core's Introduction

farm-ng-core

farm-ng-core

Foundational library for robotics and machine sensing application under active development


for c++, python and soon rust - under active development


👟Getting Started

Check out the getting-started docs:

here

or

here

Core layer

Convenient macros such as FARM_ENUM, FARM_ASSERT_* and FARM_UNWRAP.

Standard Library-like genera purpose utilities.

farm-ng-core only has a small set of dependencies: libfmt, expected (both being targeted for c++ standardization) and Protocol Buffers / GRPC.

Sophus 2: Building Blocks for 2D and 3D Geometry

Sophus started as a c++ implementation of Lie Groups / Manifolds. It evolved to a collection of types and functions commonly used or 2d and 3d geometric problems especially in the domain of robotics, computer vision annd graphics.

🌐Lie Groups

tldr: rotations, translations and scaling in 2d and 3d

Lie groups are generalizations of the Euclidean vector spaces R^N. A little more formally, a Manifold which is also an abstract group.

Okay, and what is a Manifold?

Manifold are generalizations of the Euclidean vector spaces R^N. In particular, they behave locally like a Euclidean vector space, but globally can have a very different structures. In particular there can be wrap-around. The circle group SO(2) is the simplest example for such wrap around. Assume, we have a dial pointing North. If you turn the dial 90 degree to the left, it points West. If you turn it another 90 degrees it turns South. Now, if you turn it again 90 degrees is points East. And you turn it left again for 90 degrees it points North again. It wrapped around: 90 "+" 90 "+" 90 "+" 90 = 0.

3d rotation example using the SO(3) type

  // The following demonstrates the group multiplication of rotation matrices

  // Create rotation matrices from rotations around the x and y and z axes:
  double const kPi = sophus::kPi<double>;
  sophus::Rotation3F64 R1 = sophus::Rotation3F64::fromRx(kPi / 4);
  sophus::Rotation3F64 R2 = sophus::Rotation3F64::fromRy(kPi / 6);
  sophus::Rotation3F64 R3 = sophus::Rotation3F64::fromRz(-kPi / 3);

  std::cout << "The rotation matrices are" << std::endl;
  std::cout << "R1:\n" << R1.matrix() << std::endl;
  std::cout << "R2:\n" << R2.matrix() << std::endl;
  std::cout << "R3:\n" << R3.matrix() << std::endl;
  std::cout << "Their product R1*R2*R3:\n"
            << (R1 * R2 * R3).matrix() << std::endl;
  std::cout << std::endl;

  // Rotation matrices can act on vectors
  Eigen::Vector3d x;
  x << 0.0, 0.0, 1.0;
  std::cout << "Rotation matrices can act on 3-vectors" << std::endl;
  std::cout << "x\n" << x << std::endl;
  std::cout << "R2*x\n" << R2 * x << std::endl;
  std::cout << "R1*(R2*x)\n" << R1 * (R2 * x) << std::endl;
  std::cout << "(R1*R2)*x\n" << (R1 * R2) * x << std::endl;
  std::cout << std::endl;

  // SO(3) are internally represented as unit quaternions.
  std::cout << "R1 in matrix form:\n" << R1.matrix() << std::endl;
  std::cout << "R1 in unit quaternion form:\n"
            << R1.unitQuaternion().coeffs() << std::endl;
  // Note that the order of coefficients of Eigen's quaternion class is
  // (imag0, imag1, imag2, real)
  std::cout << std::endl;

3d rotation + translation example using the SE(3) type

  // Example of create a rigid transformation from an SO(3) = 3D rotation and a
  // translation 3-vector:

  // Let use assume there is a camera in the world. First we describe its
  // orientation in the world reference frame.
  sophus::Rotation3F64 world_from_camera_rotation =
      sophus::Rotation3F64::fromRx(sophus::kPi<double> / 4);
  // Then the position of the camera in the world.
  Eigen::Vector3d camera_in_world(0.0, 0.0, 1.0);

  // The pose (position and orientation) of the camera in the world is
  // constructed by its orientation ``world_from_camera_rotation`` as well as
  // its position ``camera_in_world``.
  sophus::Isometry3F64 world_anchored_camera_pose(
      world_from_camera_rotation, camera_in_world);

  // SE(3) naturally representation is a 4x4 matrix which can be accessed using
  // the .matrix() method:
  std::cout << "world_anchored_camera_pose:\n"
            << world_anchored_camera_pose.matrix() << std::endl;

Table of Lie Groups

The following table gives an overview of all Lie Groups in Sophus.

c++ type Lie group name Description
Rotation2<T> Special Orthogonal Group in 2D, SO(2) rotations in 2d, also called Circle Group, or just "angle"
Rotation3<T> Special Orthogonal Group in 3D, SO(3) rotations in 3d, 3D orientations
Isometry2<T> Special Euclidean Group in 2D, SE(3) rotations and translations in 2D, also called 2D rigid body transformations, 2d poses, plane isometries
Isometry3<T> Special Euclidean Group in 3D, SE(3) rotations and translations in 3D, also called rigid body transformations,6 DoF poses, Euclidean isometries
RxSo2<T> Direct product of SO(3) and scalar matrix, R x SO(2) scaling and rotations in 2D
RxSo3<T> Direct product of SO(3) and scalar matrix R x SO(3) scaling and rotations in 3D
Similarity2<T> Similarity Group in 2D, Sim(2) scaling, rotations and translation in 2D
Similarity3<T> Similarity Group in 3D, Sim(3) scaling, rotations and translation in 3D
Cartesian2<T> 2D Euclidean Vector Space, R^2 all vector spaces are trivial Lie groups, also called 2d translation group, the translation part of SE(2)
Cartesian3<T> 3D Euclidean Vector Space, R^3 all vector spaces are trivial Lie groups, also called 3d translation group, the translation part of SE(2)

Supported advanced features on Lie groups:

  • ✅ (linear) interpolation
  • ✅ Spline interpolation
  • ✅ Averaging (of more than two elements)

🌁Image classes, Sensor Models and more

Image Classes: Image, MutImage, DynImage, MutDynImage and view classes.

Collection of camera models (pinhole, brown-conrady aka opencv, kannala-brandt and orthographic), IMU mode and more.

Component Pipeline

C++ Component pipeline (aka actor framework) for easy parallelization of data processing pipelines.

Logging/Serialization Infrastructure

  • Text Logging

  • Protobuf Logging

  • RPCs

farm-ng-core's People

Contributors

strasdat avatar hackerman342 avatar edgarriba avatar ethanrublee avatar isherman avatar stevenlovegrove avatar guilhermedemouraa avatar wylderkeane avatar ianbtesser avatar

Stargazers

Oleksandr avatar stelzo avatar zzh avatar Bruno Santos avatar Leandro G. Almeida avatar  avatar Chris avatar Jaeseok Park avatar Masanori Ogino avatar locchuong avatar  avatar

Watchers

 avatar  avatar Gary Bradski avatar Travis Travelstead avatar Marcelo Scatolin Queiroz avatar  avatar  avatar Wren avatar  avatar  avatar Jerry Cowell Jr avatar

Forkers

strasdat

farm-ng-core's Issues

Polish newly merged core+sophus2+cmake project

Initial PR merging sophus2 and farm-ng-core in: #105

  • sort cpp/sophus2 better into existing directory structure
    #113
  • docs:
    • revive/merge docs
  • review all scripts in top level folder and see whether they are still needed
  • dependency management
    • document venv
      #113
    • merge / simply venv build scripts
      #113
    • merge Eigen/format submodules with venv build process
  • cmake
    • flatten directory structure
    • merge cmake/scripts with infra/scripts
  • CI tooling
    • revive clang-tidy
    • asan
    • compile time analysis
  • Merge geometric protos in sophus namespace with newly introduced protos in farm_ng namespace.
    • This will break log formats in downstream projects and should be done on a as needed basis only.
  • use specialization instead of ADL for proto conversion
    to enable more general purpose event logger and playback tools (e.g. such tool do not need to include all proto_conv headers, but only the definition of the toProto / fromProto function template)

PIMPL pattern and Shared

There's been some questions on the team about what our C++ conventions are around the use of the PIMPL pattern, which seems like a pattern we could offer guidance about in our C++ style guide.

To get the conversation started, here are a few statements:

  • We currently make regular use of a pattern that looks like PIMPL -- it hides implementation, with some of the same compilation firewall benefits as PIMPL, but it is not strictly-speaking PIMPL. It requires less boilerplate than PIMPL, since we don't need to provide a duplicate internal method that wraps each public method.
  • There is a great definition of the pattern we use (interface + factory) and a comparison with PIMPL here.
  • We have a type Shared that is useful for enforcing that a shared pointer is not null. By convention the factories in the pattern above return this Shared type.

And a few suggestions:

  • We should document the motivation for this pattern and offer guidance when it should be applied.
  • Our factories should return unique_ptrs (or a non-null Unique) rather than Shared for the reasons outlined here.
  • We could adopt GSL's not_null for a battle-tested implementation of not-null semantics that would apply to all raw and smart pointer types.
template<typename T>
using Unique = gsl::not_null<std::unique_ptr<T>>;

[Feature] Add an event filter utility by message type

Add a small utility in the Python API that the allows to filter the events index by types

def event_has_message(event: event_pb2.Event, msg_type: Any) -> bool:
    """Check if event has a message of type msg_type.

    Args:
        event: event_pb2.Event
        msg_type: protobuf message type

    Returns:
        bool: True if event has a message of type msg_type
    """
    return event.uri.query.split("&")[0].split(".")[-1] == msg_type.__name__

ASSERTS in RELEASE mode

review / design behavior of ASSERT macros when compiled in RELEASE mode

options

  • turn then all off
  • turn them into warnings (no aborts)
  • leave them as is, but introduce DASSERT macros which only fire in DEBUG or in DEBUG+RelWithDebInfo mode
  • etc.

There is no plan to chnge behavior for ASSERTs in DEBUG and RelWithDebInfo modes.

Gracefully deal with LIBFMT exception

Currently, any format error such as FMT("arg1: {}, arg2:P{}", 5); will (most likely) crash the program. This is in most cases not desired. It will turn a minor documentation error into program abortion.

Proposal:

  • Log a warning with the raw format string e.g. "arg1: {}, arg2:P{}" plus the exception message and then continue execution as normal.

Alternative:

  • Re-enable compile time fmt string parsing,. However this might involve sig. engineering work and also increase compile time.

Handle file splitting by max size in `EventWriter` class and log system clock

As future feature this could be part of the EventWriter that takes as input the file base name and max length and internally handle the spliting. Same for the reader, to handle multiple files from a sequence as one. Actually, with this proposal, it will save several of files which can be a bit difficult to track in the gallery/playback app. Maybe we need to append to the parent files messages pointing to the next file ?

Originally posted by @edgarriba in https://github.com/farm-ng/workspace/issues/1084#issuecomment-1373580359

[Feature] Merge boilerplate `get_event` and `read_message`

    @Hackerman342 @ethanrublee an improvement here is to merge `get_event` and `read_message` since we use all the time together. For testing and some internal use cases is good but better coupled for a more user friendly api
def read_uri_message(self, uri: uri_pb2.Uri, event_id: int) -> Any:
    # get the event and offset
    event: event_pb2.Event
    offset: int
    event, offset = self.get_event(uri, current_event)

    # seek and parse the message
    return self.read_message(event, offset)

maybe read_message should be renamed to parse_message and read_message recive the uri and event_id

Originally posted by @edgarriba in farm-ng/farm-ng-amiga#31 (comment)

core_logging, core_utils, & core_pipeline missing tests

Known missing tests:

  • utils/erase_test.cpp
  • utils/stopwatch_test.cpp
  • utils/tokenize_test.cpp
  • utils/thread_pool_test.cpp
  • utils/time_test.cpp
  • Check logging for additional missing tests
  • Check utils for additional missing tests
  • Check pipeline for additional missing tests

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.