Εμφάνιση αναρτήσεων με ετικέτα graphs. Εμφάνιση όλων των αναρτήσεων
Εμφάνιση αναρτήσεων με ετικέτα graphs. Εμφάνιση όλων των αναρτήσεων

Σάββατο 22 Δεκεμβρίου 2018

Simple RTLSDR gui

 

Λίγα λόγια:

Το RTL-SDR είναι ένα πολύ φτηνό dongle αξίας $ 25 USB το οποίο μπορεί να χρησιμοποιηθεί ως ραδιοφωνικός σαρωτής με βάση τον υπολογιστή για λήψη ζωντανών ραδιοφωνικών σημάτων στην περιοχή σας.

 

Code explanation:

Κάνουμε import τα παρακάτω packages.
  • tkinter για το gui
  • matplotlib για graph plotting
  • numpy για αναπαράσταση των δεδομένων ως 64bit complex
  • rtlsdr για να χρησιμοποιήσουμε την rtlsdr κεραία

import matplotlib; matplotlib.use("TkAgg")
import tkinter as tk

import matplotlib.animation as anim
import numpy as np
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,
                                               NavigationToolbar2TkAgg)
from matplotlib.figure import Figure
from rtlsdr import RtlSdr

LARGE_FONT = ("Verdana", 12)

Κατασκευάζουμε τα widgets στο application

class FrequencyGraph(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self, "rtlsdr-qui")

        container = tk.Frame(self)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        container.grid(row=0, column=0)

        f_station_label = tk.Label(container, text="Frequency Station", font=LARGE_FONT)
        f_station_label.grid(row=0, column=0)

        self.f_station_entry = tk.Entry(container)
        self.f_station_entry.grid(row=0, column=1)

        f_offset_label = tk.Label(container, text="Frequency Offset", font=LARGE_FONT)
        f_offset_label.grid(row=1, column=0)

        self.f_offset_entry = tk.Entry(container)
        self.f_offset_entry.grid(row=1, column=1)

        sample_rate_label = tk.Label(container, text="Sample Rate", font=LARGE_FONT)
        sample_rate_label.grid(row=2, column=0)

        self.sample_rate_entry = tk.Entry(container)
        self.sample_rate_entry.grid(row=2, column=1)

        sample_count_label = tk.Label(container, text="Sample count", font=LARGE_FONT)
        sample_count_label.grid(row=3, column=0)

        self.sample_count_entry = tk.Entry(container)
        self.sample_count_entry.grid(row=3, column=1)

        b = tk.Button(container, text="Change Settings", command=self.change_settings)
        b.grid(row=4, column=1)

        f = Figure(figsize=(5, 5), dpi=100)


Κάνουμε initialize το RtlSdr object για να αρχίσουμε να καταγράφουμε δεδομένα από την κεραία
και αρχικοποιούμε τις τιμές. Στην συνέχεια κατασκευάζουμε ένα figure canvas το οποίο το κάνουμε
associate με μια function update_plot η οποία θα ευθύνεται για να κρατάει το plot up to date.

        self.sdr = RtlSdr()
        self.ax1 = f.add_subplot(111)

        self.F_station = int(96.9e6)  # Rutgers Radio
        self.F_offset = 300000  # Offset to capture at
        # We capture at an offset to avoid DC spike
        self.Fc = self.F_station - self.F_offset  # Capture center frequency
        self.Fs = int(1140000)  # Sample rate
        self.N = int(262144)  # Samples to capture int()  8192000
        # configure device
        self.sdr.sample_rate = self.Fs  # Hz
        self.sdr.center_freq = self.Fc  # Hz
        self.sdr.gain = 'auto'

        self.f_station_entry.insert(0, "96.9")
        self.f_offset_entry.insert(0, "300000")
        self.sample_rate_entry.insert(0, "1140000")
        self.sample_count_entry.insert(0, "262144")

        samples = self.sdr.read_samples(self.N)
        x1 = np.array(samples).astype("complex64")
        self.ax1.psd(x1, NFFT=2048, Fs=self.Fs, Fc=self.Fc)

        canvas = FigureCanvasTkAgg(f, self)
        anim_void = anim.FuncAnimation(f, self.update_plot, interval=1000, blit=False)
        canvas.show()
        canvas.get_tk_widget().grid(row=0, column=1)
        canvas._tkcanvas.grid(row=0, column=1)


