From 67945ed6b5bab9ed05452ef117eb3f34feb0da93 Mon Sep 17 00:00:00 2001 From: Jenn Nguyen Date: Wed, 16 Jun 2021 18:36:00 -0700 Subject: [PATCH 1/4] set gui camera pose Signed-off-by: Jenn Nguyen --- src/gui/plugins/view_angle/ViewAngle.cc | 76 ++++++++++++- src/gui/plugins/view_angle/ViewAngle.hh | 19 ++++ src/gui/plugins/view_angle/ViewAngle.qml | 132 ++++++++++++++++++++++- 3 files changed, 221 insertions(+), 6 deletions(-) diff --git a/src/gui/plugins/view_angle/ViewAngle.cc b/src/gui/plugins/view_angle/ViewAngle.cc index eae23f7d4f..a744f0af58 100644 --- a/src/gui/plugins/view_angle/ViewAngle.cc +++ b/src/gui/plugins/view_angle/ViewAngle.cc @@ -18,6 +18,8 @@ #include "ViewAngle.hh" #include +#include +#include #include #include @@ -31,6 +33,9 @@ namespace ignition::gazebo { class ViewAnglePrivate { + /// \brief ViewAngle model + public: ViewAngle *viewAngle{nullptr}; + /// \brief Ignition communication node. public: transport::Node node; @@ -38,7 +43,17 @@ namespace ignition::gazebo public: std::mutex mutex; /// \brief View Angle service name - public: std::string service; + public: std::string viewAngleService; + + /// \brief Move gui camera to pose service name + public: std::string moveToPoseService; + + /// \brief gui camera pose + public: math::Pose3d camPose; + + /// \brief Callback for retrieving gui camera pose + /// \param[in] _msg Pose message + public: void CamPoseCb(const msgs::Pose &_msg); }; } @@ -61,7 +76,17 @@ void ViewAngle::LoadConfig(const tinyxml2::XMLElement *) this->title = "View Angle"; // For view angle requests - this->dataPtr->service = "/gui/view_angle"; + this->dataPtr->viewAngleService = "/gui/view_angle"; + + // Subscribe to camera pose + std::string topic = "/gui/camera/pose"; + this->dataPtr->node.Subscribe( + topic, &ViewAnglePrivate::CamPoseCb, this->dataPtr.get()); + + // Move to pose service + this->dataPtr->moveToPoseService = "/gui/move_to/pose"; + + this->dataPtr->viewAngle = this; } ///////////////////////////////////////////////// @@ -79,7 +104,52 @@ void ViewAngle::OnAngleMode(int _x, int _y, int _z) req.set_y(_y); req.set_z(_z); - this->dataPtr->node.Request(this->dataPtr->service, req, cb); + this->dataPtr->node.Request(this->dataPtr->viewAngleService, req, cb); +} + +///////////////////////////////////////////////// +QList ViewAngle::CamPose() const +{ + return QList({ + QString::number(this->dataPtr->camPose.Pos().X()), + QString::number(this->dataPtr->camPose.Pos().Y()), + QString::number(this->dataPtr->camPose.Pos().Z()), + QString::number(this->dataPtr->camPose.Rot().Roll()), + QString::number(this->dataPtr->camPose.Rot().Pitch()), + QString::number(this->dataPtr->camPose.Rot().Yaw()) + }); +} + +///////////////////////////////////////////////// +void ViewAngle::SetCamPose(double _x, double _y, double _z, + double _roll, double _pitch, double _yaw) +{ + this->dataPtr->camPose.Set(_x, _y, _z, _roll, _pitch, _yaw); + + std::function cb = + [](const ignition::msgs::Boolean &/*_rep*/, const bool _result) + { + if (!_result) + ignerr << "Error sending move camera to pose request" << std::endl; + }; + + ignition::msgs::GUICamera req; + msgs::Set(req.mutable_pose(), this->dataPtr->camPose); + + this->dataPtr->node.Request(this->dataPtr->moveToPoseService, req, cb); +} + +///////////////////////////////////////////////// +void ViewAnglePrivate::CamPoseCb(const msgs::Pose &_msg) +{ + std::lock_guard lock(this->mutex); + math::Pose3d pose = msgs::Convert(_msg); + + if (pose != this->camPose) + { + this->camPose = pose; + this->viewAngle->CamPoseChanged(); + } } // Register this plugin diff --git a/src/gui/plugins/view_angle/ViewAngle.hh b/src/gui/plugins/view_angle/ViewAngle.hh index 02cf34dae9..bdce9e6be7 100644 --- a/src/gui/plugins/view_angle/ViewAngle.hh +++ b/src/gui/plugins/view_angle/ViewAngle.hh @@ -36,6 +36,13 @@ namespace gazebo { Q_OBJECT + /// \brief gui camera pose (QList order is x, y, z, roll, pitch, yaw) + Q_PROPERTY( + QList camPose + READ CamPose + NOTIFY CamPoseChanged + ) + /// \brief Constructor public: ViewAngle(); @@ -54,6 +61,18 @@ namespace gazebo /// to assume. All 0s for x, y, and z indicate the initial camera pose. public slots: void OnAngleMode(int _x, int _y, int _z); + /// \brief Get the current gui camera pose. + public: Q_INVOKABLE QList CamPose() const; + + /// \brief Notify that the gui camera pose has changed. + signals: void CamPoseChanged(); + + /// \brief Callback to update gui camera pose + /// \param[in] _x, _y, _z cartesion coordinates + /// \param[in] _roll, _pitch, _yaw principal coordinates + public slots: void SetCamPose(double _x, double _y, double _z, + double _roll, double _pitch, double _yaw); + /// \internal /// \brief Pointer to private data. private: std::unique_ptr dataPtr; diff --git a/src/gui/plugins/view_angle/ViewAngle.qml b/src/gui/plugins/view_angle/ViewAngle.qml index a0ea12e017..5c47f6d15e 100644 --- a/src/gui/plugins/view_angle/ViewAngle.qml +++ b/src/gui/plugins/view_angle/ViewAngle.qml @@ -20,10 +20,11 @@ import QtQuick.Controls.Material 2.2 import QtQuick.Controls.Material.impl 2.2 import QtQuick.Layouts 1.3 import QtQuick.Controls.Styles 1.4 +import "qrc:/qml" ToolBar { - Layout.minimumWidth: 200 - Layout.minimumHeight: 200 + Layout.minimumWidth: 420 + Layout.minimumHeight: 260 background: Rectangle { color: "transparent" @@ -34,7 +35,7 @@ ToolBar { } GridLayout { - columns: 4 + columns: 8 ToolButton { id: top checkable: true @@ -182,5 +183,130 @@ ToolBar { ViewAngle.OnAngleMode(0, 0, 1) } } + + // set camera pose + // xyz + Text { + Layout.columnSpan: 2 + Layout.row: 0 + Layout.column: 5 + color: "dimgrey" + font.bold: true + text: "Position (m)" + } + + Text { + text: "X" + color: "dimgrey" + Layout.row: 1 + Layout.column: 5 + } + IgnSpinBox { + id: x + Layout.row: 1 + Layout.column: 6 + value: ViewAngle.camPose[0] + maximumValue: 1000.00 + minimumValue: -1000.00 + decimals: 2 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Y" + color: "dimgrey" + Layout.row: 2 + Layout.column: 5 + } + IgnSpinBox { + id: y + Layout.row: 2 + Layout.column: 6 + value: ViewAngle.camPose[1] + maximumValue: 1000.00 + minimumValue: -1000.00 + decimals: 2 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Z" + color: "dimgrey" + Layout.row: 3 + Layout.column: 5 + } + IgnSpinBox { + id: z + Layout.row: 3 + Layout.column: 6 + value: ViewAngle.camPose[2] + maximumValue: 1000.00 + minimumValue: -1000.00 + decimals: 2 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + + // rpy + Text { + Layout.columnSpan: 2 + Layout.row: 0 + Layout.column: 7 + color: "dimgrey" + font.bold: true + text: "Rotation (rad)" + } + + Text { + text: "Roll" + color: "dimgrey" + Layout.row: 1 + Layout.column: 7 + } + IgnSpinBox { + id: roll + Layout.row: 1 + Layout.column: 8 + value: ViewAngle.camPose[3] + maximumValue: 6.28 + minimumValue: 0.00 + decimals: 2 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Pitch" + color: "dimgrey" + Layout.row: 2 + Layout.column: 7 + } + IgnSpinBox { + id: pitch + Layout.row: 2 + Layout.column: 8 + value: ViewAngle.camPose[4] + maximumValue: 6.28 + minimumValue: 0.00 + decimals: 2 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Yaw" + color: "dimgrey" + Layout.row: 3 + Layout.column: 7 + } + IgnSpinBox { + id: yaw + Layout.row: 3 + Layout.column: 8 + value: ViewAngle.camPose[5] + maximumValue: 6.28 + minimumValue: 0.00 + decimals: 2 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } } } From 2b4c28a5b5178962e6721685c2171f5709629c52 Mon Sep 17 00:00:00 2001 From: Jenn Nguyen Date: Thu, 17 Jun 2021 10:37:51 -0700 Subject: [PATCH 2/4] removed circular dependency Signed-off-by: Jenn Nguyen --- src/gui/plugins/view_angle/ViewAngle.cc | 22 ++++++---------------- src/gui/plugins/view_angle/ViewAngle.hh | 6 ++++++ 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/gui/plugins/view_angle/ViewAngle.cc b/src/gui/plugins/view_angle/ViewAngle.cc index a744f0af58..726445ee8a 100644 --- a/src/gui/plugins/view_angle/ViewAngle.cc +++ b/src/gui/plugins/view_angle/ViewAngle.cc @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -33,9 +32,6 @@ namespace ignition::gazebo { class ViewAnglePrivate { - /// \brief ViewAngle model - public: ViewAngle *viewAngle{nullptr}; - /// \brief Ignition communication node. public: transport::Node node; @@ -50,10 +46,6 @@ namespace ignition::gazebo /// \brief gui camera pose public: math::Pose3d camPose; - - /// \brief Callback for retrieving gui camera pose - /// \param[in] _msg Pose message - public: void CamPoseCb(const msgs::Pose &_msg); }; } @@ -81,12 +73,10 @@ void ViewAngle::LoadConfig(const tinyxml2::XMLElement *) // Subscribe to camera pose std::string topic = "/gui/camera/pose"; this->dataPtr->node.Subscribe( - topic, &ViewAnglePrivate::CamPoseCb, this->dataPtr.get()); + topic, &ViewAngle::CamPoseCb, this); // Move to pose service this->dataPtr->moveToPoseService = "/gui/move_to/pose"; - - this->dataPtr->viewAngle = this; } ///////////////////////////////////////////////// @@ -140,15 +130,15 @@ void ViewAngle::SetCamPose(double _x, double _y, double _z, } ///////////////////////////////////////////////// -void ViewAnglePrivate::CamPoseCb(const msgs::Pose &_msg) +void ViewAngle::CamPoseCb(const msgs::Pose &_msg) { - std::lock_guard lock(this->mutex); + std::lock_guard lock(this->dataPtr->mutex); math::Pose3d pose = msgs::Convert(_msg); - if (pose != this->camPose) + if (pose != this->dataPtr->camPose) { - this->camPose = pose; - this->viewAngle->CamPoseChanged(); + this->dataPtr->camPose = pose; + this->CamPoseChanged(); } } diff --git a/src/gui/plugins/view_angle/ViewAngle.hh b/src/gui/plugins/view_angle/ViewAngle.hh index bdce9e6be7..545fb53672 100644 --- a/src/gui/plugins/view_angle/ViewAngle.hh +++ b/src/gui/plugins/view_angle/ViewAngle.hh @@ -18,6 +18,8 @@ #ifndef IGNITION_GAZEBO_GUI_VIEWANGLE_HH_ #define IGNITION_GAZEBO_GUI_VIEWANGLE_HH_ +#include + #include #include @@ -73,6 +75,10 @@ namespace gazebo public slots: void SetCamPose(double _x, double _y, double _z, double _roll, double _pitch, double _yaw); + /// \brief Callback for retrieving gui camera pose + /// \param[in] _msg Pose message + public: void CamPoseCb(const msgs::Pose &_msg); + /// \internal /// \brief Pointer to private data. private: std::unique_ptr dataPtr; From 0cdb38b3fdf9d3bebd4c2cc4a3d362103453de07 Mon Sep 17 00:00:00 2001 From: Jenn Nguyen Date: Thu, 17 Jun 2021 13:55:41 -0700 Subject: [PATCH 3/4] expand spinbox Signed-off-by: Jenn Nguyen --- src/gui/plugins/view_angle/ViewAngle.cc | 14 +- src/gui/plugins/view_angle/ViewAngle.hh | 4 +- src/gui/plugins/view_angle/ViewAngle.qml | 250 ++++++++++++----------- 3 files changed, 137 insertions(+), 131 deletions(-) diff --git a/src/gui/plugins/view_angle/ViewAngle.cc b/src/gui/plugins/view_angle/ViewAngle.cc index 726445ee8a..9de7fddf4f 100644 --- a/src/gui/plugins/view_angle/ViewAngle.cc +++ b/src/gui/plugins/view_angle/ViewAngle.cc @@ -98,15 +98,15 @@ void ViewAngle::OnAngleMode(int _x, int _y, int _z) } ///////////////////////////////////////////////// -QList ViewAngle::CamPose() const +QList ViewAngle::CamPose() const { return QList({ - QString::number(this->dataPtr->camPose.Pos().X()), - QString::number(this->dataPtr->camPose.Pos().Y()), - QString::number(this->dataPtr->camPose.Pos().Z()), - QString::number(this->dataPtr->camPose.Rot().Roll()), - QString::number(this->dataPtr->camPose.Rot().Pitch()), - QString::number(this->dataPtr->camPose.Rot().Yaw()) + this->dataPtr->camPose.Pos().X(), + this->dataPtr->camPose.Pos().Y(), + this->dataPtr->camPose.Pos().Z(), + this->dataPtr->camPose.Rot().Roll(), + this->dataPtr->camPose.Rot().Pitch(), + this->dataPtr->camPose.Rot().Yaw() }); } diff --git a/src/gui/plugins/view_angle/ViewAngle.hh b/src/gui/plugins/view_angle/ViewAngle.hh index 545fb53672..d58b064aed 100644 --- a/src/gui/plugins/view_angle/ViewAngle.hh +++ b/src/gui/plugins/view_angle/ViewAngle.hh @@ -40,7 +40,7 @@ namespace gazebo /// \brief gui camera pose (QList order is x, y, z, roll, pitch, yaw) Q_PROPERTY( - QList camPose + QList camPose READ CamPose NOTIFY CamPoseChanged ) @@ -64,7 +64,7 @@ namespace gazebo public slots: void OnAngleMode(int _x, int _y, int _z); /// \brief Get the current gui camera pose. - public: Q_INVOKABLE QList CamPose() const; + public: Q_INVOKABLE QList CamPose() const; /// \brief Notify that the gui camera pose has changed. signals: void CamPoseChanged(); diff --git a/src/gui/plugins/view_angle/ViewAngle.qml b/src/gui/plugins/view_angle/ViewAngle.qml index 5c47f6d15e..f63b83730b 100644 --- a/src/gui/plugins/view_angle/ViewAngle.qml +++ b/src/gui/plugins/view_angle/ViewAngle.qml @@ -23,8 +23,9 @@ import QtQuick.Controls.Styles 1.4 import "qrc:/qml" ToolBar { - Layout.minimumWidth: 420 - Layout.minimumHeight: 260 + Layout.minimumWidth: 320 + Layout.minimumHeight: 380 + anchors.fill: parent background: Rectangle { color: "transparent" @@ -35,6 +36,8 @@ ToolBar { } GridLayout { + id: views + anchors.horizontalCenter: parent.horizontalCenter columns: 8 ToolButton { id: top @@ -183,130 +186,133 @@ ToolBar { ViewAngle.OnAngleMode(0, 0, 1) } } + } - // set camera pose - // xyz - Text { - Layout.columnSpan: 2 - Layout.row: 0 - Layout.column: 5 - color: "dimgrey" - font.bold: true - text: "Position (m)" - } + // set camera pose + Rectangle { + y: views.height + 10 + width: parent.width + color: "transparent" - Text { - text: "X" - color: "dimgrey" - Layout.row: 1 - Layout.column: 5 - } - IgnSpinBox { - id: x - Layout.row: 1 - Layout.column: 6 - value: ViewAngle.camPose[0] - maximumValue: 1000.00 - minimumValue: -1000.00 - decimals: 2 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) - } - Text { - text: "Y" - color: "dimgrey" - Layout.row: 2 - Layout.column: 5 - } - IgnSpinBox { - id: y - Layout.row: 2 - Layout.column: 6 - value: ViewAngle.camPose[1] - maximumValue: 1000.00 - minimumValue: -1000.00 - decimals: 2 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) - } - Text { - text: "Z" - color: "dimgrey" - Layout.row: 3 - Layout.column: 5 - } - IgnSpinBox { - id: z - Layout.row: 3 - Layout.column: 6 - value: ViewAngle.camPose[2] - maximumValue: 1000.00 - minimumValue: -1000.00 - decimals: 2 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) - } + GridLayout { + width: parent.width + columns: 6 - // rpy - Text { - Layout.columnSpan: 2 - Layout.row: 0 - Layout.column: 7 - color: "dimgrey" - font.bold: true - text: "Rotation (rad)" - } + Text { + text: "X (m)" + color: "dimgrey" + Layout.row: 4 + Layout.column: 1 + leftPadding: 5 + } + IgnSpinBox { + id: x + Layout.fillWidth: true + Layout.row: 4 + Layout.column: 2 + value: ViewAngle.camPose[0] + maximumValue: 1000000 + minimumValue: -1000000 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Y (m)" + color: "dimgrey" + Layout.row: 5 + Layout.column: 1 + leftPadding: 5 + } + IgnSpinBox { + id: y + Layout.fillWidth: true + Layout.row: 5 + Layout.column: 2 + value: ViewAngle.camPose[1] + maximumValue: 1000000 + minimumValue: -1000000 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Z (m)" + color: "dimgrey" + Layout.row: 6 + Layout.column: 1 + leftPadding: 5 + } + IgnSpinBox { + id: z + Layout.fillWidth: true + Layout.row: 6 + Layout.column: 2 + value: ViewAngle.camPose[2] + maximumValue: 1000000 + minimumValue: -1000000 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } - Text { - text: "Roll" - color: "dimgrey" - Layout.row: 1 - Layout.column: 7 - } - IgnSpinBox { - id: roll - Layout.row: 1 - Layout.column: 8 - value: ViewAngle.camPose[3] - maximumValue: 6.28 - minimumValue: 0.00 - decimals: 2 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) - } - Text { - text: "Pitch" - color: "dimgrey" - Layout.row: 2 - Layout.column: 7 - } - IgnSpinBox { - id: pitch - Layout.row: 2 - Layout.column: 8 - value: ViewAngle.camPose[4] - maximumValue: 6.28 - minimumValue: 0.00 - decimals: 2 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) - } - Text { - text: "Yaw" - color: "dimgrey" - Layout.row: 3 - Layout.column: 7 - } - IgnSpinBox { - id: yaw - Layout.row: 3 - Layout.column: 8 - value: ViewAngle.camPose[5] - maximumValue: 6.28 - minimumValue: 0.00 - decimals: 2 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + Text { + text: "Roll (rad)" + color: "dimgrey" + Layout.row: 4 + Layout.column: 3 + leftPadding: 5 + } + IgnSpinBox { + id: roll + Layout.fillWidth: true + Layout.row: 4 + Layout.column: 4 + value: ViewAngle.camPose[3] + maximumValue: 6.28 + minimumValue: -6.28 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Pitch (rad)" + color: "dimgrey" + Layout.row: 5 + Layout.column: 3 + leftPadding: 5 + } + IgnSpinBox { + id: pitch + Layout.fillWidth: true + Layout.row: 5 + Layout.column: 4 + value: ViewAngle.camPose[4] + maximumValue: 6.28 + minimumValue: -6.28 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Yaw (rad)" + color: "dimgrey" + Layout.row: 6 + Layout.column: 3 + leftPadding: 5 + } + IgnSpinBox { + id: yaw + Layout.fillWidth: true + Layout.row: 6 + Layout.column: 4 + value: ViewAngle.camPose[5] + maximumValue: 6.28 + minimumValue: -6.28 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } } } } From f08cd03baacf4686dd975d38238db8106005b279 Mon Sep 17 00:00:00 2001 From: Nate Koenig Date: Fri, 18 Jun 2021 10:19:53 -0700 Subject: [PATCH 4/4] Added a header Signed-off-by: Nate Koenig --- src/gui/plugins/view_angle/ViewAngle.qml | 233 ++++++++++++----------- 1 file changed, 122 insertions(+), 111 deletions(-) diff --git a/src/gui/plugins/view_angle/ViewAngle.qml b/src/gui/plugins/view_angle/ViewAngle.qml index f63b83730b..311ca12b3e 100644 --- a/src/gui/plugins/view_angle/ViewAngle.qml +++ b/src/gui/plugins/view_angle/ViewAngle.qml @@ -194,124 +194,135 @@ ToolBar { width: parent.width color: "transparent" - GridLayout { + ColumnLayout { width: parent.width - columns: 6 - Text { - text: "X (m)" - color: "dimgrey" + text: "Camera Pose" + color: Material.Grey Layout.row: 4 Layout.column: 1 leftPadding: 5 } - IgnSpinBox { - id: x - Layout.fillWidth: true - Layout.row: 4 - Layout.column: 2 - value: ViewAngle.camPose[0] - maximumValue: 1000000 - minimumValue: -1000000 - decimals: 6 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) - } - Text { - text: "Y (m)" - color: "dimgrey" - Layout.row: 5 - Layout.column: 1 - leftPadding: 5 - } - IgnSpinBox { - id: y - Layout.fillWidth: true - Layout.row: 5 - Layout.column: 2 - value: ViewAngle.camPose[1] - maximumValue: 1000000 - minimumValue: -1000000 - decimals: 6 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) - } - Text { - text: "Z (m)" - color: "dimgrey" - Layout.row: 6 - Layout.column: 1 - leftPadding: 5 - } - IgnSpinBox { - id: z - Layout.fillWidth: true - Layout.row: 6 - Layout.column: 2 - value: ViewAngle.camPose[2] - maximumValue: 1000000 - minimumValue: -1000000 - decimals: 6 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) - } - Text { - text: "Roll (rad)" - color: "dimgrey" - Layout.row: 4 - Layout.column: 3 - leftPadding: 5 - } - IgnSpinBox { - id: roll - Layout.fillWidth: true - Layout.row: 4 - Layout.column: 4 - value: ViewAngle.camPose[3] - maximumValue: 6.28 - minimumValue: -6.28 - decimals: 6 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) - } - Text { - text: "Pitch (rad)" - color: "dimgrey" - Layout.row: 5 - Layout.column: 3 - leftPadding: 5 - } - IgnSpinBox { - id: pitch - Layout.fillWidth: true - Layout.row: 5 - Layout.column: 4 - value: ViewAngle.camPose[4] - maximumValue: 6.28 - minimumValue: -6.28 - decimals: 6 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) - } - Text { - text: "Yaw (rad)" - color: "dimgrey" - Layout.row: 6 - Layout.column: 3 - leftPadding: 5 - } - IgnSpinBox { - id: yaw - Layout.fillWidth: true - Layout.row: 6 - Layout.column: 4 - value: ViewAngle.camPose[5] - maximumValue: 6.28 - minimumValue: -6.28 - decimals: 6 - stepSize: 0.01 - onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + GridLayout { + width: parent.width + columns: 6 + + Text { + text: "X (m)" + color: "dimgrey" + Layout.row: 4 + Layout.column: 1 + leftPadding: 5 + } + IgnSpinBox { + id: x + Layout.fillWidth: true + Layout.row: 4 + Layout.column: 2 + value: ViewAngle.camPose[0] + maximumValue: 1000000 + minimumValue: -1000000 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Y (m)" + color: "dimgrey" + Layout.row: 5 + Layout.column: 1 + leftPadding: 5 + } + IgnSpinBox { + id: y + Layout.fillWidth: true + Layout.row: 5 + Layout.column: 2 + value: ViewAngle.camPose[1] + maximumValue: 1000000 + minimumValue: -1000000 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Z (m)" + color: "dimgrey" + Layout.row: 6 + Layout.column: 1 + leftPadding: 5 + } + IgnSpinBox { + id: z + Layout.fillWidth: true + Layout.row: 6 + Layout.column: 2 + value: ViewAngle.camPose[2] + maximumValue: 1000000 + minimumValue: -1000000 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + + Text { + text: "Roll (rad)" + color: "dimgrey" + Layout.row: 4 + Layout.column: 3 + leftPadding: 5 + } + IgnSpinBox { + id: roll + Layout.fillWidth: true + Layout.row: 4 + Layout.column: 4 + value: ViewAngle.camPose[3] + maximumValue: 6.28 + minimumValue: -6.28 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Pitch (rad)" + color: "dimgrey" + Layout.row: 5 + Layout.column: 3 + leftPadding: 5 + } + IgnSpinBox { + id: pitch + Layout.fillWidth: true + Layout.row: 5 + Layout.column: 4 + value: ViewAngle.camPose[4] + maximumValue: 6.28 + minimumValue: -6.28 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } + Text { + text: "Yaw (rad)" + color: "dimgrey" + Layout.row: 6 + Layout.column: 3 + leftPadding: 5 + } + IgnSpinBox { + id: yaw + Layout.fillWidth: true + Layout.row: 6 + Layout.column: 4 + value: ViewAngle.camPose[5] + maximumValue: 6.28 + minimumValue: -6.28 + decimals: 6 + stepSize: 0.01 + onEditingFinished: ViewAngle.SetCamPose(x.value, y.value, z.value, roll.value, pitch.value, yaw.value) + } } } }