Как передавать и получать сигнал основной полосы частот в unetstack?

Я пытаюсь работать над проектом, связанным с внедрением моделей акустических потерь при распространении в подводной связи (на основе определенного исследовательского документа). Мы пытаемся смоделировать это в unetstack. Конечной целью является создание класса модели канала, в котором реализованы все модели потерь.

Но сейчас мы начали с попытки отправить сигнал основной полосы частот с одного узла на другой, а затем пытаемся зафиксировать частоту на узле-приемнике и рассчитать модели потерь на этой заданной частоте. (Модели потерь являются функцией значения частоты сигнала). Я пытался следовать некоторой документации и некоторым сообщениям в блогах, но я не могу передавать и получать сигнал.

Для справки я уже ссылался на эти статьи: 1.) SVC-12-основной диапазон 2.) базовые операции с модемом с использованием unetstack

Это исследовательская работа, которой я следую это для расчета убытков на основе различных моделей убытков.

Я попытался написать отличный файл для моделирования, но он не работает. Если кто-то может посмотреть и сообщить мне ошибки, которые я сделал, это было бы реальной помощью. Мы новичок в unetstack, а также в теме подводной обработки сигналов, и это наша первая попытка реализовать это на симуляторе. Мы используем unetsim-1.3

Любая помощь очень ценится! заранее спасибо

import org.arl.fjage.*
import org.arl.unet.*
import org.arl.unet.phy.*
import org.arl.unet.bb.*
import org.arl.unet.sim.*
import org.arl.unet.sim.channels.*
import static org.arl.unet.Services.*
import static org.arl.unet.phy.Physical.*

import java.lang.Math.*

platform = RealTimePlatform

simulate 3.minutes, {
    def n = []
    n << node('1', address: 1, location: [0,0,0])
    n << node('2', address: 2, location: [0,0,0])

    n.eachWithIndex { n2, i ->

        n2.startup = {
            def phy = agentForService PHYSICAL
            def node = agentForService NODE_INFO
            def bb = agentForService BASEBAND
            subscribe phy
            subscribe bb

            if (node.address == 1)
            {
                add new TickerBehavior(50000, {

                    float freq = 5000
                    float duration = 1000e-3
                    int fd = 24000
                    int fc = 24000
                    int num = duration*fd
                    def sig = []
                    (0..num-1).each { t ->
                        double a = 2*Math.PI*(freq-fc)*t/fd
                        sig << (int)(Math.cos(a))
                        sig << (int)(Math.sin(a))
                    }

                    bb << new TxBasebandSignalReq(signal: sig)
                    println "sent"
                })

            }

            if (node.address == 2)
            {
                add new TickerBehavior(50000, { 
                    bb << new RecordBasebandSignalReq(recLen: 24000)
                    def rxNtf = receive(RxBasebandSignalNtf, 25000)
                    if (rxNtf)
                    {
                        println "Received"
                    }

                    println "Tried"
                })              
            }
        }
    } 
}

В некоторых случаях «Пробовал» печатается первым, даже до того, как печатается «Отправлено». Это показывает, что код (node.address == 2) выполняется первым, прежде чем выполняется (node.address == 1).

Не могли бы вы объяснить, что вы подразумеваете под «похоже, что это не работает»? Каково ваше ожидаемое поведение и что вы видите? Поскольку поведение тикера запускается в одно и то же время и имеет одинаковый период, порядок срабатывания может быть либо узел 1, затем 2, либо узел 2, а затем 1.

Mandar Chitre 09.04.2019 19:28

Наша цель - отправить сигнал основной полосы частот от узла 1 к узлу 2 определенной частоты. Таким образом, когда node2 получает сигнал, он может извлечь и изменить частоту сигнала. Итак, не могли бы вы предложить некоторые изменения в коде, чтобы этого можно было достичь? Спасибо

