Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ambient pressure #184

Merged
merged 39 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7041d99
add ambient_pressure
InvincibleRMC Jun 1, 2024
01cd707
Better prefix for judge packets
benjaminwp18 Jun 1, 2024
a62f834
Special case for calibration packets
benjaminwp18 Jun 1, 2024
e9eb71f
remove ambient pressure
InvincibleRMC Jun 1, 2024
84e7343
add pytest fixture
InvincibleRMC Jun 1, 2024
4d60a01
fix imports
InvincibleRMC Jun 1, 2024
95d0092
update unit test
InvincibleRMC Jun 1, 2024
2c95849
Add exit
InvincibleRMC Jun 1, 2024
7415e0f
try catch?
InvincibleRMC Jun 1, 2024
7eda780
clang
InvincibleRMC Jun 1, 2024
f7eb09f
refactor to packet handler
InvincibleRMC Jun 1, 2024
6f7d232
update unit test
InvincibleRMC Jun 1, 2024
3fc3ae8
equal function
InvincibleRMC Jun 1, 2024
5b0615d
add silly typing
InvincibleRMC Jun 1, 2024
7eab9aa
update unit test
InvincibleRMC Jun 1, 2024
2d0e8d9
remove extra ]
InvincibleRMC Jun 1, 2024
a6b09ea
fix math
InvincibleRMC Jun 1, 2024
1d4383c
Move judge packet size to const
benjaminwp18 Jun 3, 2024
23a4448
Linting
benjaminwp18 Jun 3, 2024
b4ef5fa
Merge branch 'main' into add-ambient-pressure
Jun 5, 2024
cce62d3
Fix during pool test
benjaminwp18 Jun 5, 2024
ab3365e
Change layout
Jun 8, 2024
ccf72a0
Merge branch 'main' into add-ambient-pressure
InvincibleRMC Jun 8, 2024
b1a1509
Merge branch 'main' into add-ambient-pressure
Jun 11, 2024
8e6a88b
start float single
InvincibleRMC Jun 15, 2024
93f1611
Merge remote-tracking branch 'origin/main' into add-ambient-pressure
InvincibleRMC Jun 15, 2024
e635a6d
feature complete
InvincibleRMC Jun 15, 2024
4a36b86
I HATE 0/5
InvincibleRMC Jun 15, 2024
7db8d5e
Update src/surface/transceiver/transceiver/serial_reader.py
InvincibleRMC Jun 15, 2024
f4581da
make instance
InvincibleRMC Jun 15, 2024
a2a23e6
add missing self
InvincibleRMC Jun 15, 2024
b0fd8e7
add ros single constant
InvincibleRMC Jun 15, 2024
e546748
remove blank line
InvincibleRMC Jun 15, 2024
bc4b617
slightly better
InvincibleRMC Jun 15, 2024
7683577
pressure_reading
InvincibleRMC Jun 15, 2024
d13f1d4
Update src/surface/transceiver/transceiver/serial_reader.py
InvincibleRMC Jun 15, 2024
e6947f8
Update src/surface/transceiver/transceiver/serial_reader.py
InvincibleRMC Jun 15, 2024
eaac153
for loop
InvincibleRMC Jun 15, 2024
4b37191
fix line lenthgs
InvincibleRMC Jun 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/float/float_transceiver/float_transceiver.ino
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ void loop() {

int intComponent = pressure;
int fracComponent = trunc((pressure - intComponent) * 10000);
char judgePacketBuffer[25];
char judgePacketBuffer[30];
benjaminwp18 marked this conversation as resolved.
Show resolved Hide resolved
snprintf(
judgePacketBuffer, 25, "%d,%lu,%d.%04d\0", TEAM_NUM, previousPressureReadTime, intComponent,
judgePacketBuffer, 30, "ROS:SINGLE:%d:%lu,%d.%04d\0", TEAM_NUM, previousPressureReadTime, intComponent,
fracComponent);
Serial.println(judgePacketBuffer);

Expand Down
15 changes: 11 additions & 4 deletions src/float/surface_transceiver/surface_transceiver.ino
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,18 @@ bool receivePacket() {
if (len < MAX_RESPONSE_LEN) {
// This packet is probably an ACK/NACK, but could be a simple packet for judges
byteBuffer[len] = '\0';
serialPrintf("Got pkt w/len %d, str '%s' & vals: ", len, reinterpret_cast<char*>(byteBuffer));
for (int i = 0; i < len; i++) {
serialPrintf("%d, ", byteBuffer[i]);
char *charBuffer = reinterpret_cast<char*>(byteBuffer);
// If this is a "single" judge/calibration packet
if (strncmp(byteBuffer, "ROS:SINGLE:", 11) == 0) {
Serial.println(charBuffer);
}
else {
serialPrintf("Got pkt w/len %d, str '%s' & vals: ", len, charBuffer);
for (int i = 0; i < len; i++) {
serialPrintf("%d, ", byteBuffer[i]);
}
Serial.println();
}
Serial.println();

bool isACK = (strncmp(byteBuffer, "ACK", 3) == 0);
bool isNACK = (strncmp(byteBuffer, "NACK", 4) == 0);
Expand Down
56 changes: 52 additions & 4 deletions src/surface/transceiver/test/test_parser.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from queue import Queue

import pytest
from transceiver.serial_reader import SerialReader

Expand All @@ -10,8 +12,15 @@
HEADER_TWO_ELEMENTS = "ROS:11,1:313901,988.53;314843,988.57;315785,988.99;316727,991.56;317669,996.21;318611,1002.36;319553,1010.36;320495,1021.11;321437,1034.42;322379,1050.23;323321,1051.86;324263,1053.20;325206,1053.32;326146,1053.46;327088,1053.52;328030,1053.58;328972,1053.61;329914,1053.64;330856,1053.61;331798,1053.60;332740,1053.65;333682,1053.58;334624,1053.53;335566,1053.52;336508,1053.39;337453,1053.41;338395,1053.46;339337,1053.37;340279,1053.42;341221,1053.49;342163,1053.54" # noqa: E501


def test_parser() -> None:
msg = SerialReader._message_parser(PACKET)
ROS_SINGLE_ONE = "ROS:SINGLE:25:5552,992.4500"
ROS_SINGLE_TWO = "ROS:SINGLE:25:11071,994.4299"
ROS_SINGLE_THREE = "ROS:SINGLE:25:16592,992.9600"
ROS_SINGLE_FOUR = "ROS:SINGLE:25:22112,993.3699"
ROS_SINGLE_FIVE = "ROS:SINGLE:25:27631,993.2600"
InvincibleRMC marked this conversation as resolved.
Show resolved Hide resolved


def test_message_parser() -> None:
msg = SerialReader()._message_parser(PACKET)

assert msg == FloatData(
team_number=11,
Expand All @@ -22,7 +31,46 @@ def test_parser() -> None:
)

with pytest.raises(ValueError, match="Packet expected 3 sections, found 2 sections"):
SerialReader._message_parser(NOT_THREE_SECTIONS)
SerialReader()._message_parser(NOT_THREE_SECTIONS)

with pytest.raises(ValueError, match="Packet header length of 3 expected found 2 instead"):
SerialReader._message_parser(HEADER_TWO_ELEMENTS)
SerialReader()._message_parser(HEADER_TWO_ELEMENTS)


def test_handle_ros_single() -> None:
s = SerialReader()
s._handle_ros_single(ROS_SINGLE_ONE)
test_queue: Queue[float] = Queue(5)
test_queue.put(992.4500)

assert s.surface_pressures == test_queue
assert s.surface_pressure == 992.4500

s._handle_ros_single(ROS_SINGLE_TWO)
test_queue.put(994.4299)

assert s.surface_pressures == test_queue
assert s.surface_pressures == 992.43995

s._handle_ros_single(ROS_SINGLE_THREE)
test_queue.put(992.9600)

assert s.surface_pressures == test_queue
assert s.surface_pressures == 992.6133

s._handle_ros_single(ROS_SINGLE_FOUR)
test_queue.put(993.3699)

assert s.surface_pressures == test_queue
assert s.surface_pressures == 992.80245

s._handle_ros_single(ROS_SINGLE_FIVE)
test_queue.put(993.26)

assert s.surface_pressures == test_queue
assert s.surface_pressures == 992.89396

# Test no more get added
s._handle_ros_single(ROS_SINGLE_FIVE)
assert s.surface_pressures == test_queue

39 changes: 33 additions & 6 deletions src/surface/transceiver/transceiver/serial_reader.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import time
from threading import Thread

from queue import Queue
import rclpy
from rclpy.node import Node
from rclpy.qos import QoSPresetProfiles
Expand All @@ -12,6 +12,9 @@
SECONDS_TO_MINUTES = 1/60
MBAR_TO_METER_OF_HEAD = 0.010199773339984


AMBIENT_PRESSURE_DEFAULT = 1013.25 # in (mbar)

# AKA the length of the float in (m)
FLOAT_CONVERSION_FACTOR = 0.635

InvincibleRMC marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -39,6 +42,10 @@ def __init__(self) -> None:

self.serial = Serial("/dev/serial/by-id/usb-Adafruit_Feather_32u4-if00", 115200)

self.surface_pressure = AMBIENT_PRESSURE_DEFAULT

self.surface_pressures: Queue[float] = Queue(5)

Thread(target=self.read_serial, daemon=True,
name="Serial Reader").start()

Expand All @@ -63,14 +70,34 @@ def ros_publish(self, packet: str) -> None:
return

try:
msg = SerialReader._message_parser(packet)
if SerialReader.is_ros_single_message(packet):
self._handle_ros_single(packet)
else:
msg = self._message_parser(packet)
self.data_publisher.publish(msg)
except Exception as e:
self.get_logger().error(f"Error {e} caught dropping packet")
return
self.data_publisher.publish(msg)

@staticmethod
def _message_parser(packet: str) -> FloatData:
def is_ros_single_message(packet: str) -> bool:
ros_single = ROS_PACKET + "SINGLE"
InvincibleRMC marked this conversation as resolved.
Show resolved Hide resolved
return packet[:len(ros_single)] != ros_single
InvincibleRMC marked this conversation as resolved.
Show resolved Hide resolved

def _handle_ros_single(self, packet: str) -> None:
if self.surface_pressures.full():
return

packet_sections = packet.split(SECTION_SEPARATOR)
data = packet_sections[3]
InvincibleRMC marked this conversation as resolved.
Show resolved Hide resolved
pressure = float(data.split(COMMA_SEPARATOR)[1])
InvincibleRMC marked this conversation as resolved.
Show resolved Hide resolved

self.surface_pressures.put(pressure)

q = self.surface_pressures.queue
avg_pressure = sum(q) / len(q)
InvincibleRMC marked this conversation as resolved.
Show resolved Hide resolved
self.surface_pressure = avg_pressure

def _message_parser(self, packet: str) -> FloatData:
msg = FloatData()

packet_sections = packet.split(SECTION_SEPARATOR)
Expand Down Expand Up @@ -102,7 +129,7 @@ def _message_parser(packet: str) -> FloatData:
time_data_list.append(int(time_reading) * MILLISECONDS_TO_SECONDS * SECONDS_TO_MINUTES)

# Starts out as float
depth_data_list.append(float(depth_reading) * MBAR_TO_METER_OF_HEAD)
depth_data_list.append((float(depth_reading) - self.surface_pressure) * MBAR_TO_METER_OF_HEAD)
msg.time_data = time_data_list
msg.depth_data = depth_data_list

Expand Down