mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-22 01:11:40 +00:00
Too many changes to list
running in to bug in CameraStreamer with native exceptions
This commit is contained in:
437
LICENSE
Normal file
437
LICENSE
Normal file
@@ -0,0 +1,437 @@
|
||||
Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution-NonCommercial-ShareAlike 4.0 International Public License
|
||||
("Public License"). To the extent this Public License may be
|
||||
interpreted as a contract, You are granted the Licensed Rights in
|
||||
consideration of Your acceptance of these terms and conditions, and the
|
||||
Licensor grants You such rights in consideration of benefits the
|
||||
Licensor receives from making the Licensed Material available under
|
||||
these terms and conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. BY-NC-SA Compatible License means a license listed at
|
||||
creativecommons.org/compatiblelicenses, approved by Creative
|
||||
Commons as essentially the equivalent of this Public License.
|
||||
|
||||
d. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
e. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
g. License Elements means the license attributes listed in the name
|
||||
of a Creative Commons Public License. The License Elements of this
|
||||
Public License are Attribution, NonCommercial, and ShareAlike.
|
||||
|
||||
h. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
i. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
j. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
k. NonCommercial means not primarily intended for or directed towards
|
||||
commercial advantage or monetary compensation. For purposes of
|
||||
this Public License, the exchange of the Licensed Material for
|
||||
other material subject to Copyright and Similar Rights by digital
|
||||
file-sharing or similar means is NonCommercial provided there is
|
||||
no payment of monetary compensation in connection with the
|
||||
exchange.
|
||||
|
||||
l. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
m. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
n. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part, for NonCommercial purposes only; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material for
|
||||
NonCommercial purposes only.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. Additional offer from the Licensor -- Adapted Material.
|
||||
Every recipient of Adapted Material from You
|
||||
automatically receives an offer from the Licensor to
|
||||
exercise the Licensed Rights in the Adapted Material
|
||||
under the conditions of the Adapter's License You apply.
|
||||
|
||||
c. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties, including when
|
||||
the Licensed Material is used other than for NonCommercial
|
||||
purposes.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
b. ShareAlike.
|
||||
|
||||
In addition to the conditions in Section 3(a), if You Share
|
||||
Adapted Material You produce, the following conditions also apply.
|
||||
|
||||
1. The Adapter's License You apply must be a Creative Commons
|
||||
license with the same License Elements, this version or
|
||||
later, or a BY-NC-SA Compatible License.
|
||||
|
||||
2. You must include the text of, or the URI or hyperlink to, the
|
||||
Adapter's License You apply. You may satisfy this condition
|
||||
in any reasonable manner based on the medium, means, and
|
||||
context in which You Share Adapted Material.
|
||||
|
||||
3. You may not offer or impose any additional or different terms
|
||||
or conditions on, or apply any Effective Technological
|
||||
Measures to, Adapted Material that restrict exercise of the
|
||||
rights granted under the Adapter's License You apply.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database for NonCommercial purposes
|
||||
only;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material,
|
||||
including for purposes of Section 3(b); and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public
|
||||
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||
its public licenses to material it publishes and in those instances
|
||||
will be considered the “Licensor.” The text of the Creative Commons
|
||||
public licenses is dedicated to the public domain under the CC0 Public
|
||||
Domain Dedication. Except for the limited purpose of indicating that
|
||||
material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the
|
||||
public licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
||||
@@ -1,15 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_12">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/settings" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.javalin:javalin:3.4.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.31" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.3.31" level="project" />
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.chameleonvision;
|
||||
|
||||
import com.chameleonvision.classabstraction.VisionManager;
|
||||
import com.chameleonvision.classabstraction.config.ConfigManager;
|
||||
import com.chameleonvision.network.NetworkManager;
|
||||
import com.chameleonvision.settings.GeneralSettings;
|
||||
import com.chameleonvision.settings.Platform;
|
||||
import com.chameleonvision.settings.SettingsManager;
|
||||
import com.chameleonvision.util.Utilities;
|
||||
@@ -134,34 +136,40 @@ public class Main {
|
||||
}
|
||||
|
||||
if (testMode) {
|
||||
ConfigManager.initializeSettings();
|
||||
NetworkManager.initialize(manageNetwork);
|
||||
NetworkTableInstance.getDefault().startServer();
|
||||
|
||||
boolean visionSourcesOk = VisionManager.initializeSources();
|
||||
if (!visionSourcesOk) {
|
||||
System.out.println("No cameras connected!");
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkManager.initialize(manageNetwork);
|
||||
|
||||
boolean visionProcessesOk = VisionManager.initializeProcesses();
|
||||
if (!visionProcessesOk) {
|
||||
System.err.println("shit");
|
||||
return;
|
||||
}
|
||||
|
||||
runServer();
|
||||
VisionManager.startProcesses();
|
||||
|
||||
// runServer(true);
|
||||
} else {
|
||||
if (CameraManager.initializeCameras()) {
|
||||
SettingsManager.initialize();
|
||||
NetworkManager.initialize(manageNetwork);
|
||||
CameraManager.initializeThreads();
|
||||
runServer();
|
||||
runServer(false);
|
||||
} else {
|
||||
System.err.println("No cameras connected!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void runServer() {
|
||||
private static void runServer(boolean test) {
|
||||
GeneralSettings settings = test ? ConfigManager.settings : SettingsManager.generalSettings;
|
||||
|
||||
if (ntServerMode) {
|
||||
System.out.println("Starting NT Server");
|
||||
NetworkTableInstance.getDefault().startServer();
|
||||
@@ -170,7 +178,7 @@ public class Main {
|
||||
if (ntClientModeServer != null) {
|
||||
NetworkTableInstance.getDefault().startClient(ntClientModeServer);
|
||||
} else {
|
||||
NetworkTableInstance.getDefault().startClientTeam(SettingsManager.generalSettings.teamNumber);
|
||||
NetworkTableInstance.getDefault().startClientTeam(settings.teamNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.chameleonvision.classabstraction;
|
||||
import com.chameleonvision.classabstraction.camera.USBCameraProcess;
|
||||
import com.chameleonvision.classabstraction.config.CameraConfig;
|
||||
import com.chameleonvision.classabstraction.config.ConfigManager;
|
||||
import com.chameleonvision.settings.Platform;
|
||||
import com.chameleonvision.settings.SettingsManager;
|
||||
import com.chameleonvision.util.FileHelper;
|
||||
import edu.wpi.cscore.UsbCamera;
|
||||
@@ -11,9 +12,7 @@ import org.opencv.videoio.VideoCapture;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class VisionManager {
|
||||
|
||||
@@ -22,6 +21,7 @@ public class VisionManager {
|
||||
private static final Path CamConfigPath = Paths.get(SettingsManager.SettingsPath.toString(), "cameras");
|
||||
|
||||
public static final LinkedHashMap<String, UsbCameraInfo> UsbCameraInfosByCameraName = new LinkedHashMap<>();
|
||||
private static final LinkedList<CameraConfig> LoadedCameraConfigs = new LinkedList<>();
|
||||
public static final LinkedHashMap<String, VisionProcess> VisionProcessesByCameraName = new LinkedHashMap<>();
|
||||
|
||||
public static boolean initializeSources() {
|
||||
@@ -46,70 +46,41 @@ public class VisionManager {
|
||||
FileHelper.CheckPath(CamConfigPath);
|
||||
|
||||
// load the config
|
||||
List<CameraConfig> loadedConfigs = ConfigManager.initializeCameraConfig(new ArrayList<>(UsbCameraInfosByCameraName.keySet()));
|
||||
loadedConfigs.forEach(config -> {
|
||||
var camera = new USBCameraProcess(
|
||||
new edu.wpi.cscore.UsbCamera(config.name, config.path),
|
||||
config
|
||||
);
|
||||
VisionProcessesByCameraName.put(config.name, new VisionProcess(camera, config.name));
|
||||
List<CameraConfig> preliminaryConfigs = new ArrayList<>();
|
||||
|
||||
UsbCameraInfosByCameraName.values().forEach((cameraInfo) -> {
|
||||
String truePath;
|
||||
|
||||
if (Platform.CurrentPlatform.isWindows()) {
|
||||
truePath = cameraInfo.path;
|
||||
} else {
|
||||
truePath = Arrays.stream(cameraInfo.otherPaths).filter(x -> x.contains("/dev/v4l/by-path")).findFirst().orElse(cameraInfo.path);
|
||||
}
|
||||
|
||||
preliminaryConfigs.add(new CameraConfig(truePath, cameraInfo.name));
|
||||
});
|
||||
|
||||
|
||||
LoadedCameraConfigs.addAll(ConfigManager.initializeCameraConfig(preliminaryConfigs));
|
||||
// UsbCameraInfosByCameraName.forEach((cameraName, cameraInfo) -> {
|
||||
// Path cameraConfigFolder = Paths.get(CamConfigPath.toString(), String.format("%s\\", cameraName));
|
||||
// Path cameraConfigPath = Paths.get(cameraConfigFolder.toString(), String.format("%s.json", cameraName));
|
||||
// Path cameraPipelinesPath = Paths.get(cameraConfigFolder.toString(), "pipelines.json");
|
||||
// Path cameraDrivermodePath = Paths.get(cameraConfigFolder.toString(), "drivermode.json");
|
||||
//
|
||||
// try {
|
||||
//
|
||||
// boolean cameraFolderExists = Files.exists(cameraConfigFolder);
|
||||
//
|
||||
// if (!cameraFolderExists) {
|
||||
// Files.createDirectory(cameraConfigFolder);
|
||||
// }
|
||||
// boolean cameraConfigExists = cameraFolderExists && Files.exists(cameraConfigPath);
|
||||
//
|
||||
// if (Files.exists(cameraConfigFolder)) {
|
||||
// if (Files.exists(cameraConfigPath)) {
|
||||
// File cameraConfigFile = new File(cameraConfigPath.toString());
|
||||
// if (cameraConfigFile.length() != 0) {
|
||||
// try {
|
||||
// Gson gson = new GsonBuilder().create();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// Files.createFile(cameraConfigPath);
|
||||
// }
|
||||
// } else {
|
||||
// Files.createDirectory(cameraConfigFolder);
|
||||
// }
|
||||
// } catch (IOException ex) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// });
|
||||
|
||||
// FileHelper.CheckPath(CamConfigPath);
|
||||
// UsbCameraInfosByCameraName.forEach((cameraName, cameraInfo) -> {
|
||||
// Path cameraConfigPath = Paths.get(CamConfigPath.toString(), String.format("%s.json", cameraName));
|
||||
// File cameraConfigFile = new File(cameraConfigPath.toString());
|
||||
// if (cameraConfigFile.exists() && cameraConfigFile.length() != 0) {
|
||||
//// try {
|
||||
//// Gson gson = new GsonBuilder().registerTypeAdapter(USBCameraProcess.class, new CameraDeserializer());
|
||||
//// }
|
||||
// }
|
||||
// })
|
||||
// TODO: implement new camera JSON loads
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean initializeProcesses() {
|
||||
|
||||
LoadedCameraConfigs.forEach(config -> {
|
||||
var camera = new USBCameraProcess(config);
|
||||
VisionProcessesByCameraName.put(config.name, new VisionProcess(camera, config.name));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void startProcesses() {
|
||||
VisionProcessesByCameraName.forEach((name, process) -> {
|
||||
process.start();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,17 +34,29 @@ public class VisionProcess {
|
||||
// Thread to grab frames from the camera
|
||||
// TODO: fix video modes!!!
|
||||
this.cameraRunnable = new CameraFrameRunnable(cameraProcess.getProperties().videoModes.get(0).fps);
|
||||
new Thread(cameraRunnable).start();
|
||||
|
||||
// Thread to put frames on the dashboard
|
||||
this.cameraStreamer = new CameraStreamer(cameraProcess, name);
|
||||
this.streamRunnable = new CameraStreamerRunnable(1000L/32, cameraStreamer);
|
||||
new Thread(streamRunnable).start();
|
||||
|
||||
// Thread to process vision data
|
||||
this.visionRunnable = new VisionProcessRunnable();
|
||||
new Thread(visionRunnable).start();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
System.out.println("Starting camera thread.");
|
||||
new Thread(cameraRunnable).start();
|
||||
while (cameraRunnable.cameraFrame == null) {
|
||||
try {
|
||||
if (cameraRunnable.cameraFrame.cols() > 0) break;
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
System.out.println("Starting vision thread.");
|
||||
new Thread(visionRunnable).start();
|
||||
System.out.println("Starting stream thread.");
|
||||
new Thread(streamRunnable).start();
|
||||
}
|
||||
|
||||
public void setPipeline(int pipelineIndex) {
|
||||
@@ -73,7 +85,7 @@ public class VisionProcess {
|
||||
* at a specified loopTime
|
||||
*/
|
||||
protected class CameraFrameRunnable extends LoopingRunnable {
|
||||
private Mat cameraFrame = new Mat();
|
||||
private Mat cameraFrame;
|
||||
private long timestampMicros;
|
||||
|
||||
private final Object frameLock = new Object();
|
||||
@@ -95,18 +107,23 @@ public class VisionProcess {
|
||||
|
||||
// Grab camera frames
|
||||
var camData = cameraProcess.getFrame();
|
||||
synchronized (frameLock) {
|
||||
cameraFrame = camData.getLeft();
|
||||
if (camData.getLeft().cols() > 0) {
|
||||
// System.out.println("grabbing frame");
|
||||
// synchronized (frameLock) {
|
||||
cameraFrame = camData.getLeft();
|
||||
// }
|
||||
timestampMicros = camData.getRight();
|
||||
}
|
||||
timestampMicros = camData.getRight();
|
||||
}
|
||||
}
|
||||
|
||||
public Mat getFrame(Mat dst) {
|
||||
synchronized (frameLock) {
|
||||
cameraFrame.copyTo(dst);
|
||||
return dst;
|
||||
if (cameraFrame != null) {
|
||||
dst = cameraFrame;
|
||||
} else {
|
||||
System.out.println("no frame");
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
public long getTimestampMicros() {
|
||||
@@ -125,7 +142,12 @@ public class VisionProcess {
|
||||
@Override
|
||||
public void run() {
|
||||
while(!Thread.interrupted()) {
|
||||
result = currentPipeline.runPipeline(cameraRunnable.getFrame(streamBuffer));
|
||||
streamBuffer = cameraRunnable.getFrame(streamBuffer);
|
||||
if (streamBuffer.cols() > 0 && streamBuffer.rows() > 0) {
|
||||
result = currentPipeline.runPipeline(streamBuffer);
|
||||
} else {
|
||||
// System.err.println("Bad streambuffer mat");
|
||||
}
|
||||
// TODO do something with the result
|
||||
}
|
||||
}
|
||||
@@ -143,7 +165,16 @@ public class VisionProcess {
|
||||
|
||||
@Override
|
||||
protected void process() {
|
||||
streamer.runStream(cameraRunnable.getFrame(streamBuffer));
|
||||
CVPipelineResult latestResult = visionRunnable.result;
|
||||
if (latestResult != null) {
|
||||
Mat toStreamMat = visionRunnable.result.outputMat;
|
||||
streamBuffer = toStreamMat;
|
||||
streamer.runStream(toStreamMat);
|
||||
// if (toStreamMat != null && toStreamMat.cols() > 0) {
|
||||
// } else {
|
||||
// System.out.println("fuuuuck");
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package com.chameleonvision.classabstraction.camera;
|
||||
|
||||
import com.chameleonvision.Main;
|
||||
import com.chameleonvision.classabstraction.config.CameraConfig;
|
||||
import com.chameleonvision.settings.Platform;
|
||||
import com.chameleonvision.vision.camera.USBCamera;
|
||||
import edu.wpi.cscore.UsbCamera;
|
||||
import edu.wpi.cscore.UsbCameraInfo;
|
||||
import edu.wpi.cscore.VideoMode;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
@@ -16,7 +13,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class CameraProperties {
|
||||
private static final double DEFAULT_FOV = 70;
|
||||
public static final double DEFAULT_FOV = 70;
|
||||
private static final int DEFAULT_EXPOSURE = 50;
|
||||
private static final int DEFAULT_BRIGHTNESS = 50;
|
||||
private static final int MINIMUM_FPS = 30;
|
||||
@@ -61,8 +58,16 @@ public class CameraProperties {
|
||||
System.out.printf("USBCameraProcess initialized in %.2fms\n", initTimeMs);
|
||||
}
|
||||
|
||||
// TODO: find way to determine if camera is a PS3Eye
|
||||
hasGain = false;
|
||||
var props = baseCamera.enumerateProperties();
|
||||
// var props = baseCamera.enumerateProperties();
|
||||
// for (var prop : props) {
|
||||
// var name = prop.getName();
|
||||
// var min = prop.getMin();
|
||||
// var max = prop.getMax();
|
||||
// var _default = prop.getDefault();
|
||||
// var kind = prop.getKind();
|
||||
// }
|
||||
|
||||
videoModes = filterVideoModes(baseCamera.enumerateVideoModes());
|
||||
}
|
||||
@@ -85,12 +90,12 @@ public class CameraProperties {
|
||||
staticProperties = new CameraStaticProperties(videoMode.width, videoMode.height, FOV);
|
||||
}
|
||||
|
||||
public double CalculatePitch(double PixelY, double centerY) {
|
||||
public double calculatePitch(double PixelY, double centerY) {
|
||||
double pitch = FastMath.toDegrees(FastMath.atan((PixelY - centerY) / staticProperties.verticalFocalLength));
|
||||
return (pitch * -1);
|
||||
}
|
||||
|
||||
public double CalculateYaw(double PixelX, double centerX) {
|
||||
public double calculateYaw(double PixelX, double centerX) {
|
||||
return FastMath.toDegrees(FastMath.atan((PixelX - centerX) / staticProperties.horizontalFocalLength));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
package com.chameleonvision.classabstraction.camera;
|
||||
|
||||
import com.chameleonvision.vision.camera.StreamDivisor;
|
||||
import com.chameleonvision.web.ServerHandler;
|
||||
import edu.wpi.cscore.CvSource;
|
||||
import edu.wpi.cscore.VideoMode;
|
||||
import edu.wpi.first.cameraserver.CameraServer;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
public class CameraStreamer {
|
||||
private final CameraProcess cameraProcess;
|
||||
@@ -24,6 +21,7 @@ public class CameraStreamer {
|
||||
this.cvSource = CameraServer.getInstance().putVideo(name,
|
||||
cameraProcess.getProperties().staticProperties.imageWidth / divisor.value,
|
||||
cameraProcess.getProperties().staticProperties.imageHeight / divisor.value);
|
||||
setDivisor(divisor);
|
||||
}
|
||||
|
||||
public void setDivisor(StreamDivisor newDivisor) {
|
||||
@@ -37,7 +35,7 @@ public class CameraStreamer {
|
||||
cameraProcess.getProperties().staticProperties.imageWidth / divisor.value,
|
||||
cameraProcess.getProperties().staticProperties.imageHeight / divisor.value);
|
||||
}
|
||||
ServerHandler.sendFullSettings();
|
||||
// ServerHandler.sendFullSettings();
|
||||
}
|
||||
|
||||
public void setNewVideoMode(VideoMode newVideoMode) {
|
||||
@@ -47,14 +45,16 @@ public class CameraStreamer {
|
||||
}
|
||||
|
||||
public void runStream(Mat image) {
|
||||
image.copyTo(streamBuffer);
|
||||
if (divisor.value != 1) {
|
||||
var camVal = cameraProcess.getProperties().staticProperties;
|
||||
var newWidth = camVal.imageWidth / divisor.value;
|
||||
var newHeight = camVal.imageHeight / divisor.value;
|
||||
Size newSize = new Size(newWidth, newHeight);
|
||||
Imgproc.resize(streamBuffer, streamBuffer, newSize);
|
||||
synchronized (streamBufferLock) {
|
||||
streamBuffer = image;
|
||||
}
|
||||
// if (divisor.value != 1) {
|
||||
// var camVal = cameraProcess.getProperties().staticProperties;
|
||||
// var newWidth = camVal.imageWidth / divisor.value;
|
||||
// var newHeight = camVal.imageHeight / divisor.value;
|
||||
// Size newSize = new Size(newWidth, newHeight);
|
||||
// Imgproc.resize(streamBuffer, streamBuffer, newSize);
|
||||
// }
|
||||
cvSource.putFrame(streamBuffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,10 @@ public class USBCameraProcess implements CameraProcess {
|
||||
private Mat imageBuffer = new Mat();
|
||||
private CameraProperties properties;
|
||||
|
||||
public USBCameraProcess(UsbCamera camera, CameraConfig config) {
|
||||
baseCamera = camera;
|
||||
|
||||
public USBCameraProcess(CameraConfig config) {
|
||||
baseCamera = new UsbCamera(config.name, config.path);
|
||||
cvSink = CameraServer.getInstance().getVideo(baseCamera);
|
||||
properties = new CameraProperties(baseCamera, config.fov);
|
||||
properties = new CameraProperties(baseCamera, config);
|
||||
|
||||
setVideoMode(properties.videoModes.get(0));
|
||||
}
|
||||
|
||||
@@ -1,17 +1,31 @@
|
||||
package com.chameleonvision.classabstraction.config;
|
||||
|
||||
import com.chameleonvision.classabstraction.camera.CameraProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class CameraConfig {
|
||||
public final double fov;
|
||||
public final String path;
|
||||
public final String name;
|
||||
public final String nickname;
|
||||
|
||||
public CameraConfig(double FOV,
|
||||
String path, String name,
|
||||
String nickname) {
|
||||
this.fov = FOV;
|
||||
@JsonCreator
|
||||
public CameraConfig(
|
||||
@JsonProperty("fov") double fov,
|
||||
@JsonProperty("path") String path,
|
||||
@JsonProperty("name") String name,
|
||||
@JsonProperty("nickname") String nickname) {
|
||||
this.fov = fov;
|
||||
this.path = path;
|
||||
this.name = name;
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public CameraConfig(String path, String name) {
|
||||
this.fov = CameraProperties.DEFAULT_FOV;
|
||||
this.path = path;
|
||||
this.name = name;
|
||||
this.nickname = name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,37 +2,25 @@ package com.chameleonvision.classabstraction.config;
|
||||
|
||||
import com.chameleonvision.classabstraction.util.ProgramDirectoryUtilities;
|
||||
import com.chameleonvision.settings.GeneralSettings;
|
||||
import com.chameleonvision.settings.SettingsManager;
|
||||
import com.chameleonvision.util.FileHelper;
|
||||
import com.chameleonvision.vision.camera.CameraDeserializer;
|
||||
import com.chameleonvision.vision.camera.USBCamera;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ConfigManager {
|
||||
private ConfigManager() {}
|
||||
|
||||
private static final Path SettingsPath = Paths.get(ProgramDirectoryUtilities.getProgramDirectory(), "settings");
|
||||
private static final Path cameraConfigPath = Paths.get(ProgramDirectoryUtilities.getProgramDirectory(), "cameras");
|
||||
private static final Path cameraConfigPath = Paths.get(SettingsPath.toString(), "cameras");
|
||||
|
||||
public static GeneralSettings settings = new GeneralSettings();
|
||||
|
||||
public static void initializeSettings() {
|
||||
boolean settingsFolderExists = Files.exists(SettingsPath);
|
||||
|
||||
if (!settingsFolderExists) {
|
||||
if (Files.notExists(SettingsPath)) {
|
||||
try {
|
||||
Files.createDirectory(SettingsPath);
|
||||
} catch (IOException e) {
|
||||
@@ -42,11 +30,10 @@ public class ConfigManager {
|
||||
|
||||
// try to load the settings file and deserialize it
|
||||
Path settingsFilePath = Paths.get(SettingsPath.toString(), "settings.json");
|
||||
boolean settingsFileExists = Files.exists(settingsFilePath);
|
||||
|
||||
if (!settingsFileExists) {
|
||||
if (Files.notExists(settingsFilePath)) {
|
||||
try {
|
||||
FileHelper.Serializer(settings, settingsFilePath);
|
||||
FileHelper.Serializer(settingsFilePath, settings);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -57,53 +44,41 @@ public class ConfigManager {
|
||||
System.err.println("Failed to load settings.json, using defaults.");
|
||||
}
|
||||
}
|
||||
|
||||
// try to load camera file and deserialize it
|
||||
// var cameraConfigs = initializeCameraConfig();
|
||||
|
||||
}
|
||||
|
||||
public static List<CameraConfig> initializeCameraConfig(List<String> cameraNames) {
|
||||
|
||||
public static List<CameraConfig> initializeCameraConfig(List<CameraConfig> preliminaryConfigs) {
|
||||
var configList = new ArrayList<CameraConfig>();
|
||||
|
||||
|
||||
// loop over all the camera names and try to create settings folders for it
|
||||
cameraNames.forEach((cameraName) -> {
|
||||
final Path cameraConfigFolder = Paths.get(cameraConfigPath.toString(), String.format("%s\\", cameraName));
|
||||
final Path cameraConfigPath = Paths.get(cameraConfigFolder.toString(), String.format("%s.json", cameraName));
|
||||
preliminaryConfigs.forEach((preliminaryConfig) -> {
|
||||
|
||||
final Path cameraConfigFolderPath = Paths.get(cameraConfigPath.toString(), String.format("%s\\", preliminaryConfig.name));
|
||||
final Path cameraConfigPath = Paths.get(cameraConfigFolderPath.toString(), "camera.json");
|
||||
|
||||
// check if the config folder exists, and if not, create it
|
||||
boolean cameraConfigFolderExists = Files.exists(cameraConfigFolder);
|
||||
|
||||
if (!cameraConfigFolderExists) {
|
||||
if (Files.notExists(cameraConfigFolderPath)) {
|
||||
try {
|
||||
Files.createDirectory(cameraConfigFolder);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// try to deserialize the file
|
||||
var camJsonFile = new File(cameraConfigPath.toString());
|
||||
if(camJsonFile.exists() && camJsonFile.length() > 0) {
|
||||
try {
|
||||
var config = FileHelper.DeSerializer(cameraConfigPath, CameraConfig.class);
|
||||
configList.add(config);
|
||||
Files.createDirectory(cameraConfigFolderPath);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
// create a default one
|
||||
configList.add(new CameraConfig(
|
||||
70.0,
|
||||
cameraConfigPath.toString(),
|
||||
cameraName,
|
||||
cameraName
|
||||
));
|
||||
CameraConfig config = preliminaryConfig;
|
||||
if(!Files.exists(cameraConfigPath)) {
|
||||
try {
|
||||
FileHelper.Serializer(cameraConfigPath, preliminaryConfig);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
config = FileHelper.DeSerializer(cameraConfigPath, CameraConfig.class);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
configList.add(config);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
return configList;
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.util.function.Supplier;
|
||||
* @param <R> Pipeline result type
|
||||
*/
|
||||
public abstract class CVPipeline<R extends CVPipelineResult, S extends CVPipelineSettings> {
|
||||
protected Mat outputMat;
|
||||
protected Mat outputMat = new Mat();
|
||||
CameraProcess cameraProcess;
|
||||
final Supplier<S> settingsSupplier;
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
|
||||
var settings = settingsSupplier.get();
|
||||
CameraStaticProperties camProps = cameraProcess.getProperties().staticProperties;
|
||||
|
||||
inputMat.copyTo(rawCameraMat);
|
||||
rawCameraMat = inputMat;
|
||||
|
||||
// prepare pipes
|
||||
RotateFlipPipe rotateFlipPipe = new RotateFlipPipe(ImageRotation.DEG_0, settings.flipMode);
|
||||
|
||||
@@ -7,13 +7,13 @@ import java.util.List;
|
||||
public abstract class CVPipelineResult<T> {
|
||||
public final List<T> targets;
|
||||
public final boolean hasTarget;
|
||||
public final Mat outputMat = new Mat();
|
||||
public final Mat outputMat;
|
||||
public final long processTime;
|
||||
|
||||
public CVPipelineResult(List<T> targets, Mat outputMat, long processTime) {
|
||||
this.targets = targets;
|
||||
hasTarget = targets != null && !targets.isEmpty();
|
||||
outputMat.copyTo(this.outputMat);
|
||||
this.outputMat = outputMat;
|
||||
this.processTime = processTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package com.chameleonvision.classabstraction.pipeline;
|
||||
|
||||
import com.chameleonvision.classabstraction.camera.CameraProcess;
|
||||
import com.chameleonvision.classabstraction.pipeline.pipes.Draw2dContoursPipe;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.opencv.core.Mat;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.chameleonvision.classabstraction.pipeline.DriverVisionPipeline.*;
|
||||
import static com.chameleonvision.classabstraction.pipeline.DriverVisionPipeline.DriverPipelineResult;
|
||||
|
||||
public class DriverVisionPipeline extends CVPipeline<DriverPipelineResult, CVPipelineSettings> {
|
||||
|
||||
@@ -14,16 +15,18 @@ public class DriverVisionPipeline extends CVPipeline<DriverPipelineResult, CVPip
|
||||
super(settingsSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initPipeline(CameraProcess camera) {
|
||||
camera.setBrightness((int) getSettings().brightness);
|
||||
camera.setExposure((int) getSettings().exposure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DriverPipelineResult runPipeline(Mat inputMat) {
|
||||
|
||||
inputMat.copyTo(outputMat);
|
||||
outputMat = inputMat;
|
||||
|
||||
var camProps = cameraProcess.getProperties().staticProperties;
|
||||
|
||||
Draw2dContoursPipe.Draw2dContoursSettings draw2dContoursSettings = new Draw2dContoursPipe.Draw2dContoursSettings();
|
||||
draw2dContoursSettings.showCrosshair = true;
|
||||
Draw2dContoursPipe draw2dContoursPipe = new Draw2dContoursPipe(draw2dContoursSettings, camProps);
|
||||
|
||||
outputMat = draw2dContoursPipe.run(Pair.of(outputMat, null)).getLeft();
|
||||
|
||||
return new DriverPipelineResult(null, inputMat, 0);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.chameleonvision.classabstraction.pipeline.pipes;
|
||||
|
||||
import com.chameleonvision.classabstraction.camera.CameraStaticProperties;
|
||||
import com.chameleonvision.classabstraction.util.Helpers;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.opencv.core.*;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.core.*;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -26,37 +27,41 @@ public class Draw2dContoursPipe implements Pipe<Pair<Mat, List<RotatedRect>>, Ma
|
||||
public Pair<Mat, Long> run(Pair<Mat, List<RotatedRect>> input) {
|
||||
long processStartNanos = System.nanoTime();
|
||||
|
||||
input.getLeft().copyTo(outputMat);
|
||||
outputMat = input.getLeft();
|
||||
|
||||
for (RotatedRect r : input.getRight()) {
|
||||
if (r == null) continue;
|
||||
if (input.getRight() != null && !input.getRight().isEmpty()) {
|
||||
for (RotatedRect r : input.getRight()) {
|
||||
if (r == null) continue;
|
||||
|
||||
List<MatOfPoint> drawnContour = new ArrayList<>();
|
||||
Point[] vertices = new Point[4];
|
||||
r.points(vertices);
|
||||
MatOfPoint contour = new MatOfPoint(vertices);
|
||||
drawnContour.add(contour);
|
||||
List<MatOfPoint> drawnContour = new ArrayList<>();
|
||||
Point[] vertices = new Point[4];
|
||||
r.points(vertices);
|
||||
MatOfPoint contour = new MatOfPoint(vertices);
|
||||
drawnContour.add(contour);
|
||||
|
||||
if (settings.showCentroid) {
|
||||
Imgproc.circle(outputMat, r.center, 3, colorToScalar(settings.centroidColor));
|
||||
if (settings.showCentroid) {
|
||||
Imgproc.circle(outputMat, r.center, 3, Helpers.colorToScalar(settings.centroidColor));
|
||||
}
|
||||
|
||||
if (settings.showRotatedBox) {
|
||||
Imgproc.drawContours(outputMat, drawnContour, 0, Helpers.colorToScalar(settings.rotatedBoxColor), settings.boxOutlineSize);
|
||||
}
|
||||
|
||||
if (settings.showMaximumBox) {
|
||||
Rect box = Imgproc.boundingRect(contour);
|
||||
Imgproc.rectangle(outputMat, new Point(box.x, box.y), new Point((box.x + box.width), (box.y + box.height)), Helpers.colorToScalar(settings.maximumBoxColor), settings.boxOutlineSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.showCrosshair) {
|
||||
Point xMax = new Point(camProps.centerX + 10, camProps.centerY);
|
||||
Point xMin = new Point(camProps.centerX - 10, camProps.centerY);
|
||||
Point yMax = new Point(camProps.centerX, camProps.centerY + 10);
|
||||
Point yMin = new Point(camProps.centerX, camProps.centerY - 10);
|
||||
Imgproc.line(outputMat, xMax, xMin, colorToScalar(settings.crosshairColor), 2);
|
||||
Imgproc.line(outputMat, yMax, yMin, colorToScalar(settings.crosshairColor), 2);
|
||||
}
|
||||
|
||||
if (settings.showRotatedBox) {
|
||||
Imgproc.drawContours(outputMat, drawnContour, 0, colorToScalar(settings.rotatedBoxColor), settings.boxOutlineSize);
|
||||
}
|
||||
|
||||
if (settings.showMaximumBox) {
|
||||
Rect box = Imgproc.boundingRect(contour);
|
||||
Imgproc.rectangle(outputMat, new Point(box.x, box.y), new Point((box.x + box.width), (box.y + box.height)), colorToScalar(settings.maximumBoxColor), settings.boxOutlineSize);
|
||||
if (settings.showCrosshair) {
|
||||
Point xMax = new Point(camProps.centerX + 10, camProps.centerY);
|
||||
Point xMin = new Point(camProps.centerX - 10, camProps.centerY);
|
||||
Point yMax = new Point(camProps.centerX, camProps.centerY + 10);
|
||||
Point yMin = new Point(camProps.centerX, camProps.centerY - 10);
|
||||
if (outputMat != null && outputMat.cols() > 0) {
|
||||
Imgproc.line(outputMat, xMax, xMin, Helpers.colorToScalar(settings.crosshairColor), 2);
|
||||
Imgproc.line(outputMat, yMax, yMin, Helpers.colorToScalar(settings.crosshairColor), 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,10 +71,6 @@ public class Draw2dContoursPipe implements Pipe<Pair<Mat, List<RotatedRect>>, Ma
|
||||
return output;
|
||||
}
|
||||
|
||||
private Scalar colorToScalar(Color color) {
|
||||
return new Scalar(color.getRed(), color.getGreen(), color.getBlue());
|
||||
}
|
||||
|
||||
public static class Draw2dContoursSettings {
|
||||
public boolean showCentroid = false;
|
||||
public boolean showCrosshair = false;
|
||||
@@ -80,6 +81,5 @@ public class Draw2dContoursPipe implements Pipe<Pair<Mat, List<RotatedRect>>, Ma
|
||||
public Color crosshairColor = Color.GREEN;
|
||||
public Color rotatedBoxColor = Color.BLUE;
|
||||
public Color maximumBoxColor = Color.RED;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,7 @@ public class OutputMatPipe implements Pipe<Pair<Mat, Mat>, Mat> {
|
||||
public Pair<Mat, Long> run(Pair<Mat, Mat> input) {
|
||||
long processStartNanos = System.nanoTime();
|
||||
|
||||
if (showThresholded) {
|
||||
input.getRight().copyTo(outputMat);
|
||||
} else {
|
||||
input.getLeft().copyTo(outputMat);
|
||||
}
|
||||
outputMat = showThresholded ? input.getRight() : input.getLeft();
|
||||
|
||||
long processTime = processStartNanos - System.nanoTime();
|
||||
Pair<Mat, Long> output = Pair.of(outputMat, processTime);
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.chameleonvision.classabstraction.util;
|
||||
|
||||
import org.opencv.core.Scalar;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class Helpers {
|
||||
private Helpers() {}
|
||||
|
||||
public static Scalar colorToScalar(Color color) {
|
||||
return new Scalar(color.getRed(), color.getGreen(), color.getBlue());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,7 +27,8 @@ public class ProgramDirectoryUtilities
|
||||
return getCurrentJARDirectory();
|
||||
} else
|
||||
{
|
||||
return getCurrentProjectDirectory();
|
||||
return System.getProperty("user.dir");
|
||||
// return getCurrentProjectDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@ import java.net.SocketException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.chameleonvision.settings.Platform.CurrentPlatform;
|
||||
|
||||
public class NetworkManager {
|
||||
private NetworkManager() {}
|
||||
|
||||
@@ -22,9 +20,11 @@ public class NetworkManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CurrentPlatform.isLinux()) {
|
||||
Platform platform = Platform.getCurrentPlatform();
|
||||
|
||||
if (platform.isLinux()) {
|
||||
networking = new LinuxNetworking();
|
||||
} else if (CurrentPlatform.isWindows()) {
|
||||
} else if (platform.isWindows()) {
|
||||
// networking = new WindowsNetworking();
|
||||
System.out.println("Windows networking is not yet supported. Running unmanaged.");
|
||||
return;
|
||||
|
||||
@@ -28,15 +28,20 @@ public class FileHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static void Serializer(Object object, Path path) throws IOException {
|
||||
public static void Serializer(Path path, Object object) throws IOException {
|
||||
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfBaseType(Object.class).build();
|
||||
ObjectMapper objectMapper = JsonMapper.builder().activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT).build();
|
||||
objectMapper.writeValue(new File(path.toString()), object);
|
||||
objectMapper.writerWithDefaultPrettyPrinter().writeValue(new File(path.toString()), object);
|
||||
}
|
||||
|
||||
public static <T> T DeSerializer(Path path, Class<T> ref) throws IOException {
|
||||
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfBaseType(Object.class).build();
|
||||
ObjectMapper objectMapper = JsonMapper.builder().activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT).build();
|
||||
return objectMapper.readValue(new File(path.toString()), ref);
|
||||
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfBaseType(ref).build();
|
||||
ObjectMapper objectMapper = JsonMapper.builder().activateDefaultTyping(ptv).build();
|
||||
File jsonFile = new File(path.toString());
|
||||
if (jsonFile.exists() && jsonFile.length() > 0) {
|
||||
T readObject = objectMapper.readValue(jsonFile, ref);
|
||||
return readObject;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Chameleon-Vision
|
||||
|
||||

|
||||

|
||||
|
||||
Chameleon Vision is free open-source software for FRC teams to use for vision proccesing on their robots.
|
||||
|
||||
## Getting started
|
||||
|
||||
Reference in New Issue
Block a user