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

Point cloud visualization plugin #346

Merged
merged 13 commits into from
Jan 26, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
21 changes: 21 additions & 0 deletions examples/standalone/point_cloud/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)

project(ignition-gui-point-cloud-example)

if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
find_package(ignition-transport12 QUIET REQUIRED OPTIONAL_COMPONENTS log)
set(IGN_TRANSPORT_VER ${ignition-transport12_VERSION_MAJOR})

find_package(ignition-common5 REQUIRED)
set(IGN_COMMON_VER ${ignition-common5_VERSION_MAJOR})

find_package(ignition-msgs9 REQUIRED)
set(IGN_MSGS_VER ${ignition-msgs9_VERSION_MAJOR})

add_executable(point_cloud point_cloud.cc)
target_link_libraries(point_cloud
ignition-transport${IGN_TRANSPORT_VER}::core
ignition-msgs${IGN_MSGS_VER}
ignition-common${IGN_COMMON_VER}::ignition-common${IGN_COMMON_VER}
)
endif()
43 changes: 43 additions & 0 deletions examples/standalone/point_cloud/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Point cloud visualization example

This example publishes a point cloud that can be visualized with the
`PointCloud` plugin. The example publishes:

* `ignition::msgs::PointCloudPacked` messages on `/point_cloud` with XYZ
positions of points.
* `ignition::msgs::FloatV` messages on 3 different topics:
* `/flat`: Array of 1s
* `/sum`: Each value in the array corresponds to the sum of its point's
coordinates (X + Y + Z).
* `/product`: Each value in the array corresponds to the product of its
point's coordinates (X * Y * Z).

## Build Instructions

Navigate to this directory:

cd <path to ign-gui>/examples/standalone/point_cloud

Build:

mkdir build
cd build
cmake ..
make

## Execute Instructions

1. Navigate to this directory:

cd <path to ign-gui>/examples/standalone/point_cloud

1. Launch the example config file:

ign gui -c point_cloud.config

3. From the build directory above, publish clouds to be visualized:

./point_cloud

4. Try out different options on the plugin.

106 changes: 106 additions & 0 deletions examples/standalone/point_cloud/point_cloud.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright (C) 2022 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 <ignition/msgs/float_v.pb.h>
#include <ignition/msgs/pointcloud_packed.pb.h>

#include <ignition/transport/Node.hh>

#include <atomic>
#include <chrono>
#include <csignal>
#include <iostream>
#include <thread>

using namespace std::chrono_literals;

// Set to true if a signal has been received to terminate publishing
static std::atomic<bool> g_terminatePub(false);

/////////////////////////////////////////////////
int main(int _argc, char **_argv)
{
// Install a signal handler for SIGINT and SIGTERM.
auto signalHandler = [](int _signal) -> void
{
if (_signal == SIGINT || _signal == SIGTERM)
g_terminatePub = true;
};
std::signal(SIGINT, signalHandler);
std::signal(SIGTERM, signalHandler);

// Create messages
ignition::msgs::PointCloudPacked pcMsg;
ignition::msgs::InitPointCloudPacked(pcMsg, "some_frame", true,
{{"xyz", ignition::msgs::PointCloudPacked::Field::FLOAT32}});

int numberOfPoints{1000};
unsigned int dataSize{numberOfPoints * pcMsg.point_step()};
pcMsg.mutable_data()->resize(dataSize);
pcMsg.set_height(1);
pcMsg.set_width(1000);

ignition::msgs::Float_V flatMsg;
ignition::msgs::Float_V sumMsg;
ignition::msgs::Float_V productMsg;

// Populate messages
ignition::msgs::PointCloudPackedIterator<float> xIter(pcMsg, "x");
ignition::msgs::PointCloudPackedIterator<float> yIter(pcMsg, "y");
ignition::msgs::PointCloudPackedIterator<float> zIter(pcMsg, "z");

for (float x = 0.0, y = 0.0, z = 0.0;
xIter != xIter.End();
++xIter, ++yIter, ++zIter)
{
*xIter = x;
*yIter = y;
*zIter = z;
flatMsg.add_data(1);
sumMsg.add_data(x + y + z);
productMsg.add_data(x * y * z);

x += 1.0;
if (x > 9)
{
x = 0.0;
y += 1.0;
}
if (y > 9)
{
y = 0.0;
z += 1.0;
}
}

// Publish messages at 1Hz until interrupted.
ignition::transport::Node node;
auto flatPub = node.Advertise<ignition::msgs::Float_V>("/flat");
auto sumPub = node.Advertise<ignition::msgs::Float_V>("/sum");
auto productPub = node.Advertise<ignition::msgs::Float_V>("/product");
auto pcPub = node.Advertise<ignition::msgs::PointCloudPacked>("/point_cloud");

while (!g_terminatePub)
{
std::cout << "Publishing" << std::endl;
flatPub.Publish(flatMsg);
sumPub.Publish(sumMsg);
productPub.Publish(productMsg);
pcPub.Publish(pcMsg);
std::this_thread::sleep_for(1s);
}
}
63 changes: 63 additions & 0 deletions examples/standalone/point_cloud/point_cloud.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0"?>

