Change SBC to Jetson Orin
This commit is contained in:
2
.idea/inspectionProfiles/Project_Default.xml
generated
2
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -4,6 +4,7 @@
|
|||||||
<inspection_tool class="ExtractMethodRecommender" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="ExtractMethodRecommender" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="minLength" value="745" />
|
<option name="minLength" value="745" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
|
<inspection_tool class="GrazieInspection" enabled="false" level="GRAMMAR_ERROR" enabled_by_default="false" />
|
||||||
<inspection_tool class="HttpUrlsUsage" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
<inspection_tool class="HttpUrlsUsage" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
<option name="ignoredUrls">
|
<option name="ignoredUrls">
|
||||||
<list>
|
<list>
|
||||||
@@ -35,6 +36,7 @@
|
|||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
|
<inspection_tool class="LanguageDetectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="MethodNameSameAsClassName" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="MethodNameSameAsClassName" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="RedundantCast" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="RedundantCast" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||||
|
|||||||
@@ -134,8 +134,8 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<a>
|
<a onmousedown="send_stop_movement()">
|
||||||
<i id="btn_center" class="btn-nav-center fa-solid fa-circle"></i>
|
<i id="btn_center" class="btn-nav-center fa-solid fa-circle" title="Stop Movement"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
|||||||
80
onnx/coco.names
Normal file
80
onnx/coco.names
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
person
|
||||||
|
bicycle
|
||||||
|
car
|
||||||
|
motorbike
|
||||||
|
aeroplane
|
||||||
|
bus
|
||||||
|
train
|
||||||
|
truck
|
||||||
|
boat
|
||||||
|
traffic light
|
||||||
|
fire hydrant
|
||||||
|
stop sign
|
||||||
|
parking meter
|
||||||
|
bench
|
||||||
|
bird
|
||||||
|
cat
|
||||||
|
dog
|
||||||
|
horse
|
||||||
|
sheep
|
||||||
|
cow
|
||||||
|
elephant
|
||||||
|
bear
|
||||||
|
zebra
|
||||||
|
giraffe
|
||||||
|
backpack
|
||||||
|
umbrella
|
||||||
|
handbag
|
||||||
|
tie
|
||||||
|
suitcase
|
||||||
|
frisbee
|
||||||
|
skis
|
||||||
|
snowboard
|
||||||
|
sports ball
|
||||||
|
kite
|
||||||
|
baseball bat
|
||||||
|
baseball glove
|
||||||
|
skateboard
|
||||||
|
surfboard
|
||||||
|
tennis racket
|
||||||
|
bottle
|
||||||
|
wine glass
|
||||||
|
cup
|
||||||
|
fork
|
||||||
|
knife
|
||||||
|
spoon
|
||||||
|
bowl
|
||||||
|
banana
|
||||||
|
apple
|
||||||
|
sandwich
|
||||||
|
orange
|
||||||
|
broccoli
|
||||||
|
carrot
|
||||||
|
hot dog
|
||||||
|
pizza
|
||||||
|
donut
|
||||||
|
cake
|
||||||
|
chair
|
||||||
|
sofa
|
||||||
|
pottedplant
|
||||||
|
bed
|
||||||
|
diningtable
|
||||||
|
toilet
|
||||||
|
tvmonitor
|
||||||
|
laptop
|
||||||
|
mouse
|
||||||
|
remote
|
||||||
|
keyboard
|
||||||
|
cell phone
|
||||||
|
microwave
|
||||||
|
oven
|
||||||
|
toaster
|
||||||
|
sink
|
||||||
|
refrigerator
|
||||||
|
book
|
||||||
|
clock
|
||||||
|
vase
|
||||||
|
scissors
|
||||||
|
teddy bear
|
||||||
|
hair drier
|
||||||
|
toothbrush
|
||||||
BIN
onnx/yolov8n.onnx
Normal file
BIN
onnx/yolov8n.onnx
Normal file
Binary file not shown.
26
pom.xml
26
pom.xml
@@ -178,32 +178,6 @@
|
|||||||
<version>5.1.2-1.5.8</version>
|
<version>5.1.2-1.5.8</version>
|
||||||
<classifier>linux-arm64</classifier>
|
<classifier>linux-arm64</classifier>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- manual tambah untuk platform linux-x86_64
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bytedeco</groupId>
|
|
||||||
<artifactId>opencv</artifactId>
|
|
||||||
<version>4.9.0-1.5.10</version>
|
|
||||||
<classifier>linux-x86_64</classifier>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bytedeco</groupId>
|
|
||||||
<artifactId>javacpp</artifactId>
|
|
||||||
<version>1.5.10</version>
|
|
||||||
<classifier>linux-x86_64</classifier>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bytedeco</groupId>
|
|
||||||
<artifactId>openblas</artifactId>
|
|
||||||
<version>0.3.26-1.5.10</version>
|
|
||||||
<classifier>linux-x86_64</classifier>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bytedeco</groupId>
|
|
||||||
<artifactId>ffmpeg</artifactId>
|
|
||||||
<version>6.1.1-1.5.10</version>
|
|
||||||
<classifier>linux-x86_64</classifier>
|
|
||||||
</dependency>
|
|
||||||
-->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.corundumstudio.socketio</groupId>
|
<groupId>com.corundumstudio.socketio</groupId>
|
||||||
<artifactId>netty-socketio</artifactId>
|
<artifactId>netty-socketio</artifactId>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.bytedeco.javacv.Frame;
|
import org.bytedeco.javacv.Frame;
|
||||||
import org.bytedeco.javacv.FrameGrabber;
|
import org.bytedeco.javacv.FrameGrabber;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Mat;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
public class GrabbingTask implements Runnable {
|
public class GrabbingTask implements Runnable {
|
||||||
@@ -23,6 +24,8 @@ public class GrabbingTask implements Runnable {
|
|||||||
@Setter private Consumer<Frame> onLQFrameUpdate;
|
@Setter private Consumer<Frame> onLQFrameUpdate;
|
||||||
@Setter private Consumer<String> onHQBase64Update;
|
@Setter private Consumer<String> onHQBase64Update;
|
||||||
@Setter private Consumer<String> onLQBase64Update;
|
@Setter private Consumer<String> onLQBase64Update;
|
||||||
|
@Setter private Consumer<Frame> onYoloUpdate;
|
||||||
|
@Setter private Consumer<String> onYoloBase64Update;
|
||||||
|
|
||||||
// status of capture fps
|
// status of capture fps
|
||||||
@Getter private int CaptureFPS = 0;
|
@Getter private int CaptureFPS = 0;
|
||||||
@@ -33,6 +36,8 @@ public class GrabbingTask implements Runnable {
|
|||||||
// for FPS calculation
|
// for FPS calculation
|
||||||
private int intendedFps = 10;
|
private int intendedFps = 10;
|
||||||
|
|
||||||
|
private final YoloDetector yolo;
|
||||||
|
|
||||||
@SuppressWarnings("SameParameterValue")
|
@SuppressWarnings("SameParameterValue")
|
||||||
private void updateMessage(String message) {
|
private void updateMessage(String message) {
|
||||||
if (onMessageUpdate != null) {
|
if (onMessageUpdate != null) {
|
||||||
@@ -40,9 +45,17 @@ public class GrabbingTask implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateYoloBase64(String base64) {
|
||||||
|
if (onYoloBase64Update != null) {
|
||||||
|
onYoloBase64Update.accept(base64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateYoloFrame(Frame frame) {
|
||||||
|
if (onYoloUpdate != null) {
|
||||||
|
onYoloUpdate.accept(frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateHQBase64(String base64) {
|
private void updateHQBase64(String base64) {
|
||||||
if (onHQBase64Update != null) {
|
if (onHQBase64Update != null) {
|
||||||
@@ -77,6 +90,7 @@ public class GrabbingTask implements Runnable {
|
|||||||
this.isGrabbing = isGrabbing;
|
this.isGrabbing = isGrabbing;
|
||||||
this.grabber = grabber;
|
this.grabber = grabber;
|
||||||
if (fps>0) intendedFps = fps;
|
if (fps>0) intendedFps = fps;
|
||||||
|
yolo = new YoloDetector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -94,6 +108,23 @@ public class GrabbingTask implements Runnable {
|
|||||||
} else updateMessage("processFrame have null frame");
|
} else updateMessage("processFrame have null frame");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO masih trouble di sini
|
||||||
|
private void DetectYolo(Frame frame){
|
||||||
|
if (frame!=null){
|
||||||
|
try{
|
||||||
|
Mat processed = yolo.Detect(frame);
|
||||||
|
Frame yoloFrame = SomeCodes.CoreMatConverter.convert(processed);
|
||||||
|
updateYoloFrame(yoloFrame);
|
||||||
|
updateYoloBase64(SomeCodes.FrameToBase64(yoloFrame));
|
||||||
|
} catch (Exception e){
|
||||||
|
System.out.println("error processing YOLO, Message : "+e.getMessage());
|
||||||
|
updateYoloFrame(null);
|
||||||
|
updateYoloBase64("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void flush_grabber(){
|
private void flush_grabber(){
|
||||||
try {
|
try {
|
||||||
if (grabber!=null) grabber.flush();
|
if (grabber!=null) grabber.flush();
|
||||||
@@ -117,9 +148,13 @@ public class GrabbingTask implements Runnable {
|
|||||||
Thread.yield();
|
Thread.yield();
|
||||||
Frame frame = grabber.grab();
|
Frame frame = grabber.grab();
|
||||||
if (framecount<Integer.MAX_VALUE) framecount++; else framecount = 0;
|
if (framecount<Integer.MAX_VALUE) framecount++; else framecount = 0;
|
||||||
if (framecount % skippedframes == 0) processFrame(frame);
|
if (framecount % skippedframes == 0) {
|
||||||
|
processFrame(frame);
|
||||||
|
DetectYolo(frame);
|
||||||
|
}
|
||||||
} catch (Exception e){
|
} catch (Exception e){
|
||||||
Logger.error("Error grabbing frame: "+e.getMessage());
|
Logger.error("Error grabbing frame: "+e.getMessage());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long elapsed = System.currentTimeMillis() - starttick;
|
long elapsed = System.currentTimeMillis() - starttick;
|
||||||
|
|||||||
@@ -70,10 +70,11 @@ public class PanTiltController {
|
|||||||
command[0] = (byte) 0xFF; // add synchronization byte
|
command[0] = (byte) 0xFF; // add synchronization byte
|
||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
Main.Max485Direction(true);
|
Main.Max485Direction(true);
|
||||||
serialPort.writeBytes(command, command.length);
|
int written = serialPort.writeBytes(command, command.length);
|
||||||
Main.Max485Direction(false);
|
Main.Max485Direction(false);
|
||||||
Main.Blink_LedPanTilt();
|
Main.Blink_LedPanTilt();
|
||||||
}
|
System.out.println("Stop Movement written : "+written);
|
||||||
|
} else System.out.println("Stop Movement failed, serial port not open");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,10 +90,11 @@ public class PanTiltController {
|
|||||||
command[0] = (byte) 0xFF; // add synchronization byte
|
command[0] = (byte) 0xFF; // add synchronization byte
|
||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
Main.Max485Direction(true);
|
Main.Max485Direction(true);
|
||||||
serialPort.writeBytes(command, command.length);
|
int written = serialPort.writeBytes(command, command.length);
|
||||||
Main.Max485Direction(false);
|
Main.Max485Direction(false);
|
||||||
Main.Blink_LedPanTilt();
|
Main.Blink_LedPanTilt();
|
||||||
}
|
System.out.println("Pan Left written : "+written);
|
||||||
|
} else System.out.println("Pan Left failed, serial port not open");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,10 +110,11 @@ public class PanTiltController {
|
|||||||
command[0] = (byte) 0xFF; // add synchronization byte
|
command[0] = (byte) 0xFF; // add synchronization byte
|
||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
Main.Max485Direction(true);
|
Main.Max485Direction(true);
|
||||||
serialPort.writeBytes(command, command.length);
|
int written = serialPort.writeBytes(command, command.length);
|
||||||
Main.Max485Direction(false);
|
Main.Max485Direction(false);
|
||||||
Main.Blink_LedPanTilt();
|
Main.Blink_LedPanTilt();
|
||||||
}
|
System.out.println("Pan Right written : "+written);
|
||||||
|
} else System.out.println("Pan Right failed, serial port not open");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,10 +130,11 @@ public class PanTiltController {
|
|||||||
command[0] = (byte) 0xFF; // add synchronization byte
|
command[0] = (byte) 0xFF; // add synchronization byte
|
||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
Main.Max485Direction(true);
|
Main.Max485Direction(true);
|
||||||
serialPort.writeBytes(command, command.length);
|
int written = serialPort.writeBytes(command, command.length);
|
||||||
Main.Max485Direction(false);
|
Main.Max485Direction(false);
|
||||||
Main.Blink_LedPanTilt();
|
Main.Blink_LedPanTilt();
|
||||||
}
|
System.out.println("Tilt Up written : "+written);
|
||||||
|
} else System.out.println("Tilt Up failed, serial port not open");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,6 +148,23 @@ public class PanTiltController {
|
|||||||
byte[] command = new byte[]{0, cameraid, 0, 16, speed, 0, 0};
|
byte[] command = new byte[]{0, cameraid, 0, 16, speed, 0, 0};
|
||||||
command[6] = Checksum(command); // add checksum
|
command[6] = Checksum(command); // add checksum
|
||||||
command[0] = (byte) 0xFF; // add synchronization byte
|
command[0] = (byte) 0xFF; // add synchronization byte
|
||||||
|
if (isOpen()) {
|
||||||
|
Main.Max485Direction(true);
|
||||||
|
int written = serialPort.writeBytes(command, command.length);
|
||||||
|
Main.Max485Direction(false);
|
||||||
|
Main.Blink_LedPanTilt();
|
||||||
|
System.out.println("Tilt Down written : "+written);
|
||||||
|
} else System.out.println("Tilt Down failed, serial port not open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go to Preset
|
||||||
|
* @param preset preset number
|
||||||
|
*/
|
||||||
|
public void GoToPreset(byte preset){
|
||||||
|
byte[] command = new byte[]{0, cameraid, 0, 15, preset, 0, 0};
|
||||||
|
command[6] = Checksum(command); // add checksum
|
||||||
|
command[0] = (byte) 0xFF; // add synchronization byte
|
||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
Main.Max485Direction(true);
|
Main.Max485Direction(true);
|
||||||
serialPort.writeBytes(command, command.length);
|
serialPort.writeBytes(command, command.length);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import lombok.Getter;
|
|||||||
import org.bytedeco.ffmpeg.global.avutil;
|
import org.bytedeco.ffmpeg.global.avutil;
|
||||||
import org.bytedeco.javacv.FFmpegFrameGrabber;
|
import org.bytedeco.javacv.FFmpegFrameGrabber;
|
||||||
import org.bytedeco.javacv.Frame;
|
import org.bytedeco.javacv.Frame;
|
||||||
|
import org.bytedeco.opencv.global.opencv_core;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
@@ -17,8 +18,10 @@ public class RtspGrabber {
|
|||||||
private final AtomicBoolean isGrabbing = new AtomicBoolean(false);
|
private final AtomicBoolean isGrabbing = new AtomicBoolean(false);
|
||||||
private Frame lastHQFrame = null;
|
private Frame lastHQFrame = null;
|
||||||
private Frame lastLQFrame = null;
|
private Frame lastLQFrame = null;
|
||||||
|
private Frame lastYoloFrame = null;
|
||||||
private String lastHQBase64 = null;
|
private String lastHQBase64 = null;
|
||||||
private String lastLQBase64 = null;
|
private String lastLQBase64 = null;
|
||||||
|
private String lastYoloBase64 = null;
|
||||||
private @Getter int HQWidth = 0;
|
private @Getter int HQWidth = 0;
|
||||||
private @Getter int HQHeight = 0;
|
private @Getter int HQHeight = 0;
|
||||||
private @Getter int LQWidth = 0;
|
private @Getter int LQWidth = 0;
|
||||||
@@ -26,6 +29,13 @@ public class RtspGrabber {
|
|||||||
private GrabbingTask grabbingTask;
|
private GrabbingTask grabbingTask;
|
||||||
|
|
||||||
public RtspGrabber(String ip, String path) {
|
public RtspGrabber(String ip, String path) {
|
||||||
|
int cudacount = opencv_core.getCudaEnabledDeviceCount();
|
||||||
|
if (cudacount>0){
|
||||||
|
Logger.info("CUDA enabled devices found: " + cudacount);
|
||||||
|
opencv_core.printCudaDeviceInfo(0);
|
||||||
|
} else {
|
||||||
|
Logger.info("No CUDA enabled devices found");
|
||||||
|
}
|
||||||
this.rtspUrl = "rtsp://" + ip + path;
|
this.rtspUrl = "rtsp://" + ip + path;
|
||||||
Logger.info("RtspGrabber created with url: " + rtspUrl);
|
Logger.info("RtspGrabber created with url: " + rtspUrl);
|
||||||
}
|
}
|
||||||
@@ -62,6 +72,22 @@ public class RtspGrabber {
|
|||||||
return lastLQBase64;
|
return lastLQBase64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized void setLastYoloBase64(String base64){
|
||||||
|
lastYoloBase64 = base64;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized String getLastYoloBase64(){
|
||||||
|
return lastYoloBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void setLastYoloFrame(Frame frame){
|
||||||
|
lastYoloFrame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Frame getLastYoloFrame(){
|
||||||
|
return lastYoloFrame;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start grabbing frames from rtsp
|
* Start grabbing frames from rtsp
|
||||||
* @param useTcp Use tcp instead of udp
|
* @param useTcp Use tcp instead of udp
|
||||||
@@ -143,6 +169,8 @@ public class RtspGrabber {
|
|||||||
});
|
});
|
||||||
tt.setOnHQBase64Update(this::setLastHQBase64);
|
tt.setOnHQBase64Update(this::setLastHQBase64);
|
||||||
tt.setOnLQBase64Update(this::setLastLQBase64);
|
tt.setOnLQBase64Update(this::setLastLQBase64);
|
||||||
|
tt.setOnYoloUpdate(this::setLastYoloFrame);
|
||||||
|
tt.setOnYoloBase64Update(this::setLastYoloBase64);
|
||||||
return tt;
|
return tt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
167
src/main/java/Camera/YoloDetector.java
Normal file
167
src/main/java/Camera/YoloDetector.java
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
package Camera;
|
||||||
|
|
||||||
|
import Other.SomeCodes;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bytedeco.javacv.Frame;
|
||||||
|
import org.bytedeco.opencv.global.opencv_dnn;
|
||||||
|
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Mat;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Rect;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Scalar;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Size;
|
||||||
|
import org.bytedeco.opencv.opencv_dnn.*;
|
||||||
|
import org.opencv.core.MatOfFloat;
|
||||||
|
import org.opencv.core.MatOfInt;
|
||||||
|
import org.opencv.core.MatOfRect2d;
|
||||||
|
import org.opencv.dnn.Dnn;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.bytedeco.opencv.global.opencv_core.CV_32F;
|
||||||
|
|
||||||
|
public class YoloDetector {
|
||||||
|
private Net net;
|
||||||
|
private @Getter boolean NetLoaded;
|
||||||
|
private List<String> classes ;
|
||||||
|
// YOLO expect image in 640 x 640
|
||||||
|
private final int input_width = 640;
|
||||||
|
private final int input_height = 640;
|
||||||
|
// minimum confidence for detections
|
||||||
|
private final float confidence_threshold = 0.5f;
|
||||||
|
// Non-maximum suppression threshold
|
||||||
|
private final float nms_threshold = 0.4f;
|
||||||
|
|
||||||
|
public YoloDetector() {
|
||||||
|
NetLoaded = false;
|
||||||
|
net = null;
|
||||||
|
classes = null;
|
||||||
|
String onnxfile = SomeCodes.ExtractResource("/yolov8n.onnx", SomeCodes.currentDirectory);
|
||||||
|
String namesfile = SomeCodes.ExtractResource("/coco.names", SomeCodes.currentDirectory);
|
||||||
|
if (SomeCodes.ValidFile(onnxfile)){
|
||||||
|
if (SomeCodes.ValidFile(namesfile)){
|
||||||
|
net = opencv_dnn.readNetFromONNX(onnxfile);
|
||||||
|
net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
|
||||||
|
net.setPreferableTarget(Dnn.DNN_TARGET_CPU);
|
||||||
|
|
||||||
|
classes = new ArrayList<>();
|
||||||
|
try(BufferedReader br = new BufferedReader(new FileReader(namesfile))) {
|
||||||
|
String line;
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
classes.add(line);
|
||||||
|
}
|
||||||
|
} catch (Exception e){
|
||||||
|
System.out.println("Error: reading names file");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!net.empty()){
|
||||||
|
if (!classes.isEmpty()){
|
||||||
|
NetLoaded = true;
|
||||||
|
} else System.out.println("Error: names file is empty");
|
||||||
|
} else System.out.println("Error: net is empty");
|
||||||
|
} else System.out.println("Error: names file not found");
|
||||||
|
} else System.out.println("Error: onnx file not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mat Detect(Frame frame){
|
||||||
|
Mat mat = SomeCodes.CoreMatConverter.convertToMat(frame);
|
||||||
|
return Detect(mat);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mat Detect(Mat frame){
|
||||||
|
if (NetLoaded){
|
||||||
|
Mat blob = opencv_dnn.blobFromImage(frame, 1.0/255.0, new Size(input_width, input_height), new Scalar(0) , true, false, CV_32F);
|
||||||
|
net.setInput(blob);
|
||||||
|
|
||||||
|
Mat detections = net.forward();
|
||||||
|
return detections;
|
||||||
|
} else {
|
||||||
|
System.out.println("Error: Net not loaded");
|
||||||
|
return new Mat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mat ProcessDetection(Mat frame, Mat output){
|
||||||
|
int rows = output.rows();
|
||||||
|
int cols = output.cols();
|
||||||
|
List<Rect> boxes = new ArrayList<>();
|
||||||
|
List<Float> confidences = new ArrayList<>();
|
||||||
|
List<Integer> classIds = new ArrayList<>();
|
||||||
|
|
||||||
|
for(int i=0;i<rows;i++){
|
||||||
|
Mat row = output.row(i);
|
||||||
|
float confidence = row.getFloatBuffer().get(4);
|
||||||
|
if (confidence >= confidence_threshold){
|
||||||
|
FloatBuffer data = row.getFloatBuffer();
|
||||||
|
int classid = 0;
|
||||||
|
float maxscore = 0;
|
||||||
|
for(int j = 5; j< cols; j++){
|
||||||
|
float score = data.get(j);
|
||||||
|
if (score > maxscore){
|
||||||
|
maxscore = score;
|
||||||
|
classid = j-5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxscore>= confidence_threshold){
|
||||||
|
int x = (int)(data.get(0) * frame.cols());
|
||||||
|
int y = (int)(data.get(1) * frame.rows());
|
||||||
|
int width = (int)(data.get(2) * frame.cols());
|
||||||
|
int height = (int)(data.get(3) * frame.rows());
|
||||||
|
|
||||||
|
boxes.add(new Rect(x-width/2, y-height/2, width, height));
|
||||||
|
confidences.add(maxscore);
|
||||||
|
classIds.add(classid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect[] rr = new Rect[boxes.size()];
|
||||||
|
for(int ii = 0; ii<boxes.size(); ii++){
|
||||||
|
rr[ii] = boxes.get(ii);
|
||||||
|
}
|
||||||
|
MatOfRect2d rects = new MatOfRect2d(ListToRectArray(boxes));
|
||||||
|
|
||||||
|
MatOfFloat conf = new MatOfFloat(ListToArray(confidences));
|
||||||
|
|
||||||
|
MatOfInt indices = new MatOfInt();
|
||||||
|
|
||||||
|
if (!boxes.isEmpty()){
|
||||||
|
Dnn.NMSBoxes(rects, conf, confidence_threshold, nms_threshold, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] idx = indices.toArray();
|
||||||
|
for(int i : idx){
|
||||||
|
Rect box = boxes.get(i);
|
||||||
|
int classId = classIds.get(i);
|
||||||
|
float confidence = confidences.get(i);
|
||||||
|
String label = classes.get(classId);
|
||||||
|
opencv_imgproc.rectangle(frame, box, Scalar.RED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
private org.opencv.core.Rect2d[] ListToRectArray(List<Rect> list){
|
||||||
|
org.opencv.core.Rect2d[] arr = new org.opencv.core.Rect2d[list.size()];
|
||||||
|
for(int i=0;i<list.size();i++){
|
||||||
|
Rect r = list.get(i);
|
||||||
|
arr[i] = new org.opencv.core.Rect2d(r.x(), r.y(), r.width(), r.height());
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float[] ListToArray(List<Float> list){
|
||||||
|
float[] arr = new float[list.size()];
|
||||||
|
for(int i=0;i<list.size();i++){
|
||||||
|
arr[i] = list.get(i);
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,10 +6,9 @@ import org.bytedeco.javacv.Frame;
|
|||||||
import org.bytedeco.javacv.Java2DFrameConverter;
|
import org.bytedeco.javacv.Java2DFrameConverter;
|
||||||
import org.bytedeco.javacv.OpenCVFrameConverter;
|
import org.bytedeco.javacv.OpenCVFrameConverter;
|
||||||
import org.bytedeco.opencv.global.opencv_core;
|
import org.bytedeco.opencv.global.opencv_core;
|
||||||
|
import org.bytedeco.opencv.global.opencv_dnn;
|
||||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||||
import org.bytedeco.opencv.opencv_core.Mat;
|
import org.bytedeco.opencv.opencv_core.*;
|
||||||
import org.bytedeco.opencv.opencv_core.Size;
|
|
||||||
import org.bytedeco.opencv.opencv_core.UMat;
|
|
||||||
import org.bytedeco.opencv.opencv_java;
|
import org.bytedeco.opencv.opencv_java;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.opencv.core.MatOfByte;
|
import org.opencv.core.MatOfByte;
|
||||||
@@ -184,6 +183,20 @@ public class SomeCodes {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String MatToBase64(org.opencv.core.Mat mat){
|
||||||
|
if (mat!=null){
|
||||||
|
if (!mat.empty()){
|
||||||
|
MatOfByte mob = new MatOfByte();
|
||||||
|
Imgcodecs.imencode(".jpg", mat, mob);
|
||||||
|
byte[] jpgdata = mob.toArray();
|
||||||
|
mob.release();
|
||||||
|
mat.release();
|
||||||
|
return base64encoder.encodeToString(jpgdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Function ini pakai opencv, bukan javacv, jadi perlu Loader.load(opencv_java.class) di awal
|
// Function ini pakai opencv, bukan javacv, jadi perlu Loader.load(opencv_java.class) di awal
|
||||||
// lebih optimal untuk konversi frame ke base64
|
// lebih optimal untuk konversi frame ke base64
|
||||||
@@ -191,14 +204,7 @@ public class SomeCodes {
|
|||||||
if (frame!=null){
|
if (frame!=null){
|
||||||
org.opencv.core.Mat converted = CoreMatConverter.convert(frame);
|
org.opencv.core.Mat converted = CoreMatConverter.convert(frame);
|
||||||
if (converted!=null){
|
if (converted!=null){
|
||||||
if (!converted.empty()){
|
return MatToBase64(converted);
|
||||||
MatOfByte mob = new MatOfByte();
|
|
||||||
Imgcodecs.imencode(".jpg", converted, mob);
|
|
||||||
byte[] jpgdata = mob.toArray();
|
|
||||||
mob.release();
|
|
||||||
converted.release();
|
|
||||||
return base64encoder.encodeToString(jpgdata);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
@@ -283,4 +289,106 @@ public class SomeCodes {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Sleep(int milliseconds){
|
||||||
|
try{
|
||||||
|
Thread.sleep(milliseconds);
|
||||||
|
} catch (Exception e){
|
||||||
|
Logger.error("Error sleeping: "+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat ResizeForYolo(Mat image) {
|
||||||
|
int targetSize = 640; // YOLOv8 input size (640x640)
|
||||||
|
|
||||||
|
// Get original dimensions
|
||||||
|
int originalWidth = image.cols();
|
||||||
|
int originalHeight = image.rows();
|
||||||
|
|
||||||
|
// Compute new dimensions while keeping aspect ratio
|
||||||
|
float scale = Math.min((float) targetSize / originalWidth, (float) targetSize / originalHeight);
|
||||||
|
int newWidth = Math.round(originalWidth * scale);
|
||||||
|
int newHeight = Math.round(originalHeight * scale);
|
||||||
|
|
||||||
|
// Resize while keeping aspect ratio
|
||||||
|
Mat resizedImage = new Mat();
|
||||||
|
opencv_imgproc.resize(image, resizedImage, new Size(newWidth, newHeight));
|
||||||
|
|
||||||
|
// Create a black 640x640 image and place the resized image in the center (padding)
|
||||||
|
Mat paddedImage = new Mat(targetSize, targetSize, image.type(), new Scalar(0, 0, 0,0));
|
||||||
|
int xOffset = (targetSize - newWidth) / 2;
|
||||||
|
int yOffset = (targetSize - newHeight) / 2;
|
||||||
|
|
||||||
|
Rect roi = new Rect(xOffset, yOffset, newWidth, newHeight);
|
||||||
|
Mat regionOfInterest = paddedImage.apply(roi);
|
||||||
|
resizedImage.copyTo(regionOfInterest);
|
||||||
|
|
||||||
|
// Convert to blob (normalize to [0,1])
|
||||||
|
//Mat blob = new Mat();
|
||||||
|
//opencv_dnn.blobFromImage(paddedImage, blob, 1.0 / 255.0, new Size(targetSize, targetSize), new Scalar(0, 0, 0), true, false);
|
||||||
|
|
||||||
|
return paddedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat preprocessForYOLO(Mat image) {
|
||||||
|
int targetSize = 640; // YOLO input size
|
||||||
|
|
||||||
|
// Original size
|
||||||
|
int originalWidth = image.cols();
|
||||||
|
int originalHeight = image.rows();
|
||||||
|
|
||||||
|
// Scale to fit 640x640 while maintaining aspect ratio
|
||||||
|
float scale = Math.min((float) targetSize / originalWidth, (float) targetSize / originalHeight);
|
||||||
|
int newWidth = Math.round(originalWidth * scale);
|
||||||
|
int newHeight = Math.round(originalHeight * scale);
|
||||||
|
|
||||||
|
// Resize image
|
||||||
|
Mat resizedImage = new Mat();
|
||||||
|
opencv_imgproc.resize(image, resizedImage, new Size(newWidth, newHeight));
|
||||||
|
|
||||||
|
// Create black canvas (640x640)
|
||||||
|
Mat paddedImage = new Mat(targetSize, targetSize, image.type(), new Scalar());
|
||||||
|
|
||||||
|
// Center the resized image on the black background
|
||||||
|
int xOffset = (targetSize - newWidth) / 2;
|
||||||
|
int yOffset = (targetSize - newHeight) / 2;
|
||||||
|
Rect roi = new Rect(xOffset, yOffset, newWidth, newHeight);
|
||||||
|
resizedImage.copyTo(paddedImage.apply(roi));
|
||||||
|
|
||||||
|
// Convert to blob (normalize to [0,1])
|
||||||
|
Mat blob = new Mat();
|
||||||
|
opencv_dnn.blobFromImage(paddedImage);
|
||||||
|
|
||||||
|
return blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Mat resizeAndPad(Frame fr, int targetWidth, int targetHeight) {
|
||||||
|
Mat image = matConverter.convertToMat(fr);
|
||||||
|
int originalWidth = image.cols();
|
||||||
|
int originalHeight = image.rows();
|
||||||
|
|
||||||
|
// Scale factor for resizing while maintaining aspect ratio
|
||||||
|
float scale = Math.min((float) targetWidth / originalWidth, (float) targetHeight / originalHeight);
|
||||||
|
int newWidth = Math.round(originalWidth * scale);
|
||||||
|
int newHeight = Math.round(originalHeight * scale);
|
||||||
|
|
||||||
|
// Resize the image
|
||||||
|
Mat resizedImage = new Mat();
|
||||||
|
opencv_imgproc.resize(image, resizedImage, new Size(newWidth, newHeight));
|
||||||
|
|
||||||
|
// Create a new black (zero-filled) Mat of target size
|
||||||
|
Mat paddedImage = new Mat(targetHeight, targetWidth, image.type(), new Scalar());
|
||||||
|
|
||||||
|
// Calculate padding
|
||||||
|
int xOffset = (targetWidth - newWidth) / 2;
|
||||||
|
int yOffset = (targetHeight - newHeight) / 2;
|
||||||
|
|
||||||
|
// Place resized image into center of the black canvas
|
||||||
|
Rect roi = new Rect(xOffset, yOffset, newWidth, newHeight);
|
||||||
|
Mat regionOfInterest = paddedImage.apply(roi);
|
||||||
|
resizedImage.copyTo(regionOfInterest);
|
||||||
|
|
||||||
|
return paddedImage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
38
src/main/java/SBC/I2C_BUS.java
Normal file
38
src/main/java/SBC/I2C_BUS.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package SBC;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
public class I2C_BUS {
|
||||||
|
private final Linux_C_lib C = Linux_C_lib.INSTANCE;
|
||||||
|
|
||||||
|
|
||||||
|
private @Getter boolean opened = false;
|
||||||
|
private final @Getter String i2c_name;
|
||||||
|
private @Getter int i2c_handle = -1;
|
||||||
|
|
||||||
|
public I2C_BUS(int bus_number){
|
||||||
|
this.i2c_name = "/dev/i2c-"+bus_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean Open_Bus(){
|
||||||
|
if (!opened){
|
||||||
|
final int O_RDWR = 0x00000002;
|
||||||
|
i2c_handle = C.open(i2c_name, O_RDWR);
|
||||||
|
if (i2c_handle>=0){
|
||||||
|
opened = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close_Bus(){
|
||||||
|
if (opened){
|
||||||
|
if (i2c_handle>=0){
|
||||||
|
C.close(i2c_handle);
|
||||||
|
i2c_handle = -1;
|
||||||
|
}
|
||||||
|
opened = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
147
src/main/java/SBC/I2C_Device.java
Normal file
147
src/main/java/SBC/I2C_Device.java
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
package SBC;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class I2C_Device {
|
||||||
|
|
||||||
|
|
||||||
|
Linux_C_lib C = Linux_C_lib.INSTANCE;
|
||||||
|
private @Getter int bus_handle;
|
||||||
|
private @Getter int device_address;
|
||||||
|
private @Getter int dev_handle;
|
||||||
|
private @Getter boolean opened = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create I2C Device
|
||||||
|
* @param bus_handle I2C Bus Handle, from opening I2C_Bus
|
||||||
|
* @param device_address I2C Device Address
|
||||||
|
*/
|
||||||
|
public I2C_Device(int bus_handle, int device_address){
|
||||||
|
opened = false;
|
||||||
|
if (bus_handle<0 || device_address<0) return;
|
||||||
|
this.bus_handle = bus_handle;
|
||||||
|
this.device_address = device_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open I2C Device in Slave mode
|
||||||
|
* @return true if successfully opened
|
||||||
|
*/
|
||||||
|
public boolean Open_Slave(){
|
||||||
|
boolean sucess = false;
|
||||||
|
dev_handle = C.ioctl(bus_handle, I2C_Flags.I2C_SLAVE, device_address);
|
||||||
|
if (dev_handle>=0){
|
||||||
|
sucess = true;
|
||||||
|
}
|
||||||
|
opened = sucess;
|
||||||
|
return opened;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open I2C Device in Slave mode with Force
|
||||||
|
* @return true if successfully opened
|
||||||
|
*/
|
||||||
|
public boolean Open_SlaveForce(){
|
||||||
|
boolean sucess = false;
|
||||||
|
dev_handle = C.ioctl(bus_handle, I2C_Flags.I2C_SLAVE_FORCE, device_address);
|
||||||
|
if (dev_handle>=0){
|
||||||
|
C.ioctl(bus_handle,I2C_Flags.I2C_RETRIES, 3);
|
||||||
|
C.ioctl(bus_handle,I2C_Flags.I2C_TIMEOUT, 1000);
|
||||||
|
sucess = true;
|
||||||
|
}
|
||||||
|
opened = sucess;
|
||||||
|
return opened;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open I2C Device in Read Write mode
|
||||||
|
* @return true if successfully opened
|
||||||
|
*/
|
||||||
|
public boolean Open_RDWR(){
|
||||||
|
boolean sucess = false;
|
||||||
|
dev_handle = C.ioctl(bus_handle, I2C_Flags.I2C_RDWR, device_address);
|
||||||
|
if (dev_handle>=0){
|
||||||
|
sucess = true;
|
||||||
|
}
|
||||||
|
opened = sucess;
|
||||||
|
return opened;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open I2C Device in SMBus mode
|
||||||
|
* @return true if successfully opened
|
||||||
|
*/
|
||||||
|
public boolean Open_SMBus(){
|
||||||
|
boolean sucess = false;
|
||||||
|
dev_handle = C.ioctl(bus_handle, I2C_Flags.I2C_SMBUS, device_address);
|
||||||
|
if (dev_handle>=0){
|
||||||
|
sucess = true;
|
||||||
|
}
|
||||||
|
opened = sucess;
|
||||||
|
return opened;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close I2C Device
|
||||||
|
*/
|
||||||
|
public void Close(){
|
||||||
|
C.close(dev_handle);
|
||||||
|
opened = false;
|
||||||
|
dev_handle = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write Bytes to I2C Device
|
||||||
|
* @param data bytes to write
|
||||||
|
* @return number of bytes written
|
||||||
|
*/
|
||||||
|
public int WriteBytes(byte[] data){
|
||||||
|
if (bus_handle<0 || dev_handle<0 || device_address<0) return -1;
|
||||||
|
return C.write(bus_handle, data, data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write Byte to I2C Device
|
||||||
|
* @param register_address register address
|
||||||
|
* @param data byte to write
|
||||||
|
* @return number of bytes written
|
||||||
|
*/
|
||||||
|
public int WriteBytes(int register_address, byte data){
|
||||||
|
byte[] cmd = new byte[2];
|
||||||
|
cmd[0] = (byte) register_address;
|
||||||
|
cmd[1] = data;
|
||||||
|
return WriteBytes(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write Bytes to I2C Device
|
||||||
|
* @param register_address register address
|
||||||
|
* @param data bytes to write
|
||||||
|
* @return number of bytes written
|
||||||
|
*/
|
||||||
|
public int WriteBytes(int register_address, byte[] data){
|
||||||
|
byte[] cmd = new byte[data.length+1];
|
||||||
|
cmd[0] = (byte) register_address;
|
||||||
|
System.arraycopy(data, 0, cmd, 1, data.length);
|
||||||
|
return WriteBytes(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read Bytes from I2C Device
|
||||||
|
* @param readsize number of bytes to read
|
||||||
|
* @return bytes read
|
||||||
|
*/
|
||||||
|
public byte[] ReadBytes(int readsize){
|
||||||
|
if (bus_handle<0 || dev_handle<0 || device_address<0) return null;
|
||||||
|
byte[] data = new byte[readsize];
|
||||||
|
int read = C.read(bus_handle, data, readsize);
|
||||||
|
if (read<0) return null;
|
||||||
|
if (read<readsize){
|
||||||
|
byte[] temp = new byte[read];
|
||||||
|
System.arraycopy(data, 0, temp, 0, read);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/main/java/SBC/I2C_Flags.java
Normal file
13
src/main/java/SBC/I2C_Flags.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package SBC;
|
||||||
|
|
||||||
|
public class I2C_Flags {
|
||||||
|
public final static int I2C_RETRIES = 0x701; /* number of times a device address should be polled when not acknowledging */
|
||||||
|
public final static int I2C_TIMEOUT = 0x702; /* set timeout in units of 10 ms */
|
||||||
|
public final static int I2C_SLAVE = 0x703; /* Command at ioctl, means : Use this slave address */
|
||||||
|
public final static int I2C_TENBIT = 0x704; /* 0 for 7 bit addrs, != 0 for 10 bit */
|
||||||
|
public final static int I2C_FUNCS = 0x705; /* Command at ioctl, means : Get the adapter functionality */
|
||||||
|
public final static int I2C_SLAVE_FORCE = 0x706; /* Command at ioctl, means : Use this slave address, even if it is already in use by a driver! */
|
||||||
|
public final static int I2C_RDWR = 0x707; /* Command at ioctl, means : Combined R/W transfer (one stop only) */
|
||||||
|
public final static int I2C_PEC = 0x708; /* != 0 to use PEC with SMBus */
|
||||||
|
public final static int I2C_SMBUS = 0x720; /* SMBus transfer */
|
||||||
|
}
|
||||||
69
src/main/java/SBC/Linux_C_lib.java
Normal file
69
src/main/java/SBC/Linux_C_lib.java
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package SBC;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.sun.jna.Native;
|
||||||
|
import com.sun.jna.NativeLong;
|
||||||
|
import com.sun.jna.Pointer;
|
||||||
|
import com.sun.jna.Structure;
|
||||||
|
|
||||||
|
public interface Linux_C_lib extends com.sun.jna.Library {
|
||||||
|
Linux_C_lib INSTANCE = (Linux_C_lib) Native.load("c", Linux_C_lib.class);
|
||||||
|
|
||||||
|
long memcpy(int[] dst, short[] src, long n);
|
||||||
|
|
||||||
|
int memcpy(int[] dst, short[] src, int n);
|
||||||
|
|
||||||
|
int pipe(int[] fds);
|
||||||
|
|
||||||
|
int tcdrain(int fd);
|
||||||
|
|
||||||
|
int fcntl(int bus_handle, int command, int args);
|
||||||
|
|
||||||
|
int ioctl(int bus_handle, int command, int args);
|
||||||
|
|
||||||
|
int ioctl(int bus_handle, int command, int... args);
|
||||||
|
|
||||||
|
int ioctl(int bus_handle, int command, Pointer args);
|
||||||
|
|
||||||
|
int open(String path, int flags);
|
||||||
|
|
||||||
|
int close(int fd);
|
||||||
|
|
||||||
|
int write(int bus_handle, byte[] buffer, int count);
|
||||||
|
|
||||||
|
int read(int bus_handle, byte[] buffer, int count);
|
||||||
|
|
||||||
|
long write(int bus_handle, byte[] buffer, long count);
|
||||||
|
|
||||||
|
long read(int bus_handle, byte[] buffer, long count);
|
||||||
|
|
||||||
|
int select(int n, int[] read, int[] write, int[] error, timeval timeout);
|
||||||
|
|
||||||
|
int poll(int[] fds, int nfds, int timeout);
|
||||||
|
|
||||||
|
int tcflush(int fd, int qs);
|
||||||
|
|
||||||
|
void perror(String msg);
|
||||||
|
|
||||||
|
int tcsendbreak(int fd, int duration);
|
||||||
|
|
||||||
|
public class timeval extends Structure {
|
||||||
|
public NativeLong tv_sec;
|
||||||
|
public NativeLong tv_usec;
|
||||||
|
|
||||||
|
|
||||||
|
protected List<String> getFieldOrder() {
|
||||||
|
return Arrays.asList(//
|
||||||
|
"tv_sec",//
|
||||||
|
"tv_usec"//
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public timeval(long second, long usecond) {
|
||||||
|
tv_sec = new NativeLong(second);
|
||||||
|
tv_usec = new NativeLong(usecond);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
159
src/main/java/SBC/PCF8574.java
Normal file
159
src/main/java/SBC/PCF8574.java
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
package SBC;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class PCF8574 extends I2C_Device{
|
||||||
|
|
||||||
|
private byte data = 0x00;
|
||||||
|
private final @Getter String[] pinNames = new String[8];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new PCF8574
|
||||||
|
* @param bus_number I2C Bus Number
|
||||||
|
* @param address PCF8574 Address
|
||||||
|
*/
|
||||||
|
public PCF8574(int bus_number, int address){
|
||||||
|
super(bus_number, address);
|
||||||
|
for(int i=0; i<8; i++){
|
||||||
|
pinNames[i] = i+"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set new Pin Name
|
||||||
|
* @param pin pin number, 0-7
|
||||||
|
* @param name new name
|
||||||
|
*/
|
||||||
|
public void setPinName(int pin, String name){
|
||||||
|
if (pin<0 || pin>7) return;
|
||||||
|
pinNames[pin] = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Pin Name
|
||||||
|
* @param pin pin number, 0-7
|
||||||
|
* @return pin name, or null if not available
|
||||||
|
*/
|
||||||
|
public String getPinName(int pin){
|
||||||
|
if (pin<0 || pin>7) return null;
|
||||||
|
return pinNames[pin];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set All Pins High
|
||||||
|
* @return true if successful
|
||||||
|
*/
|
||||||
|
public boolean AllOn(){
|
||||||
|
if (super.isOpened()){
|
||||||
|
if (super.WriteBytes(new byte[]{(byte)0xFF})>0){
|
||||||
|
data = (byte)0xFF;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set all Pins Low
|
||||||
|
* @return true if successful
|
||||||
|
*/
|
||||||
|
public boolean AllOff(){
|
||||||
|
if (super.isOpened()){
|
||||||
|
if (super.WriteBytes(new byte[]{(byte)0x00})>0){
|
||||||
|
data = (byte)0x00;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Pin by Pin Name
|
||||||
|
* @param pinName pin name
|
||||||
|
* @return true if successful
|
||||||
|
*/
|
||||||
|
public boolean SetPin(String pinName){
|
||||||
|
for(int i=0; i<8; i++){
|
||||||
|
if (pinNames[i].equals(pinName)){
|
||||||
|
return SetPin(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Pin High
|
||||||
|
* @param pin pin number 0-7
|
||||||
|
* @return true if successful
|
||||||
|
*/
|
||||||
|
public boolean SetPin(int pin){
|
||||||
|
if (pin<0 || pin>7) return false;
|
||||||
|
if (super.isOpened()){
|
||||||
|
byte temp = (byte) (data | (1<<pin));
|
||||||
|
return super.WriteBytes(new byte[]{temp})>0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear Pin by Pin Name
|
||||||
|
* @param pinName pin name
|
||||||
|
* @return true if successful
|
||||||
|
*/
|
||||||
|
public boolean ClearPin(String pinName){
|
||||||
|
for(int i=0; i<8; i++){
|
||||||
|
if (pinNames[i].equals(pinName)){
|
||||||
|
return ClearPin(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Pin Low
|
||||||
|
* @param pin pin number 0-7
|
||||||
|
* @return true if successful
|
||||||
|
*/
|
||||||
|
public boolean ClearPin(int pin){
|
||||||
|
if (pin<0 || pin>7) return false;
|
||||||
|
if (super.isOpened()){
|
||||||
|
byte temp = (byte) (data & ~(1<<pin));
|
||||||
|
return super.WriteBytes(new byte[]{temp})>0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read Pin by Pin Name
|
||||||
|
* @param pinName pin name
|
||||||
|
* @return 1 if high, 0 if low, -1 if error
|
||||||
|
*/
|
||||||
|
public int ReadPin(String pinName){
|
||||||
|
for(int i=0; i<8; i++){
|
||||||
|
if (pinNames[i].equals(pinName)){
|
||||||
|
return ReadPin(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read Pin
|
||||||
|
* @param pin pin to read, 0 - 7
|
||||||
|
* @return 1 if high, 0 if low, -1 if error
|
||||||
|
*/
|
||||||
|
public int ReadPin(int pin){
|
||||||
|
if (pin<0 || pin>7) return -1;
|
||||||
|
if (super.isOpened()){
|
||||||
|
byte[] buffer = super.ReadBytes(1);
|
||||||
|
byte masker = (byte) (1<<pin);
|
||||||
|
return (buffer[0] & masker) > 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import Other.SomeCodes;
|
|||||||
import SBC.*;
|
import SBC.*;
|
||||||
import Web.*;
|
import Web.*;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.sun.jna.Platform;
|
||||||
import org.bytedeco.opencv.global.opencv_core;
|
import org.bytedeco.opencv.global.opencv_core;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
@@ -45,6 +46,9 @@ public class Main {
|
|||||||
|
|
||||||
private static ExecutorService gpioExecutor = null;
|
private static ExecutorService gpioExecutor = null;
|
||||||
|
|
||||||
|
private static I2C_BUS i2c_bus = null;
|
||||||
|
private static PCF8574 pcf8574 = null;
|
||||||
|
|
||||||
// Application start from here
|
// Application start from here
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
@@ -70,10 +74,16 @@ public class Main {
|
|||||||
if (Max485Direction!=null) {
|
if (Max485Direction!=null) {
|
||||||
Logger.info("GPIO pin {} unexport : {}", Max485Direction.pin, GPIO.UnexportPin(Max485Direction));
|
Logger.info("GPIO pin {} unexport : {}", Max485Direction.pin, GPIO.UnexportPin(Max485Direction));
|
||||||
}
|
}
|
||||||
|
if (pcf8574!=null){
|
||||||
|
pcf8574.Close();
|
||||||
|
}
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
init_gpio();
|
System.out.println("Current Directory : "+currentDirectory);
|
||||||
|
|
||||||
|
//init_gpio();
|
||||||
|
init_pcf8574();
|
||||||
init_system_monitoring();
|
init_system_monitoring();
|
||||||
|
|
||||||
init_properties();
|
init_properties();
|
||||||
@@ -81,20 +91,54 @@ public class Main {
|
|||||||
|
|
||||||
init_Vapix();
|
init_Vapix();
|
||||||
init_audio();
|
init_audio();
|
||||||
|
|
||||||
init_pantiltcontroller();
|
init_pantiltcontroller();
|
||||||
init_webserver();
|
init_webserver();
|
||||||
init_rtspgrabber();
|
init_rtspgrabber();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void init_pcf8574(){
|
||||||
|
if (Platform.isLinux()){
|
||||||
|
i2c_bus = new I2C_BUS(7);
|
||||||
|
if (i2c_bus.Open_Bus()){
|
||||||
|
Logger.info("I2C Bus opened");
|
||||||
|
pcf8574 = new PCF8574(i2c_bus.getI2c_handle(), 0x27);
|
||||||
|
if (pcf8574.Open_Slave()){
|
||||||
|
System.out.println("PCF8574 opened");
|
||||||
|
pcf8574.AllOff();
|
||||||
|
pcf8574.setPinName(0, "Amplifier Power");
|
||||||
|
pcf8574.setPinName(1, "Led Web");
|
||||||
|
pcf8574.setPinName(2, "Led IP Camera");
|
||||||
|
pcf8574.setPinName(3, "Led Pan Tilt");
|
||||||
|
pcf8574.setPinName(4, "Max485 Direction");
|
||||||
|
gpioExecutor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
System.out.println("Failed to open PCF8574");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("Failed to open I2C Bus");
|
||||||
|
}
|
||||||
|
} else System.out.println("PCF8574 not supported on this platform");
|
||||||
|
}
|
||||||
|
|
||||||
private static void init_gpio(){
|
private static void init_gpio(){
|
||||||
if (GPIO.HaveGPIO()){
|
if (Platform.isLinux()){
|
||||||
gpioExecutor = Executors.newVirtualThreadPerTaskExecutor();
|
if (GPIO.HaveGPIO()){
|
||||||
AmplifierPower = InitializePin(JetsonOrinPins.Pin13, true);
|
gpioExecutor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
LedWeb = InitializePin(JetsonOrinPins.Pin15, true);
|
AmplifierPower = InitializePin(JetsonOrinPins.Pin13, true);
|
||||||
LedIpCamera = InitializePin(JetsonOrinPins.Pin19, true);
|
LedWeb = InitializePin(JetsonOrinPins.Pin15, true);
|
||||||
LedPanTilt = InitializePin(JetsonOrinPins.Pin21, true);
|
LedIpCamera = InitializePin(JetsonOrinPins.Pin19, true);
|
||||||
Max485Direction = InitializePin(JetsonOrinPins.Pin23, true);
|
LedPanTilt = InitializePin(JetsonOrinPins.Pin21, true);
|
||||||
}
|
Max485Direction = InitializePin(JetsonOrinPins.Pin23, true);
|
||||||
|
GPIO.SetValue(AmplifierPower,false);
|
||||||
|
GPIO.SetValue(LedWeb,false);
|
||||||
|
GPIO.SetValue(LedIpCamera,false);
|
||||||
|
GPIO.SetValue(LedPanTilt,false);
|
||||||
|
GPIO.SetValue(Max485Direction,false);
|
||||||
|
}
|
||||||
|
} else System.out.println("GPIO not supported on this platform");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -121,17 +165,65 @@ public class Main {
|
|||||||
public static void Max485Direction(boolean isTransmit){
|
public static void Max485Direction(boolean isTransmit){
|
||||||
if (Max485Direction!=null){
|
if (Max485Direction!=null){
|
||||||
GPIO.SetValue(Max485Direction, isTransmit);
|
GPIO.SetValue(Max485Direction, isTransmit);
|
||||||
|
} else if (pcf8574!=null && pcf8574.isOpened()){
|
||||||
|
if (isTransmit){
|
||||||
|
pcf8574.SetPin("Max485 Direction");
|
||||||
|
} else {
|
||||||
|
pcf8574.ClearPin("Max485 Direction");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dipanggil di PanTiltController, maka perlu public dan static
|
// dipanggil di PanTiltController, maka perlu public dan static
|
||||||
public static void Blink_LedPanTilt(){
|
public static void Blink_LedPanTilt(){
|
||||||
Blink(LedPanTilt);
|
if (LedPanTilt!=null){
|
||||||
|
Blink(LedPanTilt);
|
||||||
|
} else if (pcf8574!=null && pcf8574.isOpened()){
|
||||||
|
Blink("Led Pan Tilt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Blink_LedWeb(){
|
||||||
|
if (LedWeb!=null){
|
||||||
|
Blink(LedWeb);
|
||||||
|
} else if (pcf8574!=null && pcf8574.isOpened()){
|
||||||
|
Blink("Led Web");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Blink_LedIpCamera(){
|
||||||
|
if (LedIpCamera!=null){
|
||||||
|
Blink(LedIpCamera);
|
||||||
|
} else if (pcf8574!=null && pcf8574.isOpened()){
|
||||||
|
Blink("Led IP Camera");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AmplifierControl(boolean isON){
|
private static void AmplifierControl(boolean isON){
|
||||||
if (AmplifierPower!=null){
|
if (AmplifierPower!=null){
|
||||||
GPIO.SetValue(AmplifierPower, isON);
|
GPIO.SetValue(AmplifierPower, isON);
|
||||||
|
} else if (pcf8574!=null && pcf8574.isOpened()){
|
||||||
|
if (isON){
|
||||||
|
pcf8574.SetPin("Amplifier Power");
|
||||||
|
} else {
|
||||||
|
pcf8574.ClearPin("Amplifier Power");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Blink(String pinName){
|
||||||
|
if (pcf8574!=null && pcf8574.isOpened()){
|
||||||
|
if (gpioExecutor!=null){
|
||||||
|
gpioExecutor.submit(()->{
|
||||||
|
pcf8574.SetPin(pinName);
|
||||||
|
try {
|
||||||
|
Thread.sleep(20);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
pcf8574.ClearPin(pinName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,10 +319,16 @@ public class Main {
|
|||||||
|
|
||||||
private static void init_Vapix(){
|
private static void init_Vapix(){
|
||||||
Properties config = SomeCodes.LoadProperties("config.properties");
|
Properties config = SomeCodes.LoadProperties("config.properties");
|
||||||
|
System.out.println("Saved Configuration for Camera");
|
||||||
String ip = config.getProperty("Camera_ip");
|
String ip = config.getProperty("Camera_ip");
|
||||||
String port = config.getProperty("Camera_port");
|
String port = config.getProperty("Camera_port");
|
||||||
String username = config.getProperty("Camera_user");
|
String username = config.getProperty("Camera_user");
|
||||||
String password = config.getProperty("Camera_password");
|
String password = config.getProperty("Camera_password");
|
||||||
|
System.out.println("Camera IP : "+ip);
|
||||||
|
System.out.println("Camera Port : "+port);
|
||||||
|
System.out.println("Camera Username : "+username);
|
||||||
|
System.out.println("Camera Password : "+password);
|
||||||
|
|
||||||
if (ValidString(ip)){
|
if (ValidString(ip)){
|
||||||
if (ValidPortNumber(port)){
|
if (ValidPortNumber(port)){
|
||||||
if (ValidString(username)){
|
if (ValidString(username)){
|
||||||
@@ -246,7 +344,7 @@ public class Main {
|
|||||||
} else Logger.error("PTZ Disabled");
|
} else Logger.error("PTZ Disabled");
|
||||||
Logger.info("Max Zoom: "+vapixProtocol.GetPTZMaxZoom());
|
Logger.info("Max Zoom: "+vapixProtocol.GetPTZMaxZoom());
|
||||||
Logger.info("Min Zoom: "+vapixProtocol.GetPTZMinZoom());
|
Logger.info("Min Zoom: "+vapixProtocol.GetPTZMinZoom());
|
||||||
Blink(LedIpCamera);
|
Blink_LedIpCamera();
|
||||||
} else Logger.error("Failed to query camera");
|
} else Logger.error("Failed to query camera");
|
||||||
} else Logger.error("Camera IP is not reachable");
|
} else Logger.error("Camera IP is not reachable");
|
||||||
} else Logger.error("Camera Password is not valid string");
|
} else Logger.error("Camera Password is not valid string");
|
||||||
@@ -255,15 +353,42 @@ public class Main {
|
|||||||
} else Logger.error( "Camera IP is not valid string");
|
} else Logger.error( "Camera IP is not valid string");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void test_pantiltcontroller(){
|
||||||
|
System.out.println("Pan Tilt Controller Test");
|
||||||
|
panTiltController.PanLeft((byte)0x20);
|
||||||
|
System.out.println("Pan Left");
|
||||||
|
Sleep(2000);
|
||||||
|
panTiltController.PanRight((byte)0x20);
|
||||||
|
System.out.println("Pan Right");
|
||||||
|
Sleep(2000);
|
||||||
|
panTiltController.StopMovement();
|
||||||
|
System.out.println("Stop Movement");
|
||||||
|
panTiltController.TiltUp((byte)0x20);
|
||||||
|
System.out.println("Tilt Up");
|
||||||
|
Sleep(2000);
|
||||||
|
panTiltController.TiltDown((byte)0x20);
|
||||||
|
System.out.println("Tilt Down");
|
||||||
|
Sleep(2000);
|
||||||
|
panTiltController.StopMovement();
|
||||||
|
System.out.println("Stop Movement");
|
||||||
|
panTiltController.GoToPreset((byte)0);
|
||||||
|
System.out.println("Go To Preset 0");
|
||||||
|
}
|
||||||
|
|
||||||
private static void init_pantiltcontroller() {
|
private static void init_pantiltcontroller() {
|
||||||
Properties config = SomeCodes.LoadProperties("config.properties");
|
Properties config = SomeCodes.LoadProperties("config.properties");
|
||||||
String portname = config.getProperty("SerialPort");
|
String portname = config.getProperty("SerialPort");
|
||||||
String baudrate = config.getProperty("SerialBaudRate");
|
String baudrate = config.getProperty("SerialBaudRate");
|
||||||
String PanTiltID = config.getProperty("PanTiltID");
|
String PanTiltID = config.getProperty("PanTiltID");
|
||||||
|
Logger.info("Saved Configuration for Pan Tilt Controller");
|
||||||
|
Logger.info("Serial Port : "+portname);
|
||||||
|
Logger.info("Serial Baud Rate : "+baudrate);
|
||||||
|
Logger.info("Pan Tilt ID : "+PanTiltID);
|
||||||
if (ValidString(portname)){
|
if (ValidString(portname)){
|
||||||
if (ValidInteger(baudrate)){
|
if (ValidInteger(baudrate)){
|
||||||
if (ValidInteger(PanTiltID)){
|
if (ValidInteger(PanTiltID)){
|
||||||
panTiltController = new PanTiltController(portname, Integer.parseInt(baudrate), Integer.parseInt(PanTiltID));
|
panTiltController = new PanTiltController(portname, Integer.parseInt(baudrate), Integer.parseInt(PanTiltID));
|
||||||
|
if (panTiltController.isOpen()) test_pantiltcontroller();
|
||||||
}
|
}
|
||||||
} else Logger.error("Invalid PTZ Baudrate");
|
} else Logger.error("Invalid PTZ Baudrate");
|
||||||
} else Logger.error("Invalid PTZ Port");
|
} else Logger.error("Invalid PTZ Port");
|
||||||
@@ -277,16 +402,18 @@ public class Main {
|
|||||||
Properties config = SomeCodes.LoadProperties("config.properties");
|
Properties config = SomeCodes.LoadProperties("config.properties");
|
||||||
String targetip = config.getProperty("Camera_ip");
|
String targetip = config.getProperty("Camera_ip");
|
||||||
String rtsppath = config.getProperty("Camera_Rtsp_path");
|
String rtsppath = config.getProperty("Camera_Rtsp_path");
|
||||||
|
System.out.println("Camera IP : "+targetip);
|
||||||
|
System.out.println("Camera Rtsp Path : "+rtsppath);
|
||||||
rtspGrabber = null;
|
rtspGrabber = null;
|
||||||
if (ValidString(targetip)){
|
if (ValidString(targetip)){
|
||||||
if (ValidString(rtsppath)){
|
if (ValidString(rtsppath)){
|
||||||
if (IpIsReachable(targetip)){
|
if (IpIsReachable(targetip)){
|
||||||
Logger.info("Camera IP is reachable");
|
Logger.info("Camera IP : "+targetip+" is reachable");
|
||||||
rtspGrabber = new RtspGrabber(targetip, rtsppath);
|
rtspGrabber = new RtspGrabber(targetip, rtsppath);
|
||||||
rtspGrabber.Start(true, 1920, 1080);
|
rtspGrabber.Start(true, 1920, 1080);
|
||||||
} else Logger.error("Camera IP is not reachable");
|
} else System.out.println("Camera IP : "+targetip+" is not reachable");
|
||||||
} else Logger.error("Camera Path is not valid string");
|
} else System.out.println("Camera Path : "+rtsppath+" is not valid string");
|
||||||
} else Logger.error("Camera IP is not valid string");
|
} else System.out.println("Camera IP : "+targetip+" is not valid string");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void init_audio() {
|
private static void init_audio() {
|
||||||
@@ -309,16 +436,19 @@ public class Main {
|
|||||||
@Override
|
@Override
|
||||||
public void onPlaybackStart(AudioFileProperties prop) {
|
public void onPlaybackStart(AudioFileProperties prop) {
|
||||||
Logger.info("Playback started for {}", prop.filename);
|
Logger.info("Playback started for {}", prop.filename);
|
||||||
|
AmplifierControl(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackFinished(AudioFileProperties prop) {
|
public void onPlaybackFinished(AudioFileProperties prop) {
|
||||||
Logger.info("Playback finished for {}", prop.filename);
|
Logger.info("Playback finished for {}", prop.filename);
|
||||||
|
AmplifierControl(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackFailure(AudioFileProperties prop, String reason) {
|
public void onPlaybackFailure(AudioFileProperties prop, String reason) {
|
||||||
Logger.error("Playback failed for {}: {}", prop.filename, reason);
|
Logger.error("Playback failed for {}: {}", prop.filename, reason);
|
||||||
|
AmplifierControl(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -335,7 +465,7 @@ public class Main {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WebsocketReply onWebsocketCommand(WebsocketCommand command) {
|
public WebsocketReply onWebsocketCommand(WebsocketCommand command) {
|
||||||
Blink(LedWeb);
|
Blink_LedWeb();
|
||||||
byte speed;
|
byte speed;
|
||||||
String cmd = command.command.toUpperCase().trim();
|
String cmd = command.command.toUpperCase().trim();
|
||||||
switch (cmd){
|
switch (cmd){
|
||||||
@@ -361,10 +491,10 @@ public class Main {
|
|||||||
return new WebsocketReply("STOP MOVEMENT", "");
|
return new WebsocketReply("STOP MOVEMENT", "");
|
||||||
// Audio Related Commands
|
// Audio Related Commands
|
||||||
case "MUTE":
|
case "MUTE":
|
||||||
audioPlayer.Mute();
|
if (audioPlayer!=null) audioPlayer.Mute();
|
||||||
return new WebsocketReply("MUTE", "");
|
return new WebsocketReply("MUTE", "");
|
||||||
case "UNMUTE":
|
case "UNMUTE":
|
||||||
audioPlayer.Unmute();
|
if (audioPlayer!=null) audioPlayer.Unmute();
|
||||||
return new WebsocketReply("UNMUTE", "");
|
return new WebsocketReply("UNMUTE", "");
|
||||||
case "SET VOLUME" :
|
case "SET VOLUME" :
|
||||||
int volume=-1;
|
int volume=-1;
|
||||||
@@ -374,11 +504,11 @@ public class Main {
|
|||||||
if (volume>100) volume = 100;
|
if (volume>100) volume = 100;
|
||||||
}
|
}
|
||||||
if (volume>=0){
|
if (volume>=0){
|
||||||
audioPlayer.setPlaybackvolume(volume);
|
if (audioPlayer!=null) audioPlayer.setPlaybackvolume(volume);
|
||||||
return new WebsocketReply("SET VOLUME", String.valueOf(volume));
|
return new WebsocketReply("SET VOLUME", String.valueOf(volume));
|
||||||
} else return new WebsocketReply("SET VOLUME", "Invalid Volume Value");
|
} else return new WebsocketReply("SET VOLUME", "Invalid Volume Value");
|
||||||
case "GET VOLUME" :
|
case "GET VOLUME" :
|
||||||
int vol = audioPlayer.getPlaybackvolume();
|
int vol = audioPlayer!=null ? audioPlayer.getPlaybackvolume() : 0;
|
||||||
return new WebsocketReply("GET VOLUME", String.valueOf(vol));
|
return new WebsocketReply("GET VOLUME", String.valueOf(vol));
|
||||||
case "PLAY AUDIO" :
|
case "PLAY AUDIO" :
|
||||||
if (ValidInteger(command.data)){
|
if (ValidInteger(command.data)){
|
||||||
@@ -391,7 +521,7 @@ public class Main {
|
|||||||
if (afp!=null){
|
if (afp!=null){
|
||||||
audioFileProperties = afp;
|
audioFileProperties = afp;
|
||||||
audioPlayer.PlayAudioFile(afp, true, pe);
|
audioPlayer.PlayAudioFile(afp, true, pe);
|
||||||
AmplifierControl(true);
|
//AmplifierControl(true);
|
||||||
return new WebsocketReply("PLAY AUDIO", afp.filename);
|
return new WebsocketReply("PLAY AUDIO", afp.filename);
|
||||||
|
|
||||||
} else return new WebsocketReply("PLAY AUDIO", "Failed to open audio file "+filename);
|
} else return new WebsocketReply("PLAY AUDIO", "Failed to open audio file "+filename);
|
||||||
@@ -403,18 +533,18 @@ public class Main {
|
|||||||
audioPlayer.CloseAudioFile(audioFileProperties); // close previous audio file
|
audioPlayer.CloseAudioFile(audioFileProperties); // close previous audio file
|
||||||
String filename = audioFileProperties.filename;
|
String filename = audioFileProperties.filename;
|
||||||
audioFileProperties = null;
|
audioFileProperties = null;
|
||||||
AmplifierControl(false);
|
//AmplifierControl(false);
|
||||||
return new WebsocketReply("STOP AUDIO", filename);
|
return new WebsocketReply("STOP AUDIO", filename);
|
||||||
} else return new WebsocketReply("STOP AUDIO", "No audioFileProperties");
|
} else return new WebsocketReply("STOP AUDIO", "No audioFileProperties");
|
||||||
// ZOOM Related Commands
|
// ZOOM Related Commands
|
||||||
case "GET MAX ZOOM":
|
case "GET MAX ZOOM":
|
||||||
if (vapixProtocol!=null){
|
if (vapixProtocol!=null){
|
||||||
Blink(LedIpCamera);
|
Blink_LedIpCamera();
|
||||||
return new WebsocketReply("GET MAX ZOOM", String.valueOf(vapixProtocol.GetPTZMaxZoom()));
|
return new WebsocketReply("GET MAX ZOOM", String.valueOf(vapixProtocol.GetPTZMaxZoom()));
|
||||||
} else return new WebsocketReply("GET MAX ZOOM", "VapixProtocol not initialized");
|
} else return new WebsocketReply("GET MAX ZOOM", "VapixProtocol not initialized");
|
||||||
case "GET ZOOM":
|
case "GET ZOOM":
|
||||||
if (vapixProtocol!=null){
|
if (vapixProtocol!=null){
|
||||||
Blink(LedIpCamera);
|
Blink_LedIpCamera();
|
||||||
return new WebsocketReply("GET ZOOM", String.valueOf(vapixProtocol.GetCurrentZoomValue()));
|
return new WebsocketReply("GET ZOOM", String.valueOf(vapixProtocol.GetCurrentZoomValue()));
|
||||||
} else return new WebsocketReply("GET ZOOM", "VapixProtocol not initialized");
|
} else return new WebsocketReply("GET ZOOM", "VapixProtocol not initialized");
|
||||||
case "SET ZOOM":
|
case "SET ZOOM":
|
||||||
@@ -424,7 +554,7 @@ public class Main {
|
|||||||
if (zoom<vapixProtocol.GetPTZMinZoom()) zoom = vapixProtocol.GetPTZMinZoom();
|
if (zoom<vapixProtocol.GetPTZMinZoom()) zoom = vapixProtocol.GetPTZMinZoom();
|
||||||
if (zoom>vapixProtocol.GetPTZMaxZoom()) zoom = vapixProtocol.GetPTZMaxZoom();
|
if (zoom>vapixProtocol.GetPTZMaxZoom()) zoom = vapixProtocol.GetPTZMaxZoom();
|
||||||
if (vapixProtocol.Zoom(1, zoom)){
|
if (vapixProtocol.Zoom(1, zoom)){
|
||||||
Blink(LedIpCamera);
|
Blink_LedIpCamera();
|
||||||
return new WebsocketReply("ZOOM", String.valueOf(zoom));
|
return new WebsocketReply("ZOOM", String.valueOf(zoom));
|
||||||
} else return new WebsocketReply("ZOOM", "Failed to zoom");
|
} else return new WebsocketReply("ZOOM", "Failed to zoom");
|
||||||
} else return new WebsocketReply("ZOOM", "Invalid Zoom Value");
|
} else return new WebsocketReply("ZOOM", "Invalid Zoom Value");
|
||||||
@@ -432,15 +562,21 @@ public class Main {
|
|||||||
// Live Streaming Related Commands
|
// Live Streaming Related Commands
|
||||||
case "GET BASE64":
|
case "GET BASE64":
|
||||||
if (rtspGrabber!=null){
|
if (rtspGrabber!=null){
|
||||||
if (Objects.equals(command.data,"HQ"))
|
switch (command.data){
|
||||||
return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastHQBase64(), rtspGrabber.HQStreamingStatus());
|
case "HQ":
|
||||||
else
|
return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastHQBase64(), rtspGrabber.HQStreamingStatus());
|
||||||
return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastLQBase64(), rtspGrabber.LQStreamingStatus());
|
case "LQ":
|
||||||
|
return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastLQBase64(), rtspGrabber.LQStreamingStatus());
|
||||||
|
case "YOLO":
|
||||||
|
return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastYoloBase64(), rtspGrabber.HQStreamingStatus());
|
||||||
|
default:
|
||||||
|
return new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
|
||||||
|
}
|
||||||
} else return new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
|
} else return new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
|
||||||
case "GET RESOLUTION":
|
case "GET RESOLUTION":
|
||||||
if (vapixProtocol!=null){
|
if (vapixProtocol!=null){
|
||||||
int[] res = vapixProtocol.GetCurrentResolution(1);
|
int[] res = vapixProtocol.GetCurrentResolution(1);
|
||||||
Blink(LedIpCamera);
|
Blink_LedIpCamera();
|
||||||
return new WebsocketReply("GET RESOLUTION", String.format("%dx%d", res[0], res[1]));
|
return new WebsocketReply("GET RESOLUTION", String.format("%dx%d", res[0], res[1]));
|
||||||
} else return new WebsocketReply("GET RESOLUTION", "VapixProtocol not initialized");
|
} else return new WebsocketReply("GET RESOLUTION", "VapixProtocol not initialized");
|
||||||
case "GET AUDIOFILES":
|
case "GET AUDIOFILES":
|
||||||
|
|||||||
Reference in New Issue
Block a user