mirror of
https://github.com/PhotonVision/photonvision
synced 2026-07-05 03:21:40 +00:00
Make 2027 build (#2422)
This PR updates everything for 2027. This includes removing GradleRIO, simplifying our wpilib version defintion, updating APIs, updating to Java 21, and more. Note that photonlibpy is failing because robotpy has not been fully updated yet. Examples are omitted because they need to be updated for our new PhotonPoseEstimator API and still need some changes from WPILIB. photonlib windows build is failing because we're waiting for some upstream changes. Finally, images are failing since they don't have Java 21 yet.
This commit is contained in:
@@ -28,13 +28,12 @@ package org.photonvision.struct;
|
||||
|
||||
import org.photonvision.common.dataflow.structures.Packet;
|
||||
import org.photonvision.common.dataflow.structures.PacketSerde;
|
||||
import org.photonvision.utils.PacketUtils;
|
||||
|
||||
// Assume that the base class lives here and we can import it
|
||||
import org.photonvision.targeting.*;
|
||||
|
||||
// WPILib imports (if any)
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import org.wpilib.util.struct.Struct;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,13 +28,12 @@ package org.photonvision.struct;
|
||||
|
||||
import org.photonvision.common.dataflow.structures.Packet;
|
||||
import org.photonvision.common.dataflow.structures.PacketSerde;
|
||||
import org.photonvision.utils.PacketUtils;
|
||||
|
||||
// Assume that the base class lives here and we can import it
|
||||
import org.photonvision.targeting.*;
|
||||
|
||||
// WPILib imports (if any)
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import org.wpilib.util.struct.Struct;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,13 +28,12 @@ package org.photonvision.struct;
|
||||
|
||||
import org.photonvision.common.dataflow.structures.Packet;
|
||||
import org.photonvision.common.dataflow.structures.PacketSerde;
|
||||
import org.photonvision.utils.PacketUtils;
|
||||
|
||||
// Assume that the base class lives here and we can import it
|
||||
import org.photonvision.targeting.*;
|
||||
|
||||
// WPILib imports (if any)
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import org.wpilib.util.struct.Struct;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.photonvision.utils.PacketUtils;
|
||||
import org.photonvision.targeting.*;
|
||||
|
||||
// WPILib imports (if any)
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import org.wpilib.util.struct.Struct;
|
||||
import org.wpilib.math.geometry.Transform3d;
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.photonvision.utils.PacketUtils;
|
||||
import org.photonvision.targeting.*;
|
||||
|
||||
// WPILib imports (if any)
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import org.wpilib.util.struct.Struct;
|
||||
import org.wpilib.math.geometry.Transform3d;
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,13 +28,12 @@ package org.photonvision.struct;
|
||||
|
||||
import org.photonvision.common.dataflow.structures.Packet;
|
||||
import org.photonvision.common.dataflow.structures.PacketSerde;
|
||||
import org.photonvision.utils.PacketUtils;
|
||||
|
||||
// Assume that the base class lives here and we can import it
|
||||
import org.photonvision.targeting.*;
|
||||
|
||||
// WPILib imports (if any)
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import org.wpilib.util.struct.Struct;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "photon/targeting/TargetCorner.h"
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <wpi/math/geometry/Transform3d.h>
|
||||
#include <wpi/math/geometry/Transform3d.hpp>
|
||||
|
||||
|
||||
namespace photon {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
// Includes for dependant types
|
||||
#include <stdint.h>
|
||||
#include <wpi/math/geometry/Transform3d.h>
|
||||
#include <wpi/math/geometry/Transform3d.hpp>
|
||||
|
||||
|
||||
namespace photon {
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "photon/targeting/TargetCorner.h"
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <wpi/math/geometry/Transform3d.h>
|
||||
#include <wpi/math/geometry/Transform3d.hpp>
|
||||
|
||||
|
||||
namespace photon {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
// Includes for dependant types
|
||||
#include <stdint.h>
|
||||
#include <wpi/math/geometry/Transform3d.h>
|
||||
#include <wpi/math/geometry/Transform3d.hpp>
|
||||
|
||||
|
||||
namespace photon {
|
||||
|
||||
@@ -85,15 +85,15 @@ public class NTTopicSet {
|
||||
.publish(
|
||||
PhotonPipelineResult.photonStruct.getTypeString(),
|
||||
PubSubOption.periodic(0.01),
|
||||
PubSubOption.sendAll(true),
|
||||
PubSubOption.keepDuplicates(true));
|
||||
PubSubOption.SEND_ALL,
|
||||
PubSubOption.KEEP_DUPLICATES);
|
||||
|
||||
resultPublisher =
|
||||
new PacketPublisher<PhotonPipelineResult>(rawBytesEntry, PhotonPipelineResult.photonStruct);
|
||||
protoResultPublisher =
|
||||
subTable
|
||||
.getProtobufTopic("result_proto", PhotonPipelineResult.proto)
|
||||
.publish(PubSubOption.periodic(0.01), PubSubOption.sendAll(true));
|
||||
.publish(PubSubOption.periodic(0.01), PubSubOption.SEND_ALL);
|
||||
|
||||
pipelineIndexPublisher = subTable.getIntegerTopic("pipelineIndexState").publish();
|
||||
pipelineIndexRequestSub = subTable.getIntegerTopic("pipelineIndexRequest").subscribe(0);
|
||||
|
||||
@@ -48,7 +48,6 @@ import org.wpilib.math.linalg.VecBuilder;
|
||||
import org.wpilib.math.numbers.*;
|
||||
import org.wpilib.math.util.Nat;
|
||||
import org.wpilib.math.util.Num;
|
||||
import org.wpilib.vision.camera.OpenCvLoader;
|
||||
|
||||
/**
|
||||
* A set of various utility functions for getting non-OpenCV data into an OpenCV-compatible format,
|
||||
@@ -269,7 +268,7 @@ public final class OpenCVHelp {
|
||||
* @return The converted rotation in the NWU coordinate system
|
||||
*/
|
||||
private static Rotation3d rotationEDNtoNWU(Rotation3d rot) {
|
||||
return EDN_TO_NWU.unaryMinus().plus(rot.plus(EDN_TO_NWU));
|
||||
return EDN_TO_NWU.inverse().rotateBy(rot.rotateBy(EDN_TO_NWU));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,7 +278,7 @@ public final class OpenCVHelp {
|
||||
* @return The converted rotation in the EDN coordinate system
|
||||
*/
|
||||
private static Rotation3d rotationNWUtoEDN(Rotation3d rot) {
|
||||
return NWU_TO_EDN.unaryMinus().plus(rot.plus(NWU_TO_EDN));
|
||||
return NWU_TO_EDN.inverse().rotateBy(rot.rotateBy(NWU_TO_EDN));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,7 +46,7 @@ public class RotTrlTransform3d {
|
||||
}
|
||||
|
||||
public RotTrlTransform3d(Pose3d initial, Pose3d last) {
|
||||
this.rot = last.getRotation().minus(initial.getRotation());
|
||||
this.rot = last.getRotation().relativeTo(initial.getRotation());
|
||||
this.trl = last.getTranslation().minus(initial.getTranslation().rotateBy(rot));
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ public class RotTrlTransform3d {
|
||||
* @return The inverse transformation
|
||||
*/
|
||||
public RotTrlTransform3d inverse() {
|
||||
var inverseRot = rot.unaryMinus();
|
||||
var inverseRot = rot.inverse();
|
||||
var inverseTrl = trl.rotateBy(inverseRot).unaryMinus();
|
||||
return new RotTrlTransform3d(inverseRot, inverseTrl);
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public class RotTrlTransform3d {
|
||||
}
|
||||
|
||||
public Rotation3d apply(Rotation3d rot) {
|
||||
return rot.plus(this.rot);
|
||||
return rot.rotateBy(this.rot);
|
||||
}
|
||||
|
||||
public List<Rotation3d> applyRots(List<Rotation3d> rots) {
|
||||
|
||||
@@ -106,7 +106,8 @@ void wpi::tsp::TimeSyncClient::Tick() {
|
||||
m_lastPing = ping;
|
||||
}
|
||||
|
||||
void wpi::tsp::TimeSyncClient::UdpCallback(wpi::net::uv::Buffer& buf, size_t nbytes,
|
||||
void wpi::tsp::TimeSyncClient::UdpCallback(wpi::net::uv::Buffer& buf,
|
||||
size_t nbytes,
|
||||
const sockaddr& sender,
|
||||
unsigned flags) {
|
||||
uint64_t pong_local_time = m_timeProvider();
|
||||
@@ -183,8 +184,9 @@ void wpi::tsp::TimeSyncClient::Start() {
|
||||
using namespace std::chrono_literals;
|
||||
m_pingTimer->timeout.connect(&wpi::tsp::TimeSyncClient::Tick, this);
|
||||
|
||||
m_loopRunner.ExecSync(
|
||||
[this](wpi::net::uv::Loop&) { m_pingTimer->Start(m_loopDelay, m_loopDelay); });
|
||||
m_loopRunner.ExecSync([this](wpi::net::uv::Loop&) {
|
||||
m_pingTimer->Start(m_loopDelay, m_loopDelay);
|
||||
});
|
||||
}
|
||||
|
||||
void wpi::tsp::TimeSyncClient::Stop() { m_loopRunner.Stop(); }
|
||||
|
||||
@@ -23,11 +23,12 @@
|
||||
|
||||
#include <wpi/net/UDPClient.hpp>
|
||||
#include <wpi/net/uv/util.hpp>
|
||||
#include <wpi/nt/ntcore_cpp.hpp>
|
||||
#include <wpi/util/Logger.hpp>
|
||||
#include <wpi/util/print.hpp>
|
||||
#include <wpi/util/struct/Struct.hpp>
|
||||
|
||||
#include <wpi/nt/ntcore_cpp.hpp>
|
||||
#include "net/TimeSyncStructs.h"
|
||||
|
||||
static void ServerLoggerFunc(unsigned int level, const char* file,
|
||||
unsigned int line, const char* msg) {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <Eigen/LU>
|
||||
#include <fmt/core.h>
|
||||
#include <wpi/math/fmt/Eigen.hpp>
|
||||
#include <wpi/util/timestamp.h>
|
||||
#include <wpi/util/timestamp.hpp>
|
||||
|
||||
#include "../generate/constrained_solvepnp_10_tags_fixed.h"
|
||||
#include "../generate/constrained_solvepnp_10_tags_free.h"
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "../generate/constrained_solvepnp_8_tags_free.h"
|
||||
#include "../generate/constrained_solvepnp_9_tags_fixed.h"
|
||||
#include "../generate/constrained_solvepnp_9_tags_free.h"
|
||||
#include "wpi/nt/ntcore_cpp.hpp"
|
||||
|
||||
constexpr bool VERBOSE = false;
|
||||
|
||||
@@ -225,7 +226,7 @@ constrained_solvepnp::do_optimization(
|
||||
constexpr double ERROR_TOL = 1e-4;
|
||||
|
||||
for (int iter = 0; iter < 100; iter++) {
|
||||
auto iter_start = wpi::util::Now();
|
||||
auto iter_start = wpi::nt::Now();
|
||||
|
||||
// Check for diverging iterates
|
||||
if (x.template lpNorm<Eigen::Infinity>() > 1e20 || !x.allFinite()) {
|
||||
@@ -343,7 +344,7 @@ constrained_solvepnp::do_optimization(
|
||||
}
|
||||
}
|
||||
|
||||
auto iter_end = wpi::util::Now();
|
||||
auto iter_end = wpi::nt::Now();
|
||||
if constexpr (VERBOSE) {
|
||||
fmt::println(
|
||||
"{}: {} uS, ‖∇J‖={}, α={} ({} refinement steps), {} regularization "
|
||||
|
||||
@@ -191,8 +191,8 @@ std::optional<photon::PnpResult> EstimateRobotPoseConstrainedSolvePNP(
|
||||
guess2.X().value(), guess2.Y().value(),
|
||||
guess2.Rotation().Radians().value()};
|
||||
|
||||
wpi::util::expected<constrained_solvepnp::RobotStateMat, slp::ExitStatus> result =
|
||||
constrained_solvepnp::do_optimization(
|
||||
wpi::util::expected<constrained_solvepnp::RobotStateMat, slp::ExitStatus>
|
||||
result = constrained_solvepnp::do_optimization(
|
||||
headingFree, knownTags.size(), cameraCal, robotToCamera, guessMat,
|
||||
field2points, pointObservations, gyroTheta.Radians().value(),
|
||||
gyroErrorScaleFac);
|
||||
@@ -203,7 +203,8 @@ std::optional<photon::PnpResult> EstimateRobotPoseConstrainedSolvePNP(
|
||||
photon::PnpResult res{};
|
||||
|
||||
res.best = wpi::math::Transform3d{wpi::math::Transform2d{
|
||||
wpi::units::meter_t{result.value()[0]}, wpi::units::meter_t{result.value()[1]},
|
||||
wpi::units::meter_t{result.value()[0]},
|
||||
wpi::units::meter_t{result.value()[1]},
|
||||
wpi::math::Rotation2d{wpi::units::radian_t{result.value()[2]}}}};
|
||||
|
||||
return res;
|
||||
|
||||
@@ -45,8 +45,8 @@ class TimeSyncServer {
|
||||
std::thread m_listener;
|
||||
|
||||
private:
|
||||
void UdpCallback(wpi::net::uv::Buffer& buf, size_t nbytes, const sockaddr& sender,
|
||||
unsigned flags);
|
||||
void UdpCallback(wpi::net::uv::Buffer& buf, size_t nbytes,
|
||||
const sockaddr& sender, unsigned flags);
|
||||
|
||||
public:
|
||||
explicit TimeSyncServer(int port = 5810);
|
||||
|
||||
@@ -43,7 +43,7 @@ class CameraTargetRelation {
|
||||
camToTarg(wpi::math::Transform3d{cameraPose, targetPose}),
|
||||
camToTargDist(camToTarg.Translation().Norm()),
|
||||
camToTargDistXY(wpi::units::math::hypot(camToTarg.Translation().X(),
|
||||
camToTarg.Translation().Y())),
|
||||
camToTarg.Translation().Y())),
|
||||
camToTargYaw(wpi::math::Rotation2d{camToTarg.X().to<double>(),
|
||||
camToTarg.Y().to<double>()}),
|
||||
camToTargPitch(wpi::math::Rotation2d{camToTargDistXY.to<double>(),
|
||||
|
||||
@@ -64,7 +64,7 @@ static wpi::math::Translation3d TranslationNWUtoEDN(
|
||||
|
||||
static wpi::math::Rotation3d RotationNWUtoEDN(
|
||||
const wpi::math::Rotation3d& rot) {
|
||||
return -NWU_TO_EDN + (rot + NWU_TO_EDN);
|
||||
return NWU_TO_EDN.Inverse().RotateBy(rot.RotateBy(NWU_TO_EDN));
|
||||
}
|
||||
|
||||
static std::vector<cv::Point3f> TranslationToTVec(
|
||||
@@ -186,7 +186,7 @@ static wpi::math::Translation3d TranslationEDNToNWU(
|
||||
|
||||
static wpi::math::Rotation3d RotationEDNToNWU(
|
||||
const wpi::math::Rotation3d& rot) {
|
||||
return -EDN_TO_NWU + (rot + EDN_TO_NWU);
|
||||
return EDN_TO_NWU.Inverse().RotateBy(rot.RotateBy(EDN_TO_NWU));
|
||||
}
|
||||
|
||||
static wpi::math::Translation3d TVecToTranslation(const cv::Mat& tvecInput) {
|
||||
@@ -194,9 +194,9 @@ static wpi::math::Translation3d TVecToTranslation(const cv::Mat& tvecInput) {
|
||||
cv::Mat wrapped{tvecInput.rows, tvecInput.cols, CV_32F};
|
||||
tvecInput.convertTo(wrapped, CV_32F);
|
||||
data = wrapped.at<cv::Vec3f>(cv::Point{0, 0});
|
||||
return TranslationEDNToNWU(wpi::math::Translation3d{wpi::units::meter_t{data[0]},
|
||||
wpi::units::meter_t{data[1]},
|
||||
wpi::units::meter_t{data[2]}});
|
||||
return TranslationEDNToNWU(wpi::math::Translation3d{
|
||||
wpi::units::meter_t{data[0]}, wpi::units::meter_t{data[1]},
|
||||
wpi::units::meter_t{data[2]}});
|
||||
}
|
||||
|
||||
static wpi::math::Rotation3d RVecToRotation(const cv::Mat& rvecInput) {
|
||||
|
||||
@@ -32,9 +32,10 @@ class RotTrlTransform3d {
|
||||
|
||||
RotTrlTransform3d(const wpi::math::Pose3d& initial,
|
||||
const wpi::math::Pose3d& last)
|
||||
: trl{last.Translation() - initial.Translation().RotateBy(
|
||||
last.Rotation() - initial.Rotation())},
|
||||
rot{last.Rotation() - initial.Rotation()} {}
|
||||
: trl{last.Translation() -
|
||||
initial.Translation().RotateBy(
|
||||
last.Rotation().RelativeTo(initial.Rotation()))},
|
||||
rot{last.Rotation().RelativeTo(initial.Rotation())} {}
|
||||
explicit RotTrlTransform3d(const wpi::math::Transform3d& trf)
|
||||
: RotTrlTransform3d(trf.Rotation(), trf.Translation()) {}
|
||||
RotTrlTransform3d()
|
||||
@@ -46,7 +47,7 @@ class RotTrlTransform3d {
|
||||
}
|
||||
|
||||
RotTrlTransform3d Inverse() const {
|
||||
wpi::math::Rotation3d invRot = -rot;
|
||||
wpi::math::Rotation3d invRot = rot.Inverse();
|
||||
wpi::math::Translation3d invTrl = -(trl.RotateBy(invRot));
|
||||
return RotTrlTransform3d{invRot, invTrl};
|
||||
}
|
||||
@@ -75,7 +76,7 @@ class RotTrlTransform3d {
|
||||
}
|
||||
|
||||
wpi::math::Rotation3d Apply(const wpi::math::Rotation3d& rotToApply) const {
|
||||
return rotToApply + rot;
|
||||
return rotToApply.RotateBy(rot);
|
||||
}
|
||||
|
||||
std::vector<wpi::math::Rotation3d> ApplyTrls(
|
||||
|
||||
@@ -41,11 +41,12 @@ extern "C" {
|
||||
* Signature: (ZI[D[D[D[D[DDD)[D
|
||||
*/
|
||||
JNIEXPORT jdoubleArray JNICALL
|
||||
Java_org_photonvision_jni_ConstrainedSolvepnpJni_do_1optimization(
|
||||
JNIEnv* env, jclass, jboolean headingFree, jint nTags,
|
||||
jdoubleArray cameraCal, jdoubleArray robot2camera, jdoubleArray xGuess,
|
||||
jdoubleArray field2points, jdoubleArray pointObservations, jdouble gyro_θ,
|
||||
jdouble gyro_error_scale_fac) {
|
||||
Java_org_photonvision_jni_ConstrainedSolvepnpJni_do_1optimization
|
||||
(JNIEnv* env, jclass, jboolean headingFree, jint nTags,
|
||||
jdoubleArray cameraCal, jdoubleArray robot2camera, jdoubleArray xGuess,
|
||||
jdoubleArray field2points, jdoubleArray pointObservations, jdouble gyro_θ,
|
||||
jdouble gyro_error_scale_fac)
|
||||
{
|
||||
auto cameraCalVec = convertJDoubleArray(env, cameraCal);
|
||||
auto robot2cameraVec = convertJDoubleArray(env, robot2camera);
|
||||
auto xGuessVec = convertJDoubleArray(env, xGuess);
|
||||
|
||||
@@ -18,10 +18,11 @@
|
||||
#include <string>
|
||||
|
||||
#include <opencv2/core/mat.hpp>
|
||||
#include <wpi/util/RawFrame.hpp>
|
||||
#include <wpi/util/jni_util.hpp>
|
||||
|
||||
#include "org_photonvision_jni_CscoreExtras.h"
|
||||
#include "wpi/cs/cscore_raw.h"
|
||||
#include "wpi/cs/cscore_raw.hpp"
|
||||
|
||||
// from wpilib, licensed under the wpilib BSD license
|
||||
using namespace wpi::util::java;
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <frc/fmt/Eigen.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <wpi/math/fmt/Eigen.hpp>
|
||||
#include <wpi/util/print.hpp>
|
||||
#include <wpi/util/timestamp.h>
|
||||
|
||||
@@ -159,15 +159,15 @@ void print_cost(casadi_real robot_x, casadi_real robot_y,
|
||||
x_guess << robot_x, robot_y, robot_theta;
|
||||
|
||||
for (int i = 0; i < 200; i++) {
|
||||
auto start = wpi::util::Now();
|
||||
auto start = WPI_Now();
|
||||
auto x_out = constrained_solvepnp::do_optimization(
|
||||
true, TAG_COUNT,
|
||||
constrained_solvepnp::CameraCalibration{fx, fy, cx, cy}, robot2camera,
|
||||
x_guess, field2points, point_observations, 0, 0);
|
||||
auto end = wpi::util::Now();
|
||||
auto end = WPI_Now();
|
||||
|
||||
wpi::println("{},{},{}", i, static_cast<bool>(x_out), end - start);
|
||||
wpi::println(
|
||||
wpi::util::println("{},{},{}", i, static_cast<bool>(x_out), end - start);
|
||||
wpi::util::println(
|
||||
"Solution: {}",
|
||||
x_out.value_or(constrained_solvepnp::RobotStateMat::Identity()));
|
||||
// std::cout << "iter "
|
||||
|
||||
Reference in New Issue
Block a user