<plugin filename="MinimalScene">
<ignition-gui>
<title>View 1</title>
<property type="string" key="state">docked</property>
</ignition-gui>
<engine>ogre2</engine>
<scene>scene</scene>
<ambient_light>1 1 1</ambient_light>
<background_color>0.8 0.8 0.8</background_color>
<camera_pose>-10 5 10 0 0.5 0</camera_pose>
</plugin>
<plugin filename="InteractiveViewControl" name="Interactive view control">
<ignition-gui>
<anchors target="View 1">
<line own="right" target="right"/>
<line own="top" target="top"/>
</anchors>
<property key="resizable" type="bool">false</property>
<property key="width" type="double">5</property>
<property key="height" type="double">5</property>
<property key="state" type="string">floating</property>
<property key="showTitleBar" type="bool">false</property>
</ignition-gui>
</plugin>
<plugin filename="MarkerManager" name="Marker Manager">
<ignition-gui>
<anchors target="View 1">
<line own="right" target="right"/>
<line own="top" target="top"/>
</anchors>
<property key="resizable" type="bool">false</property>
<property key="width" type="double">5</property>
<property key="height" type="double">5</property>
<property key="state" type="string">floating</property>
<property key="showTitleBar" type="bool">false</property>
</ignition-gui>
</plugin>
<plugin filename="PointCloud" name="Point Cloud">
<ignition-gui>
<title>Flat</title>
<property type="string" key="state">docked</property>
</ignition-gui>
<point_cloud_topic>/point_cloud</point_cloud_topic>
<float_v_topic>/flat</float_v_topic>
</plugin>
<plugin filename="PointCloud" name="Point Cloud">
<ignition-gui>
<title>Sum</title>
<property type="string" key="state">docked</property>
</ignition-gui>
<point_cloud_topic>/point_cloud</point_cloud_topic>
<float_v_topic>/sum</float_v_topic>
</plugin>
<plugin filename="PointCloud" name="Point Cloud">
<ignition-gui>
<title>Product</title>
<property type="string" key="state">docked</property>
</ignition-gui>
<point_cloud_topic>/point_cloud</point_cloud_topic>
<float_v_topic>/product</float_v_topic>
</plugin>
6 changes: 6 additions & 0 deletions include/ignition/gui/Helpers.hh
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,14 @@ namespace ignition
T findFirstByProperty(const QList<T> _list, const char *_key,
QVariant _value)
{
if (nullptr == _key)
return nullptr;

for (const auto &w : _list)
{
if (nullptr == w)
continue;

if (w->property(_key) == _value)
return w;
}
Expand Down
3 changes: 3 additions & 0 deletions src/Helpers_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,15 @@ TEST(HelpersTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(findFirstByProperty))

// Construct a list
auto o0 = new QObject();
ASSERT_NE(nullptr, o0);
o0->setProperty("banana", 1.0);

auto o1 = new QObject();
ASSERT_NE(nullptr, o1);
o1->setProperty("banana", 2.0);

auto o2 = new QObject();
ASSERT_NE(nullptr, o2);
o2->setProperty("banana", 1.0);

QList<QObject *> list;
Expand Down
1 change: 1 addition & 0 deletions src/plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ add_subdirectory(image_display)
add_subdirectory(interactive_view_control)
add_subdirectory(key_publisher)
add_subdirectory(plotting)
add_subdirectory(point_cloud)
add_subdirectory(publisher)
add_subdirectory(marker_manager)
add_subdirectory(minimal_scene)
Expand Down
10 changes: 10 additions & 0 deletions src/plugins/point_cloud/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ign_gui_add_plugin(PointCloud
SOURCES
PointCloud.cc
QT_HEADERS
PointCloud.hh
PUBLIC_LINK_LIBS
ignition-rendering${IGN_RENDERING_VER}::ignition-rendering${IGN_RENDERING_VER}
TEST_SOURCES
PointCloud_TEST.cc
)
Loading