2020-12-26 14:12:05 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
2020-10-30 13:55:38 -07:00
|
|
|
|
|
|
|
|
#include "frc/smartdashboard/FieldObject2d.h"
|
|
|
|
|
|
[glass] Field2d enhancements (#3234)
- Add raw support for pose lists > 255/3 in length
- Improve drag selection, especially with closely overlapping objects
- Drag selection of corner also highlights center of object with smaller circle
- Multiple styles (box, line, closed line, track)
- Configurable line and arrow settings (color, weight)
- Add tooltip for object name, index, x, y, rotation
- Context menu for pose edit/add/remove
- View/edit in feet or inches as well as meters
- Configurable object selectability
Implementation: use vector of Pose2d internally, use units
2021-03-27 13:34:44 -07:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include <wpi/Endian.h>
|
|
|
|
|
#include <wpi/MathExtras.h>
|
|
|
|
|
|
2021-04-02 01:08:07 -04:00
|
|
|
#include "frc/trajectory/Trajectory.h"
|
|
|
|
|
|
2020-10-30 13:55:38 -07:00
|
|
|
using namespace frc;
|
|
|
|
|
|
2020-12-23 20:36:51 -08:00
|
|
|
FieldObject2d::FieldObject2d(FieldObject2d&& rhs) {
|
|
|
|
|
std::swap(m_name, rhs.m_name);
|
|
|
|
|
std::swap(m_entry, rhs.m_entry);
|
|
|
|
|
std::swap(m_poses, rhs.m_poses);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FieldObject2d& FieldObject2d::operator=(FieldObject2d&& rhs) {
|
|
|
|
|
std::swap(m_name, rhs.m_name);
|
|
|
|
|
std::swap(m_entry, rhs.m_entry);
|
|
|
|
|
std::swap(m_poses, rhs.m_poses);
|
|
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-30 13:55:38 -07:00
|
|
|
void FieldObject2d::SetPose(const Pose2d& pose) {
|
|
|
|
|
SetPoses(wpi::makeArrayRef(pose));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FieldObject2d::SetPose(units::meter_t x, units::meter_t y,
|
|
|
|
|
Rotation2d rotation) {
|
|
|
|
|
SetPoses(wpi::makeArrayRef(Pose2d{x, y, rotation}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Pose2d FieldObject2d::GetPose() const {
|
|
|
|
|
std::scoped_lock lock(m_mutex);
|
|
|
|
|
UpdateFromEntry();
|
2020-12-28 12:58:06 -08:00
|
|
|
if (m_poses.empty()) {
|
|
|
|
|
return {};
|
|
|
|
|
}
|
2020-10-30 13:55:38 -07:00
|
|
|
return m_poses[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FieldObject2d::SetPoses(wpi::ArrayRef<Pose2d> poses) {
|
|
|
|
|
std::scoped_lock lock(m_mutex);
|
|
|
|
|
m_poses.assign(poses.begin(), poses.end());
|
|
|
|
|
UpdateEntry();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FieldObject2d::SetPoses(std::initializer_list<Pose2d> poses) {
|
|
|
|
|
SetPoses(wpi::makeArrayRef(poses.begin(), poses.end()));
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-02 01:08:07 -04:00
|
|
|
void FieldObject2d::SetTrajectory(const Trajectory& trajectory) {
|
|
|
|
|
std::scoped_lock lock(m_mutex);
|
|
|
|
|
m_poses.clear();
|
|
|
|
|
m_poses.reserve(trajectory.States().size());
|
|
|
|
|
for (auto&& state : trajectory.States()) {
|
|
|
|
|
m_poses.push_back(state.pose);
|
|
|
|
|
}
|
|
|
|
|
UpdateEntry();
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-30 13:55:38 -07:00
|
|
|
std::vector<Pose2d> FieldObject2d::GetPoses() const {
|
|
|
|
|
std::scoped_lock lock(m_mutex);
|
|
|
|
|
UpdateFromEntry();
|
|
|
|
|
return std::vector<Pose2d>(m_poses.begin(), m_poses.end());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wpi::ArrayRef<Pose2d> FieldObject2d::GetPoses(
|
|
|
|
|
wpi::SmallVectorImpl<Pose2d>& out) const {
|
|
|
|
|
std::scoped_lock lock(m_mutex);
|
|
|
|
|
UpdateFromEntry();
|
|
|
|
|
out.assign(m_poses.begin(), m_poses.end());
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FieldObject2d::UpdateEntry(bool setDefault) {
|
2020-12-28 12:58:06 -08:00
|
|
|
if (!m_entry) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
[glass] Field2d enhancements (#3234)
- Add raw support for pose lists > 255/3 in length
- Improve drag selection, especially with closely overlapping objects
- Drag selection of corner also highlights center of object with smaller circle
- Multiple styles (box, line, closed line, track)
- Configurable line and arrow settings (color, weight)
- Add tooltip for object name, index, x, y, rotation
- Context menu for pose edit/add/remove
- View/edit in feet or inches as well as meters
- Configurable object selectability
Implementation: use vector of Pose2d internally, use units
2021-03-27 13:34:44 -07:00
|
|
|
if (m_poses.size() < (255 / 3)) {
|
|
|
|
|
wpi::SmallVector<double, 9> arr;
|
|
|
|
|
for (auto&& pose : m_poses) {
|
|
|
|
|
auto& translation = pose.Translation();
|
|
|
|
|
arr.push_back(translation.X().to<double>());
|
|
|
|
|
arr.push_back(translation.Y().to<double>());
|
|
|
|
|
arr.push_back(pose.Rotation().Degrees().to<double>());
|
|
|
|
|
}
|
|
|
|
|
if (setDefault) {
|
|
|
|
|
m_entry.SetDefaultDoubleArray(arr);
|
|
|
|
|
} else {
|
|
|
|
|
m_entry.ForceSetDoubleArray(arr);
|
|
|
|
|
}
|
2020-12-28 12:58:06 -08:00
|
|
|
} else {
|
[glass] Field2d enhancements (#3234)
- Add raw support for pose lists > 255/3 in length
- Improve drag selection, especially with closely overlapping objects
- Drag selection of corner also highlights center of object with smaller circle
- Multiple styles (box, line, closed line, track)
- Configurable line and arrow settings (color, weight)
- Add tooltip for object name, index, x, y, rotation
- Context menu for pose edit/add/remove
- View/edit in feet or inches as well as meters
- Configurable object selectability
Implementation: use vector of Pose2d internally, use units
2021-03-27 13:34:44 -07:00
|
|
|
// send as raw array of doubles if too big for NT array
|
|
|
|
|
std::vector<char> arr;
|
|
|
|
|
arr.resize(m_poses.size() * 3 * 8);
|
|
|
|
|
char* p = arr.data();
|
|
|
|
|
for (auto&& pose : m_poses) {
|
|
|
|
|
auto& translation = pose.Translation();
|
|
|
|
|
wpi::support::endian::write64be(
|
|
|
|
|
p, wpi::DoubleToBits(translation.X().to<double>()));
|
|
|
|
|
p += 8;
|
|
|
|
|
wpi::support::endian::write64be(
|
|
|
|
|
p, wpi::DoubleToBits(translation.Y().to<double>()));
|
|
|
|
|
p += 8;
|
|
|
|
|
wpi::support::endian::write64be(
|
|
|
|
|
p, wpi::DoubleToBits(pose.Rotation().Degrees().to<double>()));
|
|
|
|
|
p += 8;
|
|
|
|
|
}
|
|
|
|
|
if (setDefault) {
|
2021-06-06 16:13:58 -07:00
|
|
|
m_entry.SetDefaultRaw({arr.data(), arr.size()});
|
[glass] Field2d enhancements (#3234)
- Add raw support for pose lists > 255/3 in length
- Improve drag selection, especially with closely overlapping objects
- Drag selection of corner also highlights center of object with smaller circle
- Multiple styles (box, line, closed line, track)
- Configurable line and arrow settings (color, weight)
- Add tooltip for object name, index, x, y, rotation
- Context menu for pose edit/add/remove
- View/edit in feet or inches as well as meters
- Configurable object selectability
Implementation: use vector of Pose2d internally, use units
2021-03-27 13:34:44 -07:00
|
|
|
} else {
|
2021-06-06 16:13:58 -07:00
|
|
|
m_entry.ForceSetRaw({arr.data(), arr.size()});
|
[glass] Field2d enhancements (#3234)
- Add raw support for pose lists > 255/3 in length
- Improve drag selection, especially with closely overlapping objects
- Drag selection of corner also highlights center of object with smaller circle
- Multiple styles (box, line, closed line, track)
- Configurable line and arrow settings (color, weight)
- Add tooltip for object name, index, x, y, rotation
- Context menu for pose edit/add/remove
- View/edit in feet or inches as well as meters
- Configurable object selectability
Implementation: use vector of Pose2d internally, use units
2021-03-27 13:34:44 -07:00
|
|
|
}
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2020-10-30 13:55:38 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FieldObject2d::UpdateFromEntry() const {
|
2020-12-28 12:58:06 -08:00
|
|
|
if (!m_entry) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-10-30 13:55:38 -07:00
|
|
|
auto val = m_entry.GetValue();
|
[glass] Field2d enhancements (#3234)
- Add raw support for pose lists > 255/3 in length
- Improve drag selection, especially with closely overlapping objects
- Drag selection of corner also highlights center of object with smaller circle
- Multiple styles (box, line, closed line, track)
- Configurable line and arrow settings (color, weight)
- Add tooltip for object name, index, x, y, rotation
- Context menu for pose edit/add/remove
- View/edit in feet or inches as well as meters
- Configurable object selectability
Implementation: use vector of Pose2d internally, use units
2021-03-27 13:34:44 -07:00
|
|
|
if (!val) {
|
2020-12-28 12:58:06 -08:00
|
|
|
return;
|
|
|
|
|
}
|
[glass] Field2d enhancements (#3234)
- Add raw support for pose lists > 255/3 in length
- Improve drag selection, especially with closely overlapping objects
- Drag selection of corner also highlights center of object with smaller circle
- Multiple styles (box, line, closed line, track)
- Configurable line and arrow settings (color, weight)
- Add tooltip for object name, index, x, y, rotation
- Context menu for pose edit/add/remove
- View/edit in feet or inches as well as meters
- Configurable object selectability
Implementation: use vector of Pose2d internally, use units
2021-03-27 13:34:44 -07:00
|
|
|
|
|
|
|
|
if (val->IsDoubleArray()) {
|
|
|
|
|
auto arr = val->GetDoubleArray();
|
|
|
|
|
auto size = arr.size();
|
|
|
|
|
if ((size % 3) != 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
m_poses.resize(size / 3);
|
|
|
|
|
for (size_t i = 0; i < size / 3; ++i) {
|
|
|
|
|
m_poses[i] =
|
|
|
|
|
Pose2d{units::meter_t{arr[i * 3 + 0]}, units::meter_t{arr[i * 3 + 1]},
|
|
|
|
|
Rotation2d{units::degree_t{arr[i * 3 + 2]}}};
|
|
|
|
|
}
|
|
|
|
|
} else if (val->IsRaw()) {
|
|
|
|
|
// treat it simply as an array of doubles
|
2021-06-06 16:13:58 -07:00
|
|
|
std::string_view data = val->GetRaw();
|
[glass] Field2d enhancements (#3234)
- Add raw support for pose lists > 255/3 in length
- Improve drag selection, especially with closely overlapping objects
- Drag selection of corner also highlights center of object with smaller circle
- Multiple styles (box, line, closed line, track)
- Configurable line and arrow settings (color, weight)
- Add tooltip for object name, index, x, y, rotation
- Context menu for pose edit/add/remove
- View/edit in feet or inches as well as meters
- Configurable object selectability
Implementation: use vector of Pose2d internally, use units
2021-03-27 13:34:44 -07:00
|
|
|
|
|
|
|
|
// must be triples of doubles
|
|
|
|
|
auto size = data.size();
|
|
|
|
|
if ((size % (3 * 8)) != 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
m_poses.resize(size / (3 * 8));
|
2021-06-06 16:13:58 -07:00
|
|
|
const char* p = data.data();
|
[glass] Field2d enhancements (#3234)
- Add raw support for pose lists > 255/3 in length
- Improve drag selection, especially with closely overlapping objects
- Drag selection of corner also highlights center of object with smaller circle
- Multiple styles (box, line, closed line, track)
- Configurable line and arrow settings (color, weight)
- Add tooltip for object name, index, x, y, rotation
- Context menu for pose edit/add/remove
- View/edit in feet or inches as well as meters
- Configurable object selectability
Implementation: use vector of Pose2d internally, use units
2021-03-27 13:34:44 -07:00
|
|
|
for (size_t i = 0; i < size / (3 * 8); ++i) {
|
|
|
|
|
double x = wpi::BitsToDouble(
|
|
|
|
|
wpi::support::endian::readNext<uint64_t, wpi::support::big,
|
|
|
|
|
wpi::support::unaligned>(p));
|
|
|
|
|
double y = wpi::BitsToDouble(
|
|
|
|
|
wpi::support::endian::readNext<uint64_t, wpi::support::big,
|
|
|
|
|
wpi::support::unaligned>(p));
|
|
|
|
|
double rot = wpi::BitsToDouble(
|
|
|
|
|
wpi::support::endian::readNext<uint64_t, wpi::support::big,
|
|
|
|
|
wpi::support::unaligned>(p));
|
|
|
|
|
m_poses[i] = Pose2d{units::meter_t{x}, units::meter_t{y},
|
|
|
|
|
Rotation2d{units::degree_t{rot}}};
|
|
|
|
|
}
|
2020-10-30 13:55:38 -07:00
|
|
|
}
|
|
|
|
|
}
|