kopia lustrzana https://github.com/projecthorus/wenet
				
				
				
			Initial re-structure of repository.
							rodzic
							
								
									0625dfc5d1
								
							
						
					
					
						commit
						5002745874
					
				| 
						 | 
				
			
			@ -62,6 +62,7 @@ If not already done above, you will also need to clone the wenet repository:
 | 
			
		|||
> git clone https://github.com/projecthorus/wenet.git
 | 
			
		||||
 | 
			
		||||
We need some binaries from the codec2-dev repository:
 | 
			
		||||
(Note that we are using a specific revision number to ensure developmental changes don't break things.)
 | 
			
		||||
 | 
			
		||||
> svn checkout -r 2914 http://svn.code.sf.net/p/freetel/code/codec2-dev/
 | 
			
		||||
> cd codec2-dev
 | 
			
		||||
| 
						 | 
				
			
			@ -69,11 +70,11 @@ We need some binaries from the codec2-dev repository:
 | 
			
		|||
> cd build
 | 
			
		||||
> cmake ../
 | 
			
		||||
> make
 | 
			
		||||
> cp src/fsk_demod ~/wenet/
 | 
			
		||||
> cp src/drs232_ldpc ~/wenet/
 | 
			
		||||
> cp src/fsk_demod ~/wenet/rx/
 | 
			
		||||
> cp src/drs232_ldpc ~/wenet/rx/
 | 
			
		||||
 | 
			
		||||
We also need to copy out the FSK Demod GUI Utility from this repository
 | 
			
		||||
> cp ~/codec2-dev/octave/fskdemodgui.py ~/wenet/
 | 
			
		||||
> cp ~/codec2-dev/octave/fskdemodgui.py ~/wenet/rx/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CALLSIGN AND SHORTCUTS SETUP
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +92,7 @@ If you are using a RTLSDR V3 and need the bias-tee enabled, uncomment the marked
 | 
			
		|||
 | 
			
		||||
Next, copy the two .desktop files to your desktop by running:
 | 
			
		||||
 | 
			
		||||
> cp *.desktop ~/Desktop/
 | 
			
		||||
> cp rx/*.desktop ~/Desktop/
 | 
			
		||||
 | 
			
		||||
If your username is somethign other than 'wenet', you will need to edit the Start_SSDV.desktop file, 
 | 
			
		||||
so that the 'Exec='' line contains the correct path to start_rx.sh
 | 
			
		||||
| 
						 | 
				
			
			@ -115,6 +116,7 @@ You can kill all the RX processed by running the 'Kill RX' shortcut on the deskt
 | 
			
		|||
If you have a recorded sample, you can replay it by doing:
 | 
			
		||||
 | 
			
		||||
Opening the SSDV Viewer GUI by running:
 | 
			
		||||
> cd rx
 | 
			
		||||
> python rx_gui.py &
 | 
			
		||||
 | 
			
		||||
Then 'playback' the sample file using:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,13 +3,16 @@
 | 
			
		|||
#	Receiver Test Script.
 | 
			
		||||
#	Feeds a list of test images into the receiver code, via stdout/stdin.
 | 
			
		||||
#
 | 
			
		||||
#	Run using: 
 | 
			
		||||
#		python rx_tester.py | python rx_ssdv.py 
 | 
			
		||||
#
 | 
			
		||||
#	Mark Jessop <vk5qi@rfhead.net>
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import time, sys, os
 | 
			
		||||
 | 
			
		||||
# Set to whatever resolution you want to test.
 | 
			
		||||
file_path = "./test_images/%d_raw.ssdv" # _raw, _800x608, _640x480, _320x240
 | 
			
		||||
file_path = "../test_images/%d_raw.ssdv" # _raw, _800x608, _640x480, _320x240
 | 
			
		||||
image_numbers = xrange(1,14)
 | 
			
		||||
 | 
			
		||||
print_as_hex = False
 | 
			
		||||
							
								
								
									
										24
									
								
								start_rx.sh
								
								
								
								
							
							
						
						
									
										24
									
								
								start_rx.sh
								
								
								
								
							| 
						 | 
				
			
			@ -1,14 +1,32 @@
 | 
			
		|||
#!/bin/bash
 | 
			
		||||
#
 | 
			
		||||
#	Start RX using a rtlsdr.
 | 
			
		||||
#	Wenet RX-side Initialisation Script
 | 
			
		||||
#	2016-12-05 Mark Jessop <vk5qi@rfhead.net>
 | 
			
		||||
#
 | 
			
		||||
#	This assumes an RTLSDR will be used for RX.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# Set CHANGEME to your callsign.
 | 
			
		||||
MYCALL=CHANGEME
 | 
			
		||||
 | 
			
		||||
cd ~/wenet/
 | 
			
		||||
# Change the following path as appropriate.
 | 
			
		||||
# If running this from a .desktop file, you may need to set an absolute path here
 | 
			
		||||
# i.e. /home/username/wenet/rx/
 | 
			
		||||
cd ~/wenet/rx/
 | 
			
		||||
 | 
			
		||||
# Start up the SSDV Uploader script and push it into the background.
 | 
			
		||||
python ssdv_upload.py $MYCALL &
 | 
			
		||||
 | 
			
		||||
# Start the SSDV RX GUI.
 | 
			
		||||
python rx_gui.py &
 | 
			
		||||
 | 
			
		||||
# Uncomment the following line if using a V3 RTLSDR and need the Bias-Tee enabled.
 | 
			
		||||
# rtl_biast -b 1 
 | 
			
		||||
rtl_sdr -s 923096 -f 440980000 -g 35 - | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.05 0.45 0.05 | csdr realpart_cf | csdr gain_ff 0.5 | csdr convert_f_s16 | ./fsk_demod 2XS 8 923096 115387 - - S 2> >(python fskdemodgui.py --wide) | ./drs232_ldpc - -  -vv| python rx_ssdv.py --partialupdate 16
 | 
			
		||||
 | 
			
		||||
# Start up the receive chain. 
 | 
			
		||||
rtl_sdr -s 923096 -f 440980000 -g 35 - | csdr convert_u8_f | \
 | 
			
		||||
csdr bandpass_fir_fft_cc 0.05 0.45 0.05 | csdr realpart_cf | \
 | 
			
		||||
csdr gain_ff 0.5 | csdr convert_f_s16 | \
 | 
			
		||||
./fsk_demod 2XS 8 923096 115387 - - S 2> >(python fskdemodgui.py --wide) | \
 | 
			
		||||
./drs232_ldpc - -  -vv | \
 | 
			
		||||
python rx_ssdv.py --partialupdate 16
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										21
									
								
								start_tx.sh
								
								
								
								
							
							
						
						
									
										21
									
								
								start_tx.sh
								
								
								
								
							| 
						 | 
				
			
			@ -1,10 +1,23 @@
 | 
			
		|||
#!/bin/bash
 | 
			
		||||
#
 | 
			
		||||
#	Wenet TX-side Initialisation Script
 | 
			
		||||
#	2016-08-07 Mark Jessop <vk5qi@rfhead.net>
 | 
			
		||||
#	2016-12-05 Mark Jessop <vk5qi@rfhead.net>
 | 
			
		||||
#
 | 
			
		||||
#	Run this to set up an attached RFM22B and start transmitting!
 | 
			
		||||
#	Run this to set up an attached RFM22B/RFM98W and start transmitting!
 | 
			
		||||
#	Replace the transmit frequency and callsign with your own.
 | 
			
		||||
#
 | 
			
		||||
python init_rfm22b.py 441.200
 | 
			
		||||
python tx_picam.py VK5QI &
 | 
			
		||||
 | 
			
		||||
MYCALL=N0CALL
 | 
			
		||||
TXFREQ=441.200
 | 
			
		||||
 | 
			
		||||
# CHANGE THE FOLLOWING LINE TO REFLECT THE ACTUAL PATH TO THE TX FOLDER.
 | 
			
		||||
# i.e. it may be /home/username/dev/wenet/tx/
 | 
			
		||||
cd ~/wenet/tx/
 | 
			
		||||
 | 
			
		||||
#Uncomment to initialise a RFM22B
 | 
			
		||||
python init_rfm22b.py $TXFREQ
 | 
			
		||||
# Uncomment for use with a RFM98W
 | 
			
		||||
#python init_rfm98w.py $TXFREQ
 | 
			
		||||
 | 
			
		||||
# Start the main TX Script.
 | 
			
		||||
python tx_picam.py $MYCALL &
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,4 +31,4 @@ new_sizes.append("raw")
 | 
			
		|||
 | 
			
		||||
for x in image_numbers:
 | 
			
		||||
	for size in new_sizes:
 | 
			
		||||
		os.system("ssdv -e -c %s -i %d %d_%s.jpg %d_%s.ssdv" % (callsign,x,x,size,x,size))
 | 
			
		||||
		os.system("ssdv -e -n -q 6 -c %s -i %d %d_%s.jpg %d_%s.ssdv" % (callsign,x,x,size,x,size))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,14 @@
 | 
			
		|||
#!/usr/bin/env python
 | 
			
		||||
#!/usr/bin/env python2.7
 | 
			
		||||
#
 | 
			
		||||
# Serial Packet Transmitter Class
 | 
			
		||||
# Wenet Packet Transmitter Class
 | 
			
		||||
#
 | 
			
		||||
# Frames packets (preamble, unique word, checksum)
 | 
			
		||||
# and transmits them out of a serial port.
 | 
			
		||||
#
 | 
			
		||||
#	RPI UART Calibration
 | 
			
		||||
#	9600  -> 9600.1536
 | 
			
		||||
# RPI UART Calibration. Measured on a Rpi A+.
 | 
			
		||||
# YMMV with other RPi models.
 | 
			
		||||
#
 | 
			
		||||
#	 9600 -> 9600.1536
 | 
			
		||||
#	19200 -> 19200.307
 | 
			
		||||
#	38400 -> 38339.148
 | 
			
		||||
#	57600 -> 57693.417
 | 
			
		||||
| 
						 | 
				
			
			@ -16,60 +18,73 @@
 | 
			
		|||
#
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import serial,Queue,sys,crcmod,struct
 | 
			
		||||
import serial
 | 
			
		||||
import Queue
 | 
			
		||||
import sys
 | 
			
		||||
import crcmod
 | 
			
		||||
import struct
 | 
			
		||||
from time import sleep
 | 
			
		||||
from threading import Thread
 | 
			
		||||
import numpy as np
 | 
			
		||||
from ldpc_encoder import *
 | 
			
		||||
 | 
			
		||||
# Alternate output module, which writes transmitted data as one-bit-per-char (i.e. 0 = 0x00, 1 = 0x01)
 | 
			
		||||
# to a file. Very useful for debugging.
 | 
			
		||||
class BinaryDebug(object):
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		self.f = open("debug.bin",'wb')
 | 
			
		||||
 | 
			
		||||
	def write(self,data):
 | 
			
		||||
		# TODO: Add in RS232 framing
 | 
			
		||||
		raw_data = np.array([],dtype=np.uint8)
 | 
			
		||||
		for d in data:
 | 
			
		||||
			d_array = np.unpackbits(np.fromstring(d,dtype=np.uint8))
 | 
			
		||||
			raw_data = np.concatenate((raw_data,[0],d_array[::-1],[1]))
 | 
			
		||||
 | 
			
		||||
		self.f.write(raw_data.astype(np.uint8).tostring())
 | 
			
		||||
 | 
			
		||||
	def close(self):
 | 
			
		||||
		self.f.close()
 | 
			
		||||
 | 
			
		||||
def write_debug_message(message, debug_file = "tx_idle_message.txt"):
 | 
			
		||||
	#f = open(debug_file,'w')
 | 
			
		||||
	#f.write(message)
 | 
			
		||||
	#f.close()
 | 
			
		||||
	print("DEBUG MSG: %s" % message)
 | 
			
		||||
 | 
			
		||||
class PacketTX(object):
 | 
			
		||||
	txqueue = Queue.Queue(4096) # Up to 1MB of 256 byte packets
 | 
			
		||||
	transmit_active = False
 | 
			
		||||
	debug = False
 | 
			
		||||
	""" Packet Transmitter Class
 | 
			
		||||
 | 
			
		||||
	The core of the Wenet transmitter stack.
 | 
			
		||||
	This class handles framing, FEC, and transmission of packets via a
 | 
			
		||||
	serial port. 
 | 
			
		||||
 | 
			
		||||
	Intended to be used with the David Rowe's fsk_demod software, with receiver
 | 
			
		||||
	glue code available in the 'rx' directory of this repository.
 | 
			
		||||
 | 
			
		||||
	Packet framing is as follows:
 | 
			
		||||
		Preamble: 16 repeats of 0x55. May not be required, but helps with timing estimation on the demod.
 | 
			
		||||
		Unique Word: 0xABCDEF01  Used for packet detection in the demod chain.
 | 
			
		||||
		Packet: 256 bytes of arbitrary binary data.
 | 
			
		||||
		Checksum: CRC16 checksum.
 | 
			
		||||
		Parity bits: 516 bits (zero-padded to 65 bytes) of LDPC parity bits, using a r=0.8 Repeat-accumulate code, developed by
 | 
			
		||||
					 Bill Cowley, VK5DSP. See ldpc_enc.c for more details.
 | 
			
		||||
 | 
			
		||||
	Packets are transmitted from two queues, named 'telemetry' and 'ssdv'.
 | 
			
		||||
	The 'telemetry' queue is intended for immediate transmission of low-latency telemetry packets,
 | 
			
		||||
	for example, GPS or IMU data. Care must be taken to not over-use this queue, at the detriment of image transmission.
 | 
			
		||||
	The 'ssdv' queue is used for transmission of large amounts of image (SSDV) data, and up to 4096 packets can be queued for transmit.
 | 
			
		||||
 | 
			
		||||
	"""
 | 
			
		||||
 | 
			
		||||
	# Transmit Queues.
 | 
			
		||||
	ssdv_queue = Queue.Queue(4096) # Up to 1MB of 256 byte packets
 | 
			
		||||
	telemetry_queue = Queue.Queue(16) # Keep this queue small. It's up to the user not to over-use this queue.
 | 
			
		||||
 | 
			
		||||
	# Framing parameters
 | 
			
		||||
	unique_word = "\xab\xcd\xef\x01"
 | 
			
		||||
	preamble = "\x55"*16
 | 
			
		||||
 | 
			
		||||
	# Idle sequence, transmitted if there is nothing in the transmit queues.
 | 
			
		||||
	idle_sequence = "\x55"*256
 | 
			
		||||
 | 
			
		||||
	# Transmit thread active flag.
 | 
			
		||||
	transmit_active = False
 | 
			
		||||
 | 
			
		||||
	def __init__(self,serial_port="/dev/ttyAMA0", serial_baud=115200, payload_length=256, fec=False, debug = False, callsign="N0CALL"):
 | 
			
		||||
		# WARNING: 115200 baud is ACTUALLY 115386.834 baud, as measured using a freq counter.
 | 
			
		||||
	# WARNING: 115200 baud is ACTUALLY 115386.834 baud, as measured using a freq counter.
 | 
			
		||||
	def __init__(self,serial_port="/dev/ttyAMA0", serial_baud=115200, payload_length=256, fec=True, debug = False, callsign="N0CALL"):
 | 
			
		||||
		
 | 
			
		||||
		# Instantiate our low-level transmit interface, be it a serial port, or the BinaryDebug class.
 | 
			
		||||
		if debug == True:
 | 
			
		||||
			self.s = BinaryDebug()
 | 
			
		||||
			self.debug = True
 | 
			
		||||
		else:
 | 
			
		||||
			self.s = serial.Serial(serial_port,serial_baud)
 | 
			
		||||
		self.payload_length = payload_length
 | 
			
		||||
 | 
			
		||||
		self.crc16 = crcmod.predefined.mkCrcFun('crc-ccitt-false')
 | 
			
		||||
 | 
			
		||||
		self.payload_length = payload_length
 | 
			
		||||
		self.callsign = callsign
 | 
			
		||||
		self.idle_message = "DE %s" % callsign
 | 
			
		||||
		self.fec = fec
 | 
			
		||||
 | 
			
		||||
		self.crc16 = crcmod.predefined.mkCrcFun('crc-ccitt-false')
 | 
			
		||||
 | 
			
		||||
	def start_tx(self):
 | 
			
		||||
		self.transmit_active = True
 | 
			
		||||
		txthread = Thread(target=self.tx_thread)
 | 
			
		||||
| 
						 | 
				
			
			@ -96,23 +111,29 @@ class PacketTX(object):
 | 
			
		|||
		self.idle_message = self.frame_packet(temp_msg,fec=self.fec)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	# Either generate an idle message, or read one in from a file (tx_idle_message.txt) if it exists.
 | 
			
		||||
	# This might be a useful way of getting error messages down from the payload.
 | 
			
		||||
	def generate_idle_message(self):
 | 
			
		||||
		# Append a \x00 control code before the data
 | 
			
		||||
		return "\x00" + "DE %s: \t%s" % (self.callsign,self.idle_message)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	def tx_thread(self):
 | 
			
		||||
		""" Main Transmit Thread.
 | 
			
		||||
			
 | 
			
		||||
			Checks telemetry and image queues in order, and transmits a packet.
 | 
			
		||||
		"""
 | 
			
		||||
		while self.transmit_active:
 | 
			
		||||
			if self.txqueue.qsize()>0:
 | 
			
		||||
				packet = self.txqueue.get_nowait()
 | 
			
		||||
			if self.telemetry_queue.qsize()>0:
 | 
			
		||||
				packet = self.telemetry_queue.get_nowait()
 | 
			
		||||
				self.s.write(packet)
 | 
			
		||||
			elif self.image_queue.qsize()>0:
 | 
			
		||||
				packet = self.image_queue.get_nowait()
 | 
			
		||||
				self.s.write(packet)
 | 
			
		||||
			else:
 | 
			
		||||
				if not self.debug:
 | 
			
		||||
					#self.s.write(self.idle_sequence)
 | 
			
		||||
					self.s.write(self.idle_message)
 | 
			
		||||
				else:
 | 
			
		||||
					# TODO: Tune this value. Ideally we should be doing a non-blocking 
 | 
			
		||||
					sleep(0.05)
 | 
			
		||||
		
 | 
			
		||||
		print("Closing Thread")
 | 
			
		||||
| 
						 | 
				
			
			@ -134,3 +155,23 @@ class PacketTX(object):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BinaryDebug(object):
 | 
			
		||||
	""" Debug binary 'transmitter' Class
 | 
			
		||||
	Used to write packet data to a file in one-bit-per-char (i.e. 0 = 0x00, 1 = 0x01)
 | 
			
		||||
	format for use with codec2-dev's fsk modulator.
 | 
			
		||||
	Useful for debugging, that's about it.
 | 
			
		||||
	"""
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		self.f = open("debug.bin",'wb')
 | 
			
		||||
 | 
			
		||||
	def write(self,data):
 | 
			
		||||
		# TODO: Add in RS232 framing
 | 
			
		||||
		raw_data = np.array([],dtype=np.uint8)
 | 
			
		||||
		for d in data:
 | 
			
		||||
			d_array = np.unpackbits(np.fromstring(d,dtype=np.uint8))
 | 
			
		||||
			raw_data = np.concatenate((raw_data,[0],d_array[::-1],[1]))
 | 
			
		||||
 | 
			
		||||
		self.f.write(raw_data.astype(np.uint8).tostring())
 | 
			
		||||
 | 
			
		||||
	def close(self):
 | 
			
		||||
		self.f.close()
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ try:
 | 
			
		|||
		tx.set_idle_message("Converting Image to SSDV...")
 | 
			
		||||
		#os.system("convert temp.jpg -resize %s\! temp.jpg" % tx_resolution)
 | 
			
		||||
		# SSDV'ify the image.
 | 
			
		||||
		os.system("ssdv -e -n -c %s -i %d ./tx_images/%s.jpg temp.ssdv" % (callsign,image_id,capture_time))
 | 
			
		||||
		os.system("ssdv -e -n -q 6 -c %s -i %d ./tx_images/%s.jpg temp.ssdv" % (callsign,image_id,capture_time))
 | 
			
		||||
		# Transmit image
 | 
			
		||||
		print("Transmitting...")
 | 
			
		||||
		transmit_file("temp.ssdv",tx)
 | 
			
		||||
| 
						 | 
				
			
			@ -9,7 +9,7 @@
 | 
			
		|||
import PacketTX,  sys, os
 | 
			
		||||
 | 
			
		||||
# Set to whatever resolution you want to test.
 | 
			
		||||
file_path = "./test_images/%d_raw.ssdv" # _raw, _800x608, _640x480, _320x240
 | 
			
		||||
file_path = "../test_images/%d_raw.ssdv" # _raw, _800x608, _640x480, _320x240
 | 
			
		||||
image_numbers = xrange(1,14)
 | 
			
		||||
 | 
			
		||||
debug_output = True # If True, packet bits are saved to debug.bin as one char per bit.
 | 
			
		||||
		Ładowanie…
	
		Reference in New Issue