Skip to content

Commit

Permalink
Merge branch 'ros1' into thread-lock
Browse files Browse the repository at this point in the history
  • Loading branch information
rafal-gorecki committed Apr 25, 2023
2 parents e8c1602 + 5059e12 commit 49d58b9
Show file tree
Hide file tree
Showing 28 changed files with 374 additions and 83 deletions.
12 changes: 12 additions & 0 deletions panther/CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package panther
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1.0.3 (2023-04-24)
------------------

1.0.2 (2023-04-24)
------------------

1.0.1 (2023-04-21)
------------------
2 changes: 1 addition & 1 deletion panther/package.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="3">
<name>panther</name>
<version>1.0.0</version>
<version>1.0.3</version>

<description>Meta package that contains all packages of Panther</description>
<license>Apache License 2.0</license>
Expand Down
12 changes: 12 additions & 0 deletions panther_battery/CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package panther_battery
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1.0.3 (2023-04-24)
------------------

1.0.2 (2023-04-24)
------------------

1.0.1 (2023-04-21)
------------------
4 changes: 4 additions & 0 deletions panther_battery/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@ Node publishing Panther battery state read from motor controllers. Used in Panth
#### Subscribes

- `/panther/driver/motor_controllers_state` [*panther_msgs/DriverState*]: current motor controllers' state and error flags.

#### Parameters

- `~high_bat_temp` [*float*, default: **55.0**]: The temperature of the battery at which the battery health state is incorrect.
2 changes: 1 addition & 1 deletion panther_battery/package.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="3">
<name>panther_battery</name>
<version>1.0.0</version>
<version>1.0.3</version>

<description>Nodes monitoring the battery state of Husarion Panhter robot</description>
<license>Apache License 2.0</license>
Expand Down
69 changes: 60 additions & 9 deletions panther_battery/src/adc_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

from threading import Lock

from collections import defaultdict
import math
from threading import Lock
from typing import Optional, Union

import rospy

Expand All @@ -13,16 +16,22 @@

class ADCNode:
BAT02_DETECT_THRESH = 3.03
V_BAT_FATAL_MIN = 27.0
V_BAT_FATAL_MAX = 43.0

def __init__(self, name: str) -> None:
rospy.init_node(name, anonymous=False)

self._lock = Lock()
self._high_bat_temp = rospy.get_param('~high_bat_temp', 55.0)

self._V_driv_front = None
self._V_driv_rear = None
self._I_driv_front = None
self._I_driv_rear = None
self._driver_battery_last_info_time: Optional[float] = None
self._I_driv: Optional[float] = None
self._V_driv: Optional[float] = None

self._volt_mean_length = 10
self._V_bat_hist = defaultdict(lambda: [37.0] * self._volt_mean_length)
self._V_bat_mean = defaultdict(lambda: 37.0)
self._V_driv_mean: Optional[float] = None

self._A = 298.15
self._B = 3977.0
Expand All @@ -33,6 +42,8 @@ def __init__(self, name: str) -> None:
self._battery_count = self._check_battery_count()
self._battery_charging = True # const for now, later this will be evaluated

self._lock = Lock()

# -------------------------------
# Subscribers
# -------------------------------
Expand Down Expand Up @@ -64,10 +75,13 @@ def __init__(self, name: str) -> None:

def _motor_controllers_state_cb(self, driver_state: DriverState) -> None:
with self._lock:
self._V_driv_front = driver_state.front.voltage
self._V_driv_rear = driver_state.front.current
self._I_driv_front = driver_state.rear.voltage
self._I_driv_rear = driver_state.rear.current
self._driver_battery_last_info_time = rospy.get_time()

driver_voltage = (driver_state.front.voltage + driver_state.rear.voltage) / 2.0
self._V_driv = driver_voltage
self._V_driv_mean = self._count_volt_mean('V_driv', driver_voltage)

self._I_driv = driver_state.front.current + driver_state.rear.current

