28#include <unordered_map>
32#include <wpi/math/interpolation/TimeInterpolatableBuffer.hpp>
33#include <wpi/smartdashboard/Field2d.hpp>
34#include <wpi/smartdashboard/FieldObject2d.hpp>
35#include <wpi/smartdashboard/SmartDashboard.hpp>
36#include <wpi/system/Timer.hpp>
62 std::string tableName =
"VisionSystemSim-" + visionSystemName;
63 wpi::SmartDashboard::PutData(tableName +
"/Sim Field", &dbgField);
68 auto it = camSimMap.find(name);
69 if (it != camSimMap.end()) {
70 return std::make_optional(it->second);
78 std::vector<PhotonCameraSim*> retVal;
79 for (
auto const& cam : camSimMap) {
80 retVal.emplace_back(cam.second);
94 const wpi::math::Transform3d& robotToCamera) {
97 if (found == camSimMap.end()) {
101 std::make_pair(std::move(cameraSim),
102 wpi::math::TimeInterpolatableBuffer<wpi::math::Pose3d>{
104 camTrfMap.at(cameraSim).AddSample(wpi::Timer::GetMonotonicTimestamp(),
105 wpi::math::Pose3d{} + robotToCamera);
122 int numOfElementsRemoved =
124 if (numOfElementsRemoved == 1) {
155 if (camTrfMap.find(cameraSim) != camTrfMap.end()) {
156 wpi::math::TimeInterpolatableBuffer<wpi::math::Pose3d> trfBuffer =
157 camTrfMap.at(cameraSim);
158 std::optional<wpi::math::Pose3d> sample = trfBuffer.Sample(time);
162 return std::make_optional(wpi::math::Transform3d{
163 wpi::math::Pose3d{}, sample.value_or(wpi::math::Pose3d{})});
178 return GetCameraPose(cameraSim, wpi::Timer::GetMonotonicTimestamp());
190 wpi::units::second_t time) {
192 if (!robotToCamera) {
195 return std::make_optional(
GetRobotPose(time) + robotToCamera.value());
208 const wpi::math::Transform3d& robotToCamera) {
209 if (camTrfMap.find(cameraSim) != camTrfMap.end()) {
210 camTrfMap.at(cameraSim).AddSample(wpi::Timer::GetMonotonicTimestamp(),
211 wpi::math::Pose3d{} + robotToCamera);
221 for (
const auto& pair : camTrfMap) {
233 wpi::units::second_t now = wpi::Timer::GetMonotonicTimestamp();
234 if (camTrfMap.find(cameraSim) != camTrfMap.end()) {
235 auto trfBuffer = camTrfMap.at(cameraSim);
236 wpi::math::Transform3d lastTrf{
238 trfBuffer.Sample(now).value_or(wpi::math::Pose3d{})};
253 std::vector<VisionTargetSim> all{};
254 for (
const auto& entry : targetSets) {
255 for (
const auto& target : entry.second) {
256 all.emplace_back(target);
269 return targetSets[type];
296 const std::vector<VisionTargetSim>& targets) {
297 if (!targetSets.contains(type)) {
298 targetSets[type] = std::vector<VisionTargetSim>{};
300 for (
const auto& tgt : targets) {
301 targetSets[type].emplace_back(tgt);
319 std::vector<VisionTargetSim> targets;
320 for (
const wpi::apriltag::AprilTag& tag : layout.GetTags()) {
321 targets.emplace_back(
VisionTargetSim{layout.GetTagPose(tag.ID).value(),
349 const std::vector<VisionTargetSim>& targets) {
350 std::vector<VisionTargetSim> removedList;
351 for (
auto& entry : targetSets) {
352 auto& vec = entry.second;
353 auto it = vec.begin();
354 while (it != vec.end()) {
355 if (std::find(targets.begin(), targets.end(), *it) != targets.end()) {
356 removedList.emplace_back(*it);
372 return GetRobotPose(wpi::Timer::GetMonotonicTimestamp());
382 return robotPoseBuffer.Sample(timestamp).value_or(wpi::math::Pose3d{});
400 robotPoseBuffer.Clear();
401 robotPoseBuffer.AddSample(wpi::Timer::GetMonotonicTimestamp(), robotPose);
411 void Update(
const wpi::math::Pose2d& robotPose) {
412 Update(wpi::math::Pose3d{robotPose});
421 void Update(
const wpi::math::Pose3d& robotPose) {
422 for (
auto& set : targetSets) {
423 std::vector<wpi::math::Pose2d> posesToAdd{};
424 for (
auto& target : set.second) {
425 posesToAdd.emplace_back(target.GetPose().ToPose2d());
427 dbgField.GetObject(set.first)->SetPoses(posesToAdd);
430 wpi::units::second_t now = wpi::Timer::GetMonotonicTimestamp();
431 robotPoseBuffer.AddSample(now, robotPose);
432 dbgField.SetRobotPose(robotPose.ToPose2d());
434 std::vector<VisionTargetSim> allTargets{};
435 for (
const auto& set : targetSets) {
436 for (
const auto& target : set.second) {
437 allTargets.emplace_back(target);
441 std::vector<wpi::math::Pose2d> visTgtPoses2d{};
442 std::vector<wpi::math::Pose2d> cameraPoses2d{};
443 bool processed{
false};
444 for (
const auto& entry : camSimMap) {
445 auto camSim = entry.second;
446 auto optTimestamp = camSim->ConsumeNextEntryTime();
452 uint64_t timestampNt = optTimestamp.value();
453 wpi::units::second_t latency = camSim->prop.EstLatency();
454 wpi::units::second_t timestampCapture =
455 wpi::units::microsecond_t{
static_cast<double>(timestampNt)} - latency;
457 wpi::math::Pose3d lateRobotPose =
GetRobotPose(timestampCapture);
458 wpi::math::Pose3d lateCameraPose =
460 cameraPoses2d.push_back(lateCameraPose.ToPose2d());
462 auto camResult = camSim->Process(latency, lateCameraPose, allTargets);
463 camSim->SubmitProcessedFrame(camResult, timestampNt);
464 for (
const auto& target : camResult.GetTargets()) {
465 auto trf = target.GetBestCameraToTarget();
466 if (trf == kEmptyTrf) {
469 visTgtPoses2d.push_back(lateCameraPose.TransformBy(trf).ToPose2d());
473 dbgField.GetObject(
"visibleTargetPoses")->SetPoses(visTgtPoses2d);
475 if (cameraPoses2d.size() != 0) {
476 dbgField.GetObject(
"cameras")->SetPoses(cameraPoses2d);
481 std::unordered_map<std::string, PhotonCameraSim*> camSimMap{};
482 static constexpr wpi::units::second_t bufferLength{1.5_s};
483 std::unordered_map<PhotonCameraSim*,
484 wpi::math::TimeInterpolatableBuffer<wpi::math::Pose3d>>
486 wpi::math::TimeInterpolatableBuffer<wpi::math::Pose3d> robotPoseBuffer{
488 std::unordered_map<std::string, std::vector<VisionTargetSim>> targetSets{};
489 wpi::Field2d dbgField{};
490 const wpi::math::Transform3d kEmptyTrf{};
const std::string_view GetCameraName() const
Returns the name of the camera.
Definition PhotonCameraSim.h:42
PhotonCamera * GetCamera()
Returns the camera being simulated.
Definition PhotonCameraSim.h:99
A simulated vision system involving a camera(s) and coprocessor(s) mounted on a mobile robot running ...
Definition VisionSystemSim.h:48
std::optional< PhotonCameraSim * > GetCameraSim(std::string name)
Get one of the simulated cameras.
Definition VisionSystemSim.h:67
void ResetRobotPose(const wpi::math::Pose3d &robotPose)
Clears all previous robot poses and sets robotPose at current time.
Definition VisionSystemSim.h:399
wpi::Field2d & GetDebugField()
Definition VisionSystemSim.h:403
std::optional< wpi::math::Transform3d > GetRobotToCamera(PhotonCameraSim *cameraSim, wpi::units::second_t time)
Get a simulated camera's position relative to the robot.
Definition VisionSystemSim.h:153
std::vector< VisionTargetSim > RemoveVisionTargets(const std::vector< VisionTargetSim > &targets)
Removes the specified VisionTargetSims from the simulated field.
Definition VisionSystemSim.h:348
std::optional< wpi::math::Transform3d > GetRobotToCamera(PhotonCameraSim *cameraSim)
Get a simulated camera's position relative to the robot.
Definition VisionSystemSim.h:139
void AddCamera(PhotonCameraSim *cameraSim, const wpi::math::Transform3d &robotToCamera)
Adds a simulated camera to this vision system with a specified robot-to-camera transformation.
Definition VisionSystemSim.h:93
void AddAprilTags(const wpi::apriltag::AprilTagFieldLayout &layout)
Adds targets on the field which your vision system is designed to detect.
Definition VisionSystemSim.h:318
void AddVisionTargets(std::string type, const std::vector< VisionTargetSim > &targets)
Adds targets on the field which your vision system is designed to detect.
Definition VisionSystemSim.h:295
void ResetCameraTransforms()
Reset the previous transforms for all cameras to their current transform.
Definition VisionSystemSim.h:220
wpi::math::Pose3d GetRobotPose(wpi::units::second_t timestamp)
Get the robot pose in meters saved by the vision system at this timestamp.
Definition VisionSystemSim.h:381
void RemoveVisionTargets(std::string type)
Removes every VisionTargetSim of the specified type from the simulated field.
Definition VisionSystemSim.h:340
bool ResetCameraTransforms(PhotonCameraSim *cameraSim)
Reset the transform history for this camera to just the current transform.
Definition VisionSystemSim.h:232
std::vector< PhotonCameraSim * > GetCameraSims()
Get all the simulated cameras.
Definition VisionSystemSim.h:77
VisionSystemSim(std::string visionSystemName)
A simulated vision system involving a camera(s) and coprocessor(s) mounted on a mobile robot running ...
Definition VisionSystemSim.h:61
std::optional< wpi::math::Pose3d > GetCameraPose(PhotonCameraSim *cameraSim)
Get a simulated camera's position on the field.
Definition VisionSystemSim.h:177
void ClearVisionTargets()
Removes every VisionTargetSim from the simulated field.
Definition VisionSystemSim.h:327
std::vector< VisionTargetSim > GetVisionTargets()
Returns all the vision targets on the field.
Definition VisionSystemSim.h:252
void ResetRobotPose(const wpi::math::Pose2d &robotPose)
Clears all previous robot poses and sets robotPose at current time.
Definition VisionSystemSim.h:390
void AddVisionTargets(const std::vector< VisionTargetSim > &targets)
Adds targets on the field which your vision system is designed to detect.
Definition VisionSystemSim.h:282
std::vector< VisionTargetSim > GetVisionTargets(std::string type)
Returns all the vision targets of the specified type on the field.
Definition VisionSystemSim.h:268
std::optional< wpi::math::Pose3d > GetCameraPose(PhotonCameraSim *cameraSim, wpi::units::second_t time)
Get a simulated camera's position on the field.
Definition VisionSystemSim.h:189
void Update(const wpi::math::Pose2d &robotPose)
Periodic update.
Definition VisionSystemSim.h:411
wpi::math::Pose3d GetRobotPose()
Get the latest robot pose in meters saved by the vision system.
Definition VisionSystemSim.h:371
bool AdjustCamera(PhotonCameraSim *cameraSim, const wpi::math::Transform3d &robotToCamera)
Adjust a camera's position relative to the robot.
Definition VisionSystemSim.h:207
void Update(const wpi::math::Pose3d &robotPose)
Periodic update.
Definition VisionSystemSim.h:421
void ClearAprilTags()
Removes all simulated AprilTag targets from the simulated field.
Definition VisionSystemSim.h:329
void ClearCameras()
Remove all simulated cameras from this vision system.
Definition VisionSystemSim.h:110
bool RemoveCamera(PhotonCameraSim *cameraSim)
Remove a simulated camera from this vision system.
Definition VisionSystemSim.h:121
Describes a vision target located somewhere on the field that your vision system can detect.
Definition VisionTargetSim.h:36
Definition VisionEstimation.h:30
static const TargetModel kAprilTag36h11
Definition TargetModel.h:117