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

Create PoC of SLAM functionality using Gaia #11

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

simone-gaia
Copy link
Contributor

This example aims at teaching Gaia concepts using a real-world use-case scenario (SLAM). This is only for demonstration purposes and does not aim to be a real solution for SLAM.

Still, you can appreciate some of the Graph-based SLAM elements such as the graph data structure (graph, vertex, edge), observation of the external world (incoming_data_event), and building of the graph elements when new observations come in.

-- license that can be found in the LICENSE.txt file
-- or at https://opensource.org/licenses/MIT.
----------------------------------------------------

Copy link

Choose a reason for hiding this comment

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

These tables need an explainer - how do these get used?
I saw that there are comments in the ruleset that talks about hooking rules up to table events,
but "what is this table representing" should be described here as clearly as possible.
Especially the incoming_data_event which won't make sense reading here and is tough to follow from the ruleset.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a little explanation but not too detail since I'm no SLAM expert.

}

// Here's an example with slightly more processing. The paradigm here
// is that incoming data has arrived, and that arrival in turn
Copy link

Choose a reason for hiding this comment

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

What is this incoming data? From where? what does it mean?
Needs more explanation both here and in the ddl.

Choose a reason for hiding this comment

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

+1, would want to see a readme.md describing this, at a high level, and being able to relate the high-level with the low-level

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added explanation in the DDL:

-- This table represents a generic input from a sensor.
-- i.e. Lidar sensor, image, etc..
-- Note: this is just an example.

}

// Create a vertex record
std::string graph_uuid_string("aaaaaaaa-0000-0000-0000-000000000000");
Copy link

Choose a reason for hiding this comment

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

explain what the uuids are being used for

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

Needs a readme.MD to explain which files are important and set the stage for the example being presented. Not enough info here for the uninitiated to follow what is going on.

BasedOnStyle: LLVM
UseCRLF: false
UseTab: Never
IndentWidth: 4

Choose a reason for hiding this comment

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

in readme.md, should document that these are our styles, etc.

Copy link
Contributor

@dr-soong dr-soong Feb 25, 2022

Choose a reason for hiding this comment

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

For the example repo, perhaps we can leave out our styles altoghether? If other people use this the styles are unlikely to align with theirs and it just adds complexity and extra build dependencies

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removd.


database gaia_slam

table graph

Choose a reason for hiding this comment

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

+1 to what bill said. plus a good part in the readme.md detailing why, what, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See comment above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added readme with pretty much same code content as the description of this PR.

{
std::stringstream ss;
ss << "Graph " << g.uuid << " vertices:\n";
for (g.vertices->v:vertex)

Choose a reason for hiding this comment

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

maybe I am a bit rusty, but cant we also do the print in a one-liner?

Choose a reason for hiding this comment

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

the reason I believe that is important is that they may do that accidentally, and they should know that it can happen, to look out for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

gaia::system::initialize();

// This examples wants to focus on direct_access hence the rules are disabled.
gaia::rules::unsubscribe_rules();

Choose a reason for hiding this comment

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

why does it? requirements in readme.md?

Choose a reason for hiding this comment

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

what is this file trying to accomplish? what are the requirements? what is the task to perform?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

why does it? requirements in readme.md?

Explained in the comment above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

/**
 * Showcase the usage of the direct_access API to create/read data from the database.
 * This example does not make usage of Rules.
 */

}

txn.commit();

Choose a reason for hiding this comment

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

how do we know this is working properly? is there expected output?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It prints the things specified in the gaia_log::app().info statements.


// We explicitly handle the transactions with begin_transaction() and commit_transaction()
// to trigger the rules.
gaia::db::begin_transaction();

Choose a reason for hiding this comment

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

why not move the begin and commit transactions inside of the calls? that is what I would expect.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I usually don't recommend it. It always happens that you then need to call the method from another method that already has a transaction open and then you have trouble.


gaia_log::app().info("=== Updates a vertex and observe the corresponding rules triggered ===");

// This code triggers the following rules:

Choose a reason for hiding this comment

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

the "this code triggers" is good. setting up what is expected, so they can follow along.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated.

Copy link

@JackAtGaia JackAtGaia left a comment

Choose a reason for hiding this comment

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

needs more work on describing what to do.

cmake_minimum_required(VERSION 3.16)

project(gaia_slam)
project(gaia_slam)

Choose a reason for hiding this comment

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

dup

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

project(gaia_slam)
project(gaia_slam)

set(CMAKE_CXX_STANDARD 17)

Choose a reason for hiding this comment

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

Why C++17? Do we use C++17 features in this app?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure, but I don't see a reason not to use it. (Well actually i do since our DAC headers use C++17 features, it's a known problem, better to proactively avoid warnings).

id uint64 unique,
type uint8,
data uint8[],
pose_x double,

Choose a reason for hiding this comment

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

This is an obvious candidate for a nested struct when we support complex types...

