Commit 4dc29852 authored by Mohd Bilal's avatar Mohd Bilal
Browse files

added gr-timgsn

parent 0936721e
......@@ -32,4 +32,8 @@ node_modules
#gnuradio
# do not upload recordings
*.wav
\ No newline at end of file
*.wav
# build
build/**
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2019 gr-fsk author.
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this software; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
import numpy
import pmt
import threading
import time
from gnuradio import gr
from skyfield.api import Topos, load
from pytz import timezone
import datetime
#Calculate doppler shift for a given speed and velocity with moving transmitter, stationary receiver
def dopplerShift(vel, f0):
c = 299792458
return f0 * ((c / (c+vel)) - 1)
class doppler_correct(gr.sync_block):
"""
Is configured with Satellite and groundstation location. Puts out doppler shift between gs and sat at system time once per second
"""
def __init__(self, sat, gs_lat, gs_long, f0, tz):
gr.sync_block.__init__(self,
name="doppler_correct_f",
in_sig=None,
out_sig=None)
self.message_port_register_out(pmt.intern('Freq_Offset'))
self.f0 = f0
self.gs = Topos(latitude_degrees = gs_lat, longitude_degrees = gs_long)
stations_url = 'http://celestrak.com/NORAD/elements/active.txt'
satellites = load.tle_file(stations_url)
by_number = {sat.model.satnum: sat for sat in satellites}
self.sat = by_number[sat]
self.dif = self.sat - self.gs
self.ts = load.timescale()
self.tz = timezone(tz)
self.verbose = False
#Check if TLE Date is less than 14 days old if not reload
t = self.ts.utc(self.tz.localize(datetime.datetime.now()))
days = t - self.sat.epoch
if abs(days) > 2:
satellites = load.tle(stations_url, reload=True)
self.sat = satellites['UWE-4']
self.time_now = datetime.datetime.utcnow()
# Start Thread for putting out Frequencies and doppler
thread = threading.Thread(target=self.loop, args=())
thread.daemon = True
thread.start()
def loop(self):
while True:
time.sleep(0.5)
t = self.ts.utc(self.tz.localize(datetime.datetime.now()))
#Calculate relative topocentric position for timespan t
topoc = self.dif.at(t)
d = topoc.position.km
#Calculate Speed relative to groundstation
d_norm = d / numpy.linalg.norm(d,axis = 0)
speed_v = numpy.multiply(d_norm, topoc.velocity.km_per_s)
speed = numpy.sum(speed_v, axis = 0)
#Compute doppler shift
dS = dopplerShift(speed * 1000, self.f0)
self.message_port_pub(pmt.intern('Freq_Offset'), pmt.from_float(-dS))
\ No newline at end of file
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: GPL-3.0
#
# GNU Radio Python Flow Graph
# Title: dd
# Author: tim
# GNU Radio version: 3.8.1.0
from gnuradio import analog
from gnuradio import blocks
from gnuradio import filter
from gnuradio.filter import firdes
from gnuradio import gr
import sys
import signal
from argparse import ArgumentParser
from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
from app.gnuradio.flowgraphs.doppler_correct import doppler_correct
from app.gnuradio.flowgraphs.packet_sender import TIM_packet_submit
import osmosdr
import time
import satellites.core
import json
def loadParameters(context, file, kwargs):
f = open(file, 'r')
j = json.load(f)
paramDict = j['client']['users'][0]
commonVariables = list(set(paramDict.keys()) & set(context.__dict__.keys()))
for var in commonVariables:
context.__dict__[var] = paramDict[var]
commonVariables = list(set(kwargs.keys()) & set(context.__dict__.keys()))
for var in commonVariables:
context.__dict__[var] = kwargs[var]
class Receiver(gr.top_block):
def __init__(self, **kwarg):
gr.top_block.__init__(self, "dd")
##################################################
# Variables
##################################################
self.username_env = kwarg["username"]
self.station_long = kwarg["station_long"]
self.station_lat = kwarg["station_lat"]
self.sat_freq = kwarg["sat_freq"]
self.samp_rate = kwarg["samp_rate"] if "samp_rate" in kwarg else 200000
self.rf_gain = kwarg["rf_gain"] if "rf_gain" in kwarg else 10
self.password_env = kwarg["password"]
self.overpass_uid = kwarg["overpass_uid"]
self.norad_id = kwarg["norad_id"]
self.if_gain = kwarg["if_gain"] if "if_gain" in kwarg else 20
self.gsn_name = kwarg["gsn_name"]
self.device_arg = kwarg["device_arg"]
self.bb_gain = kwarg["if_gain"] if "if_gain" in kwarg else 20
self.timezone = "Berlin/Europe"
if 'settings_fpath' not in kwarg:
raise FileNotFoundError("Cannot start receiver. "
"Path to settings file not provided")
self.settings_fpath = kwarg['settings_fpath']
##################################################
# Blocks
##################################################
loadParameters(self, self.settings_fpath, kwarg)
self.satellites_satellite_decoder_0 = satellites.core.gr_satellites_flowgraph(file = '/home/sdrgs/Documents/gnuradio/gr-satellites/python/satyaml/UWE-4.yml', samp_rate = self.samp_rate/2, grc_block = True, iq = True, options = "")
self.osmosdr_source_0 = osmosdr.source(
args="numchan=" + str(1) + " " + self.device_arg
)
self.osmosdr_source_0.set_sample_rate(self.samp_rate)
self.osmosdr_source_0.set_center_freq(self.sat_freq - 50e3, 0)
self.osmosdr_source_0.set_freq_corr(0, 0)
self.osmosdr_source_0.set_gain(self.rf_gain, 0)
self.osmosdr_source_0.set_if_gain(self.if_gain, 0)
self.osmosdr_source_0.set_bb_gain(self.bb_gain, 0)
self.osmosdr_source_0.set_antenna('', 0)
self.osmosdr_source_0.set_bandwidth(0, 0)
self.low_pass_filter_0 = filter.fir_filter_ccf(
2,
firdes.low_pass(
1,
100e3,
8e3,
1e3,
firdes.WIN_HAMMING,
6.76))
self.timgsn_doppler_correct_0 = doppler_correct(self.norad_id, self.station_long, self.station_lat, self.sat_freq, self.timezone)
self.timgsn_TIM_packet_submit_0 = TIM_packet_submit(self.station_long, self.station_lat, self.norad_id, self.gsn_name, self.username_env, self.password_env, self.overpass_uid)
self.blocks_multiply_xx_0_0_0 = blocks.multiply_vcc(1)
self.blocks_multiply_xx_0_0 = blocks.multiply_vcc(1)
self.analog_sig_source_x_0_0_0 = analog.sig_source_c(self.samp_rate, analog.GR_COS_WAVE, -50e3, 1, 0, 0)
self.analog_sig_source_x_0_0 = analog.sig_source_c(self.samp_rate, analog.GR_COS_WAVE, 0, 1, 0, 0)
self.analog_agc3_xx_0 = analog.agc3_cc(1e-3, 1e-4, 1.0, 1.0, 1)
self.analog_agc3_xx_0.set_max_gain(65536)
##################################################
# Connections
##################################################
self.msg_connect((self.timgsn_doppler_correct_0, 'Freq_Offset'), (self.analog_sig_source_x_0_0, 'freq'))
self.msg_connect((self.satellites_satellite_decoder_0, 'out'), (self.timgsn_TIM_packet_submit_0, 'pckt'))
self.connect((self.analog_agc3_xx_0, 0), (self.satellites_satellite_decoder_0, 0))
self.connect((self.analog_sig_source_x_0_0, 0), (self.blocks_multiply_xx_0_0, 0))
self.connect((self.analog_sig_source_x_0_0_0, 0), (self.blocks_multiply_xx_0_0_0, 0))
self.connect((self.blocks_multiply_xx_0_0, 0), (self.blocks_multiply_xx_0_0_0, 1))
self.connect((self.blocks_multiply_xx_0_0_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.analog_agc3_xx_0, 0))
self.connect((self.osmosdr_source_0, 0), (self.blocks_multiply_xx_0_0, 1))
def get_username(self):
return self.username
def set_username(self, username):
self.username = username
def get_station_long(self):
return self.station_long
def set_station_long(self, station_long):
self.station_long = station_long
def get_station_lat(self):
return self.station_lat
def set_station_lat(self, station_lat):
self.station_lat = station_lat
def get_sat_freq(self):
return self.sat_freq
def set_sat_freq(self, sat_freq):
self.sat_freq = sat_freq
self.osmosdr_source_0.set_center_freq(self.sat_freq - 50e3, 0)
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.analog_sig_source_x_0_0.set_sampling_freq(self.samp_rate)
self.analog_sig_source_x_0_0_0.set_sampling_freq(self.samp_rate)
self.osmosdr_source_0.set_sample_rate(self.samp_rate)
def get_rf_gain(self):
return self.rf_gain
def set_rf_gain(self, rf_gain):
self.rf_gain = rf_gain
self.osmosdr_source_0.set_gain(self.rf_gain, 0)
def get_password(self):
return self.password
def set_password(self, password):
self.password = password
def get_overpass_uid(self):
return self.overpass_uid
def set_overpass_uid(self, overpass_uid):
self.overpass_uid = overpass_uid
self.timgsn_TIM_packet_submit_0.set_overpass_uid(overpass_uid)
def get_norad_id(self):
return self.norad_id
def set_norad_id(self, norad_id):
self.norad_id = norad_id
def get_if_gain(self):
return self.if_gain
def set_if_gain(self, if_gain):
self.if_gain = if_gain
self.osmosdr_source_0.set_if_gain(self.if_gain, 0)
def get_gsn_name(self):
return self.gsn_name
def set_gsn_name(self, gsn_name):
self.gsn_name = gsn_name
def get_device_arg(self):
return self.device_arg
def set_device_arg(self, device_arg):
self.device_arg = device_arg
def get_bb_gain(self):
return self.bb_gain
def set_bb_gain(self, bb_gain):
self.bb_gain = bb_gain
self.osmosdr_source_0.set_bb_gain(self.bb_gain, 0)
def main(top_block_cls=Receiver, options=None):
if gr.enable_realtime_scheduling() != gr.RT_OK:
print("Error: failed to enable real-time scheduling.")
tb = top_block_cls()
def sig_handler(sig=None, frame=None):
tb.stop()
tb.wait()
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
tb.start()
try:
input('Press Enter to quit: ')
except EOFError:
pass
tb.stop()
tb.wait()
if __name__ == '__main__':
main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2021 Tim Horst.
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this software; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
import numpy
from gnuradio import gr
from io import BytesIO
import pmt
import requests
from datetime import datetime
class TIM_packet_submit(gr.sync_block):
"""
docstring for block TIM_packet_submit
"""
uni_wue_submit = [39446, 43880, 46504, 46505, 46507, 46506]
def __init__(self, gs_long, gs_lat, sat, gs_name, username, password, overpass_uid):
gr.sync_block.__init__(self,
name="TIM_packet_submit",
in_sig=None,
out_sig=None)
self.gs_long = str(gs_long) + "E" if gs_long > 0 else str(-gs_long) + "W"
self.gs_lat = str(gs_lat) + "N" if gs_lat > 0 else str(-gs_lat) + "S"
self.sat = sat
self.token = None
self.gs_name = gs_name
self.password = password
self.username = username
self.overpass_uid = overpass_uid
self.message_port_register_in(pmt.intern('pckt'))
self.set_msg_handler(pmt.intern("pckt"), self.handlePacket)
def set_overpass_uid(self, overpass_uid):
self.overpass_uid = overpass_uid
def handlePacket(self, pckt):
packet = bytes(bytearray(pmt.u8vector_elements(pmt.cdr(pckt))))
time_str = datetime.now().isoformat(timespec='milliseconds') + "Z"
if self.sat in self.uni_wue_submit:
url_base = 'http://robotik.informatik.uni-wuerzburg.de/uwe/report_frame.php'
payload = {'noradID':self.sat,
'source': self.gs_name,
'timestamp' : time_str,
'frame' : packet.hex(),
'locator' : 'longLat',
'longitude' : self.gs_long,
'latitude' : self.gs_lat}
f = requests.get(url_base, params=payload)
#Post packet data to TIM website
#TODO Change to right adress
URL = 'http://localhost:5000/api/data/telemetry'
data = {'format': 'DEMODULATED'}
files = {'file': BytesIO(packet)}
response = requests.post(f'{URL}/{self.overpass_uid}',
auth=(self.username, self.password),
data=data,
files=files)
try:
res_data = response.json()
except:
res_data = response.text
print(res_data)
# Copyright 2011,2012,2014,2016,2018 Free Software Foundation, Inc.
#
# This file was generated by gr_modtool, a tool from the GNU Radio framework
# This file is a part of gr-timgsn
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
########################################################################
# Project setup
########################################################################
cmake_minimum_required(VERSION 3.8)
project(gr-timgsn CXX C)
enable_testing()
# Install to PyBOMBS target prefix if defined
if(DEFINED ENV{PYBOMBS_PREFIX})
set(CMAKE_INSTALL_PREFIX $ENV{PYBOMBS_PREFIX})
message(STATUS "PyBOMBS installed GNU Radio. Setting CMAKE_INSTALL_PREFIX to $ENV{PYBOMBS_PREFIX}")
endif()
# Select the release build type by default to get optimization flags
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
message(STATUS "Build type not specified: defaulting to release.")
endif(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
# Make sure our local CMake Modules path comes first
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules)
# Set the version information here
set(VERSION_MAJOR 1)
set(VERSION_API 0)
set(VERSION_ABI 0)
set(VERSION_PATCH git)
cmake_policy(SET CMP0011 NEW)
# Enable generation of compile_commands.json for code completion engines
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
########################################################################
# Compiler specific setup
########################################################################
if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
AND NOT WIN32)
#http://gcc.gnu.org/wiki/Visibility
add_definitions(-fvisibility=hidden)
endif()
IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
SET(CMAKE_CXX_STANDARD 11)
ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET(CMAKE_CXX_STANDARD 11)
ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
SET(CMAKE_CXX_STANDARD 11)
ELSE()
message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.")
ENDIF()
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
SET(CMAKE_C_STANDARD 11)
ELSEIF(CMAKE_C_COMPILER_ID MATCHES "Clang")
SET(CMAKE_C_STANDARD 11)
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
SET(CMAKE_C_STANDARD 11)
ELSE()
message(WARNING "C standard could not be set because compiler is not GNU, Clang or MSVC.")
ENDIF()
########################################################################
# Install directories
########################################################################
find_package(Gnuradio "3.8" REQUIRED)
include(GrVersion)
include(GrPlatform) #define LIB_SUFFIX
if(NOT CMAKE_MODULES_DIR)
set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake)
endif(NOT CMAKE_MODULES_DIR)
set(GR_INCLUDE_DIR include/timgsn)
set(GR_CMAKE_DIR ${CMAKE_MODULES_DIR}/timgsn)
set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME})
set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME})
set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d)
set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME})
########################################################################
# On Apple only, set install name and use rpath correctly, if not already set
########################################################################
if(APPLE)
if(NOT CMAKE_INSTALL_NAME_DIR)
set(CMAKE_INSTALL_NAME_DIR
${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
PATH "Library Install Name Destination Directory" FORCE)
endif(NOT CMAKE_INSTALL_NAME_DIR)
if(NOT CMAKE_INSTALL_RPATH)
set(CMAKE_INSTALL_RPATH
${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
PATH "Library Install RPath" FORCE)
endif(NOT CMAKE_INSTALL_RPATH)
if(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE
BOOL "Do Build Using Library Install RPath" FORCE)
endif(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
endif(APPLE)
########################################################################
# Find gnuradio build dependencies
########################################################################
find_package(Doxygen)
########################################################################
# Setup doxygen option
########################################################################
if(DOXYGEN_FOUND)
option(ENABLE_DOXYGEN "Build docs using Doxygen" ON)
else(DOXYGEN_FOUND)
option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF)
endif(DOXYGEN_FOUND)
########################################################################
# Create uninstall target
########################################################################
configure_file(
${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
@ONLY)
add_custom_target(uninstall
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
)
########################################################################
# Add subdirectories
########################################################################
add_subdirectory(include/timgsn)
add_subdirectory(lib)
add_subdirectory(apps)
add_subdirectory(docs)
add_subdirectory(swig)
add_subdirectory(python)
add_subdirectory(grc)
########################################################################
# Install cmake search helper for this library