initial commit
This commit is contained in:
254
Projects/SDR_Rover/tests/lab005_virtual_channel.py
Normal file
254
Projects/SDR_Rover/tests/lab005_virtual_channel.py
Normal file
@@ -0,0 +1,254 @@
|
||||
"""
|
||||
Lab005. Передача пакетов через виртуальный радиоканал.
|
||||
|
||||
Эксперимент:
|
||||
1. Формируем 100 цифровых пакетов.
|
||||
2. Передаём их через виртуальный канал.
|
||||
3. Канал может:
|
||||
- полностью потерять пакет;
|
||||
- изменить отдельные биты.
|
||||
4. Приёмник проверяет структуру пакета и CRC-32.
|
||||
5. Выводится статистика доставки.
|
||||
"""
|
||||
|
||||
import random
|
||||
|
||||
from protocol.packet import (
|
||||
CRCError,
|
||||
MESSAGE_TYPE_TEXT,
|
||||
PacketError,
|
||||
build_packet,
|
||||
parse_packet,
|
||||
)
|
||||
|
||||
from tools.virtual_channel import transmit
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Настройки эксперимента
|
||||
# ============================================================
|
||||
|
||||
# Количество передаваемых пакетов.
|
||||
PACKET_COUNT = 100
|
||||
|
||||
# Вероятность полной потери одного пакета.
|
||||
#
|
||||
# 0.10 означает 10 %.
|
||||
DROP_PROBABILITY = 0.10
|
||||
|
||||
# Вероятность повреждения каждого отдельного бита.
|
||||
#
|
||||
# 0.002 означает:
|
||||
# 0,2 % вероятности ошибки для каждого бита.
|
||||
BIT_ERROR_PROBABILITY = 0.002
|
||||
|
||||
# Генератор случайных чисел.
|
||||
#
|
||||
# Число 2026 позволяет получать одинаковый результат
|
||||
# при каждом запуске программы.
|
||||
random_generator = random.Random(2026)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Счётчики результатов
|
||||
# ============================================================
|
||||
|
||||
sent_packets = 0
|
||||
|
||||
# Пакеты, полностью исчезнувшие в канале.
|
||||
dropped_packets = 0
|
||||
|
||||
# Доставленные, но повреждённые пакеты.
|
||||
rejected_packets = 0
|
||||
|
||||
# Пакеты, правильно принятые и разобранные.
|
||||
received_ok = 0
|
||||
|
||||
# Общее количество изменённых битов.
|
||||
total_flipped_bits = 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Передача серии пакетов
|
||||
# ============================================================
|
||||
|
||||
for sequence_number in range(PACKET_COUNT):
|
||||
|
||||
# Создаём уникальное сообщение для каждого пакета.
|
||||
message = f"ПАКЕТ {sequence_number}"
|
||||
|
||||
# Текст превращается в байты UTF-8.
|
||||
payload = message.encode("utf-8")
|
||||
|
||||
# Формируем полный пакет с заголовком и CRC-32.
|
||||
packet = build_packet(
|
||||
payload=payload,
|
||||
message_type=MESSAGE_TYPE_TEXT,
|
||||
sequence_number=sequence_number,
|
||||
)
|
||||
|
||||
sent_packets += 1
|
||||
|
||||
# Передаём пакет через виртуальный канал.
|
||||
received_packet, flipped_bits = transmit(
|
||||
packet=packet,
|
||||
drop_probability=DROP_PROBABILITY,
|
||||
bit_error_probability=BIT_ERROR_PROBABILITY,
|
||||
random_generator=random_generator,
|
||||
)
|
||||
|
||||
total_flipped_bits += flipped_bits
|
||||
|
||||
# None означает, что пакет полностью потерян.
|
||||
if received_packet is None:
|
||||
dropped_packets += 1
|
||||
continue
|
||||
|
||||
# Пытаемся разобрать принятый пакет.
|
||||
try:
|
||||
parsed_packet = parse_packet(received_packet)
|
||||
|
||||
except (CRCError, PacketError):
|
||||
# CRCError:
|
||||
# контрольная сумма не совпала.
|
||||
#
|
||||
# PacketError:
|
||||
# повреждены SYNC, версия, длина
|
||||
# или другая часть структуры.
|
||||
rejected_packets += 1
|
||||
continue
|
||||
|
||||
# Восстанавливаем текст из полезной нагрузки.
|
||||
restored_message = parsed_packet.payload.decode("utf-8")
|
||||
|
||||
# Проверяем, что получен именно тот пакет,
|
||||
# который был передан.
|
||||
assert parsed_packet.sequence_number == sequence_number
|
||||
assert restored_message == message
|
||||
|
||||
received_ok += 1
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Вывод настроек
|
||||
# ============================================================
|
||||
|
||||
print("=== Lab005. Виртуальный канал ===")
|
||||
|
||||
print("\nНастройки эксперимента:")
|
||||
|
||||
print(
|
||||
"Количество пакетов:",
|
||||
PACKET_COUNT,
|
||||
)
|
||||
|
||||
print(
|
||||
"Вероятность полной потери пакета:",
|
||||
DROP_PROBABILITY,
|
||||
)
|
||||
|
||||
print(
|
||||
"Вероятность ошибки отдельного бита:",
|
||||
BIT_ERROR_PROBABILITY,
|
||||
)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Вывод результатов
|
||||
# ============================================================
|
||||
|
||||
print("\nРезультаты:")
|
||||
|
||||
print(
|
||||
"Передано пакетов:",
|
||||
sent_packets,
|
||||
)
|
||||
|
||||
print(
|
||||
"Потеряно полностью:",
|
||||
dropped_packets,
|
||||
)
|
||||
|
||||
print(
|
||||
"Отклонено из-за повреждений:",
|
||||
rejected_packets,
|
||||
)
|
||||
|
||||
print(
|
||||
"Принято правильно:",
|
||||
received_ok,
|
||||
)
|
||||
|
||||
print(
|
||||
"Всего изменено битов:",
|
||||
total_flipped_bits,
|
||||
)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Расчёт процентов
|
||||
# ============================================================
|
||||
|
||||
delivery_rate = (
|
||||
received_ok
|
||||
/ sent_packets
|
||||
* 100
|
||||
)
|
||||
|
||||
drop_rate = (
|
||||
dropped_packets
|
||||
/ sent_packets
|
||||
* 100
|
||||
)
|
||||
|
||||
rejection_rate = (
|
||||
rejected_packets
|
||||
/ sent_packets
|
||||
* 100
|
||||
)
|
||||
|
||||
packet_failure_rate = (
|
||||
dropped_packets
|
||||
+ rejected_packets
|
||||
) / sent_packets * 100
|
||||
|
||||
|
||||
print("\nСтатистика:")
|
||||
|
||||
print(
|
||||
f"Успешно доставлено: "
|
||||
f"{delivery_rate:.1f} %"
|
||||
)
|
||||
|
||||
print(
|
||||
f"Потеряно полностью: "
|
||||
f"{drop_rate:.1f} %"
|
||||
)
|
||||
|
||||
print(
|
||||
f"Отклонено приёмником: "
|
||||
f"{rejection_rate:.1f} %"
|
||||
)
|
||||
|
||||
print(
|
||||
f"Общая доля недоставленных пакетов: "
|
||||
f"{packet_failure_rate:.1f} %"
|
||||
)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Контроль правильности
|
||||
# ============================================================
|
||||
|
||||
accounted_packets = (
|
||||
received_ok
|
||||
+ dropped_packets
|
||||
+ rejected_packets
|
||||
)
|
||||
|
||||
assert accounted_packets == sent_packets
|
||||
|
||||
print(
|
||||
"\nПроверка пройдена: "
|
||||
"все переданные пакеты учтены."
|
||||
)
|
||||
Reference in New Issue
Block a user