Yash Agarwal 10.04.2019 09:33
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
158
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Базовый код, который у вас есть для передачи (TxBasebandSignalReq) и приема (RecordBasebandSignalReq) сигналов, кажется правильным.

Это должно хорошо работать на модемах, за исключением того факта, что ваше генерирование сигнала, вероятно, ошибочно по двум причинам:

  1. Вы пытаетесь сгенерировать сигнал с частотой 5 кГц в представлении основной полосы частот, используя несущую частоту 24 кГц и полосу пропускания 24 кГц. Этот сигнал будет сглажен, так как это представление основной полосы частот может представлять только сигналы 24 ± 12 кГц, т. е. 12–36 кГц. Если вам нужно передать сигнал 5 кГц, вам нужно, чтобы ваш модем работал на гораздо более низкой несущей частоте (легко в симуляторе, но на практике вам нужно проверить характеристики модема).

  2. Вы преобразуете вывод sin и cos в int. Вероятно, это не то, что вы намеревались сделать, так как signal представляет собой массив float, масштабированный между -1 и 1. Поэтому было бы целесообразно просто отбросить (int).

На симуляторе вам необходимо убедиться, что параметры модема настроены правильно, чтобы отразить ваши предположения о несущей частоте основной полосы частот, полосе пропускания и длине записи:

modem.carrierFrequency = 24000
modem.basebandRate = 24000
modem.maxSignalLength = 24000

Параметры по умолчанию HalfDuplexModem отличаются, и ваш текущий код не выполнит RecordBasebandSignalReq с ответом REFUSE (который ваш код не проверяет).

Остальная часть вашего кода выглядит нормально, но я бы немного упростил ее:

import org.arl.fjage.*
import org.arl.unet.bb.*
import org.arl.unet.Services

platform = RealTimePlatform

modem.carrierFrequency = 24000
modem.basebandRate = 24000
modem.maxSignalLength = 48000

simulate 3.minutes, {

  def n1 = node('1', address: 1, location: [0,0,0])
  def n2 = node('2', address: 2, location: [0,0,0])

  n1.startup = {
    def bb = agentForService Services.BASEBAND
    add new TickerBehavior(50000, {
      float freq = 25000  // pick a frequency in the 12-36 kHz range
      float duration = 1000e-3
      int fd = 24000
      int fc = 24000
      int num = duration*fd
      def sig = []
      (0..num-1).each { t ->
        double a = 2*Math.PI*(freq-fc)*t/fd
        sig << Math.cos(a)
        sig << Math.sin(a)
      }
      bb << new TxBasebandSignalReq(signal: sig)
      println "sent"
    })
  }

  n2.startup = {
    def bb = agentForService Services.BASEBAND
    add new TickerBehavior(50000, {
      bb << new RecordBasebandSignalReq(recLen: 24000)
      def rxNtf = receive(RxBasebandSignalNtf, 25000)
      if (rxNtf) {
        println "Received"
      }
      println "Tried"
    })
  }

}

Это должно работать так, как ожидалось!

Тем не менее, есть еще несколько ошибок, о которых следует помнить:

  1. Вы отправляете и записываете по таймеру. В симуляторе это должно быть нормально, так как оба узла имеют одинаковое время начала и нет задержки распространения (вы установили узлы в одном и том же месте). Однако на реальном модеме запись может не происходить во время передачи.

  2. Передача и прием сигналов с настоящим модемом работает хорошо. Симулятор Unet в первую очередь является симулятором сети и фокусируется на моделировании поведения модемов в системе связи, но не обязательно на акустическом распространении. Хотя он поддерживает сервис BASEBAND, физика канала передачи сигналов не точно моделируется моделью HalfDuplexModem по умолчанию. Таким образом, ваш пробег по обработке сигнала записи может варьироваться. Это можно исправить, определив собственную модель канала, которая использует подходящую модель акустического распространения, но это нетривиальная задача.

Другие вопросы по теме