Simulation GUI: Add 2D field view (#2261)

The field image and robot image can be loaded or just a wireframe used.
The robot can be moved and rotated with a mouse click + drag.
The robot position is settable in robot code via the Field2d class.
This commit is contained in:
Peter Johnson
2020-02-01 21:30:23 -08:00
committed by GitHub
parent 42da07396c
commit c165dc5e50
16 changed files with 2325 additions and 5 deletions

View File

@@ -0,0 +1,49 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2020 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#include "frc/simulation/Field2d.h"
using namespace frc;
Field2d::Field2d() : m_device{"Field2D"} {
if (m_device) {
m_x = m_device.CreateDouble("x", false, 0.0);
m_y = m_device.CreateDouble("y", false, 0.0);
m_rot = m_device.CreateDouble("rot", false, 0.0);
}
}
void Field2d::SetRobotPose(const Pose2d& pose) {
if (m_device) {
auto& translation = pose.Translation();
m_x.Set(translation.X().to<double>());
m_y.Set(translation.Y().to<double>());
m_rot.Set(pose.Rotation().Degrees().to<double>());
} else {
m_pose = pose;
}
}
void Field2d::SetRobotPose(units::meter_t x, units::meter_t y,
Rotation2d rotation) {
if (m_device) {
m_x.Set(x.to<double>());
m_y.Set(y.to<double>());
m_rot.Set(rotation.Degrees().to<double>());
} else {
m_pose = Pose2d{x, y, rotation};
}
}
Pose2d Field2d::GetRobotPose() {
if (m_device) {
return Pose2d{units::meter_t{m_x.Get()}, units::meter_t{m_y.Get()},
Rotation2d{units::degree_t{m_rot.Get()}}};
} else {
return m_pose;
}
}

View File

@@ -0,0 +1,70 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2020 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <hal/SimDevice.h>
#include <units/units.h>
#include "frc/geometry/Pose2d.h"
#include "frc/geometry/Rotation2d.h"
namespace frc {
/**
* 2D representation of game field (for simulation).
*
* In non-simulation mode this simply stores and returns the robot pose.
*
* The robot pose is the actual location shown on the simulation view.
* This may or may not match the robot's internal odometry. For example, if
* the robot is shown at a particular starting location, the pose in this
* class would represent the actual location on the field, but the robot's
* internal state might have a 0,0,0 pose (unless it's initialized to
* something different).
*
* As the user is able to edit the pose, code performing updates should get
* the robot pose, transform it as appropriate (e.g. based on simulated wheel
* velocity), and set the new pose.
*/
class Field2d {
public:
Field2d();
/**
* Set the robot pose from a Pose object.
*
* @param pose 2D pose
*/
void SetRobotPose(const Pose2d& pose);
/**
* Set the robot pose from x, y, and rotation.
*
* @param x X location
* @param y Y location
* @param rotation rotation
*/
void SetRobotPose(units::meter_t x, units::meter_t y, Rotation2d rotation);
/**
* Get the robot pose.
*
* @return 2D pose
*/
Pose2d GetRobotPose();
private:
Pose2d m_pose;
hal::SimDevice m_device;
hal::SimDouble m_x;
hal::SimDouble m_y;
hal::SimDouble m_rot;
};
} // namespace frc