Η update_plot διαβάζει samples από την κεραία και κάνει update το διάγραμμα

    def update_plot(self, i):
        samples = self.sdr.read_samples(self.N)
        x1 = np.array(samples).astype("complex64")
        self.ax1.clear()
        self.ax1.psd(x1, NFFT=2048, Fs=self.Fs, Fc=self.Fc)


To change settings διαβάζει τα values από τα entry widgets και τα αναθέτει ως attributes

    def change_settings(self):
        self.F_station = float(self.f_station_entry.get()) * 10e5  # Rutgers Radio
        self.F_offset = int(self.f_offset_entry.get())  # Offset to capture at
        # We capture at an offset to avoid DC spike
        self.Fc = self.F_station - self.F_offset  # Capture center frequency
        self.Fs = int(self.sample_rate_entry.get())  # Sample rate
        self.N = int(self.sample_count_entry.get())  # Samples to capture int()  8192000
        # configure device
        self.sdr.sample_rate = self.Fs  # Hz
        self.sdr.center_freq = self.Fc  # Hz
        self.sdr.gain = 'auto'

Tέλος κάνουμε αρχικοποιούμε το graphical user interface

if __name__ == '__main__':
    app = FrequencyGraph()
    app.mainloop()

Useful links: https://www.rtl-sdr.com/about-rtl-sdr/

Δευτέρα 26 Δεκεμβρίου 2016

Γράφοι χωρίς συντεταγμένες.


Σε μια εργασία που είχα πρόσφατα για τεχνητή 
νοημοσύνη μας δίνονταν γράφοι με την εξής μορφή:
Μπορείτε να δείτε όλοκληρο το text εδώ

και έπρεπε να εμφανίζουμε το path από ένα αρχικό 
κόμβο σε έναν τελικό κόμβο δοκιμάζοντας
διάφορους αλγόριθμους αναζήτησης όπως ο A* , 
uniform cost , depth first search , breadth first search.

Οπότε μετά το πέρας της εργασίας απέκτησα το εξής ερώτημα:

-Πως θα μπορούσε κάποιος να απεικονήσει τους παραπάνω γράφους χωρίς να γνωρίζει λεπτομέρειες όπως συντεταγμένες.

Η αρχική ιδέα ήταν να δημιουργήσω ομογενείς κύκλους με κέντρο τον κόμβο που έχει ευρετικό 0. Άρα με βάση την ευρετική τιμή του κάθε κόμβου η ευρετική τιμή θα αποτελούσε την ακτίνα του κόμβου από το 0,0 όπου βρίσκεται ο κόμβος - στόχος αυτός που έχει ευρετικό 0.
Και για να μην είναι όλοι οι κόμβοι στην ίδια ευθεία πολύ απλά ο καθένας θα έχει γωνία: (count / πλήθος των κόμβων * 2π)
Όπου το count θα ξεκινάει από το 1 και θα ανεβαίνει κατα 1 για κάθε κόμβο. O κώδικας που χρησιμοποιήθηκε είναι της παρακάτω μορφής και έβγαζε έναν γράφο όπως αυτόν

-Τό πρόβλημα με το εξής σύστημα είναι ότι οι γραμμές και οι κόμβοι τέμνονται συχνά.

Η δεύτερη ιδέα είναι ξεκινόντας από έναν κόμβο να αρχίσεις να τοποθετείς γύρω του σε έναν κύκλο όλους τους γειτονικούς του κόμβους οι οποίοι δεν έχουν ήδη τοποθετηθεί .Η φόρμουλα των γωνιών του κύκλου είναι όμοια με την παραπάνω: (count / πλήθος των γειτονικών κόμβων * 2π)


-Το κακό είναι ότι αυτή η μέθοδος λειτουργεί μόνο για γράφους των οποίων ΌΛΟΙ οι κόμβοι είναι συνδεδεμένοι στον γράφο.