def _io_state_cb(self, io_state: IOState) -> None:
with self._lock:
Expand Down Expand Up @@ -181,6 +195,8 @@ def _publish_battery_msg(
battery_msg.power_supply_technology = BatteryState.POWER_SUPPLY_TECHNOLOGY_LIPO
battery_msg.present = True

V_bat_mean = self._count_volt_mean(bat_pub, V_bat)

# check battery status
with self._lock:
if self._charger_connected:
Expand All @@ -193,8 +209,43 @@ def _publish_battery_msg(
else:
battery_msg.power_supply_status = BatteryState.POWER_SUPPLY_STATUS_DISCHARGING

# check battery health
with self._lock:
error_msg = None
if V_bat_mean < self.V_BAT_FATAL_MIN:
battery_msg.power_supply_health = BatteryState.POWER_SUPPLY_HEALTH_DEAD
error_msg = 'Battery voltage is critically low!'
elif V_bat_mean > self.V_BAT_FATAL_MAX:
battery_msg.power_supply_health = BatteryState.POWER_SUPPLY_HEALTH_OVERVOLTAGE
error_msg = 'Battery overvoltage!'
elif temp_bat >= self._high_bat_temp:
battery_msg.power_supply_health = BatteryState.POWER_SUPPLY_HEALTH_OVERHEAT
error_msg = 'Battery is overheating!'
elif self._driver_battery_last_info_time is None:
battery_msg.power_supply_health = BatteryState.POWER_SUPPLY_HEALTH_UNKNOWN
elif (
rospy.get_time() - self._driver_battery_last_info_time < 0.1
and abs(V_bat_mean - self._V_driv_mean) > self.V_BAT_FATAL_MAX * 0.1
):
battery_msg.power_supply_health = BatteryState.POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
else:
battery_msg.power_supply_health = BatteryState.POWER_SUPPLY_HEALTH_GOOD

if error_msg is not None:
rospy.logerr_throttle_identical(10.0, f'[{rospy.get_name()}] {error_msg}')

bat_pub.publish(battery_msg)

def _count_volt_mean(self, label: Union[rospy.Publisher, str], new_val: float) -> float:
# Updates the average by adding the newest and removing the oldest component of mean value,
# in order to avoid recalculating the entire sum every time.
self._V_bat_mean[label] += (new_val - self._V_bat_hist[label][0]) / self._volt_mean_length

self._V_bat_hist[label].pop(0)
self._V_bat_hist[label].append(new_val)

return self._V_bat_mean[label]

@staticmethod
def _read_file(path: str) -> int:
with open(path, 'r') as file:
Expand Down
47 changes: 41 additions & 6 deletions panther_battery/src/roboteq_republisher_node.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/python3

from threading import Lock
from typing import Optional

import rospy

Expand All @@ -10,13 +11,21 @@


class RoboteqRepublisherNode:
V_BAT_FATAL_MIN = 27.0
V_BAT_FATAL_MAX = 43.0

def __init__(self, name: str) -> None:
rospy.init_node(name, anonymous=False)

self._lock = Lock()

self._battery_voltage = None
self._battery_current = None
self._battery_voltage: Optional[float] = None
self._battery_current: Optional[float] = None
self._battery_voltage_mean = 37.0

self._volt_mean_length = 10
self._battery_voltage_hist = [37.0] * self._volt_mean_length

self._battery_timeout = 1.0
self._last_battery_info_time = rospy.get_time()

Expand Down Expand Up @@ -45,9 +54,12 @@ def __init__(self, name: str) -> None:

def _motor_controllers_state_cb(self, msg: DriverState) -> None:
with self._lock:
new_voltage = (msg.front.voltage + msg.rear.voltage) / 2.0

self._last_battery_info_time = rospy.get_time()
self._battery_voltage = (msg.front.voltage + msg.rear.voltage) / 2.0
self._battery_voltage = new_voltage
self._battery_current = msg.front.current + msg.rear.current
self._update_volt_mean(new_voltage)

def _battery_pub_timer_cb(self, *args) -> None:
with self._lock:
Expand All @@ -56,25 +68,48 @@ def _battery_pub_timer_cb(self, *args) -> None:
battery_msg.capacity = 20.0
battery_msg.design_capacity = 20.0
battery_msg.power_supply_technology = BatteryState.POWER_SUPPLY_TECHNOLOGY_LIPO

if (
self._battery_voltage == None
or self._battery_current == None
or rospy.get_time() - self._last_battery_info_time > self._battery_timeout
):
battery_msg.power_supply_status = BatteryState.POWER_SUPPLY_STATUS_UNKNOWN
else:
battery_msg.power_supply_status = BatteryState.POWER_SUPPLY_STATUS_DISCHARGING
battery_msg.voltage = self._battery_voltage
battery_msg.temperature = float('nan')
battery_msg.current = self._battery_current
battery_msg.percentage = (battery_msg.voltage - 32.0) / 10.0
battery_msg.charge = battery_msg.percentage * battery_msg.design_capacity
battery_msg.present = True
# TODO:
# battery_msg.power_supply_health

# TODO: check battery status
battery_msg.power_supply_status = BatteryState.POWER_SUPPLY_STATUS_DISCHARGING

# check battery health
error_msg = None
if self._battery_voltage < self.V_BAT_FATAL_MIN:
battery_msg.power_supply_health = BatteryState.POWER_SUPPLY_HEALTH_DEAD
error_msg = 'Battery voltage is critically low!'
elif self._battery_voltage > self.V_BAT_FATAL_MAX:
battery_msg.power_supply_health = BatteryState.POWER_SUPPLY_HEALTH_OVERVOLTAGE
error_msg = 'Battery overvoltage!'
else:
battery_msg.power_supply_health = BatteryState.POWER_SUPPLY_HEALTH_GOOD

if error_msg is not None:
rospy.logerr_throttle_identical(10.0, f'[{rospy.get_name()}] {error_msg}')

self._battery_pub.publish(battery_msg)

def _update_volt_mean(self, new_val: float) -> float:
# Updates the average by adding the newest and removing the oldest component of mean value,
# in order to avoid recalculating the entire sum every time.
self._battery_voltage_mean += (new_val - self._battery_voltage_hist[0]) / self._volt_mean_length

self._battery_voltage_hist.pop(0)
self._battery_voltage_hist.append(new_val)


def main():
roboteq_republisher_node = RoboteqRepublisherNode('roboteq_republisher_node')
Expand Down
12 changes: 12 additions & 0 deletions panther_bringup/CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package panther_bringup
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1.0.3 (2023-04-24)
------------------

1.0.2 (2023-04-24)
------------------

1.0.1 (2023-04-21)
------------------
2 changes: 1 addition & 1 deletion panther_bringup/package.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="3">
<name>panther_bringup</name>
<version>1.0.0</version>
<version>1.0.3</version>

<description>Default launch files and configuration used to start Husarion Panther robot</description>
<license>Apache License 2.0</license>
Expand Down
12 changes: 12 additions & 0 deletions panther_description/CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package panther_description
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1.0.3 (2023-04-24)
------------------

1.0.2 (2023-04-24)
------------------

1.0.1 (2023-04-21)
------------------
2 changes: 1 addition & 1 deletion panther_description/package.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="3">
<name>panther_description</name>
<version>1.0.0</version>
<version>1.0.3</version>

<description>Semantic description of Huasrion Panther robot</description>
<license>Apache License 2.0</license>
Expand Down
12 changes: 12 additions & 0 deletions panther_driver/CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package panther_driver
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1.0.3 (2023-04-24)
------------------

1.0.2 (2023-04-24)
------------------

1.0.1 (2023-04-21)
------------------
2 changes: 1 addition & 1 deletion panther_driver/package.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package format="3">
<name>panther_driver</name>
<version>1.0.0</version>
<version>1.0.3</version>

<description>Software for controlling Panther robot motors via CAN interface.</description>
<license>Apache License 2.0</license>
Expand Down
Loading

0 comments on commit 49d58b9

Please sign in to comment.