pose_y double,

-- Relationships
graph_uuid string,
Copy link

@senderista senderista Feb 25, 2022

Choose a reason for hiding this comment

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

Have we considered creating a special UUID type? This should be straightforward to implement as a flatbuffers struct with 2 64-bit ints, and it should be much faster than strings for comparisons. I'm worried about the potential perf penalty of using strings here (and in other usage of UUIDs). If enough apps need UUIDs then I think we should add a first-class UUID type, even if we don't generally support nested structs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will remove uuid for now. This is a leftover from the source example.

But yes, we should have first class uuid support.


#include <gaia/logger.hpp>

// Rule examples. These examples are in two categories. The first shows

Choose a reason for hiding this comment

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

wrapping is odd

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What do you mean? If I had to change something I'd change to multiline comments /**/.

gaia_log::app().info("Inserted vertex record with ID {}", vertex.id);
}

// NOTE that having 2 on_insert rules for the same table results

Choose a reason for hiding this comment

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

should be either "NOTE:" or "Note that"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed



// Using tags
// Tags are a form of shorthand letting you use a shorter label

Choose a reason for hiding this comment

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

How about just "a tag is shorthand for a longer table name"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

// Record change (i.e., insertion or update)
on_change(edge)
{
// Fired for any insert or update to the edge table.

Choose a reason for hiding this comment

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

"fired on"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remvoed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed


// Iterating through a 1:n relationship
//
// This example combines tags and following references between

Choose a reason for hiding this comment

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

"This example uses both tags and reference traversal to list the records in table B that are linked from table A due to changes in A."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

}


// Rule examples where the creates other records.

Choose a reason for hiding this comment

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

"the rule"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed



// Rule examples where the creates other records.
// The serial_group() keyword makes the rules in the ruleset to run serially:

Choose a reason for hiding this comment

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

"makes the rules in the ruleset run serially"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


// Rule examples where the creates other records.
// The serial_group() keyword makes the rules in the ruleset to run serially:
// only one rule is executed in a given point in time.

Choose a reason for hiding this comment

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

"only one rule is executed at a time"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

* Wait an arbitrary amount of time for rule execution to terminate.
* Rules are triggered after commit and can take some time to fully execute.
*/
void wait_for_rules()

Choose a reason for hiding this comment

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

This is really documenting an antipattern that is sure to eventually bite users. If the timeout is too short, it will cause bugs. If it's too long, it will ruin performance.

Choose a reason for hiding this comment

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

If this antipattern is routinely needed to write nontrivial apps, then that's exposing a big hole in our API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

then that's exposing a big hole in our API.

I think this is the point. Nevertheless, the pattern is needed.

https://gaiaplatform.atlassian.net/browse/GAIAPLAT-2080


gaia_log::app().info("=== Retrieving vertexes/edges with type {} ===", vertex_type::c_image_keyframe);

// This code verify that the vertex with type vertex_type::c_image_keyframe has been created.

Choose a reason for hiding this comment

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

"verifies"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

/// Now you can write your additional logic to trigger the other rules,
/// or write some new rules!
///
/// For instance, you may want to create edges between vertexes..

Choose a reason for hiding this comment

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

you say "vertices" elsewhere, so be consistent...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


if (vertex_it.begin() == vertex_it.end())
{
throw std::runtime_error("Impossible to find vertex with id 1 and type lidar_scan");

Choose a reason for hiding this comment

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

"Cannot find"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

gaia_log::app().info(" Edge({}): ({}) --> ({})", e.id(), e.src().id(), e.dest().id());
}

txn.commit();

Choose a reason for hiding this comment

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

Better to enclose the auto_transaction_t in its own scope with all the mutating operations, so you don't need an explicit commit() (if you want to be explicit about the commit() for pedagogical reasons, you probably should use the low-level API rather than auto_transaction_t).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.


// We explicitly handle the transactions with begin_transaction() and commit_transaction()
// to trigger the rules.
gaia::db::begin_transaction();

Choose a reason for hiding this comment

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

Are you avoiding auto_transaction_t for pedagogical reasons (i.e. explicit begin/commit to make txn boundaries clear)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes.

// This code triggers the following rules:
// 1. on_insert(incoming_data_event): triggered when an incoming_data_event is inserted. This insert a new vertex.
// 2. All the rules triggered on vertex insertion.
gaia::db::begin_transaction();

Choose a reason for hiding this comment

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

Again, I would just use auto_transaction_t in a nested scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It would be just more verbose and add a level of indentation.

gaia_log::app().info("=== Retrieving vertexes/edges with type {} ===", vertex_type::c_image_keyframe);

// This code verify that the vertex with type vertex_type::c_image_keyframe has been created.
gaia::db::begin_transaction();

Choose a reason for hiding this comment

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

Again, I would just use auto_transaction_t in a nested scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Answered above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants