Skip to content

Commit

Permalink
Photo Mode Skeleton
Browse files Browse the repository at this point in the history
The start of a Photo mode that allows full-resolution images to be captured locally on the device running Rpanion
  • Loading branch information
ddd999 authored and ddd999 committed May 28, 2024
1 parent f6dd036 commit 68af2ee
Show file tree
Hide file tree
Showing 4 changed files with 358 additions and 150 deletions.
47 changes: 47 additions & 0 deletions python/capture_still.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env python3

from picamera2 import Picamera2
from argparse import ArgumentParser
import time, signal, os

parser = ArgumentParser()
parser.add_argument("-f", "--filename", dest="filename",
help="Save captured image to FILE", metavar="FILE")
args = parser.parse_args()

pid = os.getpid()
GOT_SIGNAL = 0

def receive_signal(signum, stack):
global GOT_SIGNAL
GOT_SIGNAL = 1

# Initialize the camera
picam2 = Picamera2()
config = picam2.create_still_configuration(
main={"size": picam2.sensor_resolution},
buffer_count=2
)
picam2.configure(config)
# Keep the camera active to make responses faster
picam2.start()

print("Waiting 2 seconds for camera to stabilize...")
time.sleep(2)
print("Camera is ready")

# Register the signal handler function
signal.signal(signal.SIGUSR1, receive_signal)
print("PID is : ", pid)

# Wait for a signal to arrive
while True:
if GOT_SIGNAL == 1:
print("Received signal.SIGUSR1. Capturing photo.")
filename = time.strftime("RPN%Y%m%d_%H%M%S.jpg")
print(filename)
output_orig = picam2.capture_file(filename)
GOT_SIGNAL = 0
#time.sleep(1)
# Wait for a signal
signal.pause()
35 changes: 33 additions & 2 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,33 @@ vManager.eventEmitter.on('videostreaminfo', (msg, senderSysId, senderCompId, tar
}
})

// Got a CAMERA_SETTINGS event, send to flight controller
vManager.eventEmitter.on('camerasettings', (msg, senderSysId, senderCompId, targetComponent) => {
try {
if (fcManager.m) {
fcManager.m.sendCommandAck(common.CameraSettings.MSG_ID, 0, senderSysId, senderCompId, targetComponent)
fcManager.m.sendData(msg, senderCompId)
}
} catch (err) {
console.log(err)
}
})

// Got a DO_DIGICAM_CONTROL event, send to flight controller
//vManager.eventEmitter.on('digicamcontrol', (msg, senderSysId, senderCompId, targetComponent) => {
vManager.eventEmitter.on('digicamcontrol', (senderSysId, senderCompId, targetComponent) => {
console.log("index.js:digicamcontrol event received")
try {
if (fcManager.m) {
// 203 = MAV_CMD_DO_DIGICAM_CONTROL
fcManager.m.sendCommandAck(203, 0, senderSysId, senderCompId, targetComponent)
//fcManager.m.sendData(msg, senderCompId)
}
} catch (err) {
console.log(err)
}
})

// Connecting the flight controller datastream to the logger
// and ntrip and video
fcManager.eventEmitter.on('gotMessage', (packet, data) => {
Expand Down Expand Up @@ -428,7 +455,7 @@ app.get('/api/softwareinfo', (req, res) => {

app.get('/api/videodevices', (req, res) => {
vManager.populateAddresses()
vManager.getVideoDevices((err, devices, active, seldevice, selRes, selRot, selbitrate, selfps, SeluseUDP, SeluseUDPIP, SeluseUDPPort, timestamp, fps, FPSMax, vidres, useCameraHeartbeat, selMavURI) => {
vManager.getVideoDevices((err, devices, active, seldevice, selRes, selRot, selbitrate, selfps, SeluseUDP, SelusePhotoMode, SeluseUDPIP, SeluseUDPPort, timestamp, fps, FPSMax, vidres, useCameraHeartbeat, useMavControl, selMavURI) => {
if (!err) {
res.setHeader('Content-Type', 'application/json')
res.send(JSON.stringify({
Expand All @@ -443,13 +470,15 @@ app.get('/api/videodevices', (req, res) => {
bitrate: selbitrate,
fpsSelected: selfps,
UDPChecked: SeluseUDP,
photoMode: SelusePhotoMode,
useUDPIP: SeluseUDPIP,
useUDPPort: SeluseUDPPort,
timestamp,
error: null,
fps: fps,
FPSMax: FPSMax,
enableCameraHeartbeat: useCameraHeartbeat,
enableMavControl: useMavControl,
mavStreamSelected: selMavURI
}))
} else {
Expand Down Expand Up @@ -697,8 +726,10 @@ app.post('/api/startstopvideo', [check('active').isBoolean(),
check('height').if(check('active').isIn([true])).isInt({ min: 1 }),
check('width').if(check('active').isIn([true])).isInt({ min: 1 }),
check('useUDP').if(check('active').isIn([true])).isBoolean(),
check('usePhotoMode').if(check('active').isIn([true])).isBoolean(),
check('useTimestamp').if(check('active').isIn([true])).isBoolean(),
check('useCameraHeartbeat').if(check('active').isIn([true])).isBoolean(),
check('useMavControl').if(check('active').isIn([true])).isBoolean(),
check('useUDPPort').if(check('active').isIn([true])).isPort(),
check('useUDPIP').if(check('active').isIn([true])).isIP(),
check('bitrate').if(check('active').isIn([true])).isInt({ min: 50, max: 50000 }),
Expand All @@ -712,7 +743,7 @@ app.post('/api/startstopvideo', [check('active').isBoolean(),
return res.status(422).json(ret)
}
// user wants to start/stop video streaming
vManager.startStopStreaming(req.body.active, req.body.device, req.body.height, req.body.width, req.body.format, req.body.rotation, req.body.bitrate, req.body.fps, req.body.useUDP, req.body.useUDPIP, req.body.useUDPPort, req.body.useTimestamp, req.body.useCameraHeartbeat, req.body.mavStreamSelected, (err, status, addresses) => {
vManager.startStopStreaming(req.body.active, req.body.device, req.body.height, req.body.width, req.body.format, req.body.rotation, req.body.bitrate, req.body.fps, req.body.useUDP, req.body.usePhotoMode, req.body.useUDPIP, req.body.useUDPPort, req.body.useTimestamp, req.body.useCameraHeartbeat, req.body.useMavControl, req.body.mavStreamSelected, (err, status, addresses) => {
if (!err) {
res.setHeader('Content-Type', 'application/json')
const ret = { streamingStatus: status, streamAddresses: addresses }
Expand Down
Loading

0 comments on commit 68af2ee

Please sign in to comment.