Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit f9a5677

Browse files
Merge pull request #17 from NathanaelGandhi/main
deploy(release): zone type, threading and params
2 parents 2b0e49a + 3aa12db commit f9a5677

8 files changed

+146
-32
lines changed

.github/release-drafter-config.yml

+4-5
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22
name-template: v$RESOLVED_VERSION
33
tag-template: v$RESOLVED_VERSION
44
categories:
5-
- title: 🚀 Features
5+
- title: Features
66
collapse-after: 10
77
labels:
88
- feature
99
- enhancement
10-
- title: 🐛 Bug Fixes
10+
- title: Bug Fixes
1111
collapse-after: 5
1212
labels:
1313
- fix
1414
- bugfix
1515
- bug
16-
- title: 🧰 Maintenance
16+
- title: Maintenance
1717
collapse-after: 5
1818
labels:
1919
- deploy
@@ -24,7 +24,7 @@ categories:
2424
- refactor
2525
- style
2626
- test
27-
- title: ⬆️ Dependencies
27+
- title: Dependencies
2828
collapse-after: 5
2929
labels:
3030
- dependencies
@@ -91,7 +91,6 @@ version-resolver:
9191
- chore
9292
- ci
9393
- dependencies
94-
- deploy
9594
- documentation
9695
- fix
9796
- refactor

.github/workflows/pr-autolabeler.yml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
name: PR Autolabeler
3+
4+
on:
5+
pull_request:
6+
types: [opened, reopened, synchronize]
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
label_pr:
14+
permissions:
15+
# write permission is required to create a github release
16+
contents: write
17+
# write permission is required for autolabeler
18+
# otherwise, read permission is required at least
19+
pull-requests: write
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: release-drafter/release-drafter@v6
23+
with:
24+
config-name: release-drafter-config.yml
25+
disable-autolabeler: false
26+
prerelease: false
27+
publish: false
28+
env:
29+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
---
2-
name: Release Drafter
2+
name: Publish Release
33

44
on:
55
push:
66
branches:
77
- release
8-
pull_request:
9-
types: [opened, reopened, synchronize]
108
workflow_dispatch:
119

1210
permissions:
1311
contents: read
1412

1513
jobs:
16-
update_release_draft:
14+
publish_release:
1715
permissions:
1816
# write permission is required to create a github release
1917
contents: write
2018
# write permission is required for autolabeler
2119
# otherwise, read permission is required at least
22-
pull-requests: write
20+
pull-requests: read
2321
runs-on: ubuntu-latest
2422
steps:
2523
- name: version
@@ -34,9 +32,10 @@ jobs:
3432
3533
- uses: release-drafter/release-drafter@v6
3634
with:
37-
version: ${{ steps.version.outputs.version }}
38-
publish: true
3935
config-name: release-drafter-config.yml
40-
disable-autolabeler: false
36+
disable-autolabeler: true
37+
prerelease: false
38+
publish: true
39+
version: ${{ steps.version.outputs.version }}
4140
env:
4241
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build/
2+
install/
3+
log/

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ repos:
4141
hooks:
4242
- id: black
4343
- repo: https://github.com/asottile/reorder-python-imports
44-
rev: v3.12.0
44+
rev: v3.13.0
4545
hooks:
4646
- id: reorder-python-imports
4747
# YAML

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# linux_thermal_zone_base
22
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/NathanaelGandhi/linux_thermal_zone_base/main.svg)](https://results.pre-commit.ci/latest/github/NathanaelGandhi/linux_thermal_zone_base/main)
3-
[![Release Drafter](https://github.com/NathanaelGandhi/linux_thermal_zone_base/actions/workflows/release-drafter.yml/badge.svg?branch=release)](https://github.com/NathanaelGandhi/linux_thermal_zone_base/actions/workflows/release-drafter.yml)
3+
[![Publish Release](https://github.com/NathanaelGandhi/linux_thermal_zone_base/actions/workflows/publish-release.yml/badge.svg?branch=release)](https://github.com/NathanaelGandhi/linux_thermal_zone_base/actions/workflows/publish-release.yml)
44
[![Mirror release to humble](https://github.com/NathanaelGandhi/linux_thermal_zone_base/actions/workflows/mirror-release-to-humble.yaml/badge.svg?branch=release)](https://github.com/NathanaelGandhi/linux_thermal_zone_base/actions/workflows/mirror-release-to-humble.yaml)
5+
[![PR Autolabeler](https://github.com/NathanaelGandhi/linux_thermal_zone_base/actions/workflows/pr-autolabeler.yml/badge.svg?branch=main)](https://github.com/NathanaelGandhi/linux_thermal_zone_base/actions/workflows/auto-autolabeler.yml)
56

67
ROS2 node for thermal zone(s) found on linux systems at ```/sys/class/thermal/thermal_zone*```
78

Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
#pragma once
22

3+
#include <atomic>
4+
#include <mutex>
35
#include <rclcpp/rclcpp.hpp>
46
#include <string>
7+
#include <thread>
58
#include <vector>
69

710
#include "linux_thermal_zone_interfaces/msg/linux_thermal_zone.hpp"
@@ -15,19 +18,31 @@ class LinuxThermalZoneBaseNode : public rclcpp::Node
1518

1619
protected:
1720
private:
18-
size_t linux_thermal_zone_pub_count_;
19-
rclcpp::TimerBase::SharedPtr timer_1s_;
20-
rclcpp::TimerBase::SharedPtr timer_10s_;
21+
struct Params
22+
{
23+
double data_pub_rate_hz_;
24+
double hk_pub_rate_hz_;
25+
double data_acquisition_rate_hz_;
26+
} params;
27+
28+
std::thread data_acquisition_thread_;
29+
std::mutex linux_thermal_zone_msgs_mutex_;
30+
std::vector<linux_thermal_zone_interfaces::msg::LinuxThermalZone> linux_thermal_zone_msgs_;
31+
std::atomic<size_t> linux_thermal_zone_pub_count_;
32+
rclcpp::TimerBase::SharedPtr data_pub_timer_;
33+
rclcpp::TimerBase::SharedPtr hk_pub_timer_;
2134
std::vector<rclcpp::Publisher<linux_thermal_zone_interfaces::msg::LinuxThermalZone>::SharedPtr>
2235
publishers_linux_thermal_zone_;
2336
rclcpp::Publisher<linux_thermal_zone_interfaces::msg::LinuxThermalZoneBaseNodeHk>::SharedPtr
2437
publisher_node_hk_;
2538

26-
void timer_1s_callback(void);
27-
void timer_10s_callback(void);
39+
void data_pub_timer_callback(void);
40+
void hk_pub_timer_callback(void);
41+
void data_acquisition_thread(void);
2842
std::vector<linux_thermal_zone_interfaces::msg::LinuxThermalZone> GetZoneMsgVector(void);
2943
linux_thermal_zone_interfaces::msg::LinuxThermalZone GetZoneMsg(
3044
std::string key, uint8_t zone_index);
31-
double GetZoneTemperature(std::string prefix);
45+
double GetZoneTemperature(std::string thermal_zone_dir);
46+
std::string GetZoneString(std::string filepath);
3247
uint8_t CountMatchingDirectories(const std::string & pattern);
3348
};

src/linux_thermal_zone_base_node.cpp

+79-11
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,32 @@ LinuxThermalZoneBaseNode::LinuxThermalZoneBaseNode(const std::string & node_name
1414
{
1515
RCLCPP_INFO_STREAM(this->get_logger(), "default constructor executed");
1616

17-
timer_1s_ =
18-
this->create_wall_timer(1s, std::bind(&LinuxThermalZoneBaseNode::timer_1s_callback, this));
19-
timer_10s_ =
20-
this->create_wall_timer(10s, std::bind(&LinuxThermalZoneBaseNode::timer_10s_callback, this));
17+
// ros parameters
18+
auto rate_param_desc = rcl_interfaces::msg::ParameterDescriptor{};
19+
rate_param_desc.description = "Frequency (rate in Hz) of type: double";
20+
this->declare_parameter("data_pub_rate_hz", 1.0, rate_param_desc);
21+
this->declare_parameter("hk_pub_rate_hz", 0.1, rate_param_desc);
22+
this->declare_parameter("data_acquisition_rate_hz", 0.5, rate_param_desc);
23+
params.data_pub_rate_hz_ = this->get_parameter("data_pub_rate_hz").as_double();
24+
params.hk_pub_rate_hz_ = this->get_parameter("hk_pub_rate_hz").as_double();
25+
params.data_acquisition_rate_hz_ = this->get_parameter("data_acquisition_rate_hz").as_double();
26+
27+
// threads
28+
data_acquisition_thread_ =
29+
std::thread(std::bind(&LinuxThermalZoneBaseNode::data_acquisition_thread, this));
30+
31+
// timers
32+
data_pub_timer_ = this->create_wall_timer(
33+
std::chrono::milliseconds(static_cast<int64_t>(1000.0 / params.data_pub_rate_hz_)),
34+
std::bind(&LinuxThermalZoneBaseNode::data_pub_timer_callback, this));
35+
hk_pub_timer_ = this->create_wall_timer(
36+
std::chrono::milliseconds(static_cast<int64_t>(1000.0 / params.hk_pub_rate_hz_)),
37+
std::bind(&LinuxThermalZoneBaseNode::hk_pub_timer_callback, this));
2138
RCLCPP_INFO_STREAM(this->get_logger(), "timers created");
2239

2340
uint8_t num_thermal_zones = CountMatchingDirectories("thermal_zone");
2441

42+
// publishers
2543
for (uint8_t zone_index = 0; zone_index < num_thermal_zones; zone_index++) {
2644
std::string zone_string = "thermal_zone" + std::to_string(zone_index);
2745
publishers_linux_thermal_zone_.push_back(
@@ -37,28 +55,48 @@ LinuxThermalZoneBaseNode::LinuxThermalZoneBaseNode(const std::string & node_name
3755
LinuxThermalZoneBaseNode::~LinuxThermalZoneBaseNode()
3856
{
3957
RCLCPP_INFO_STREAM(this->get_logger(), "destructor executed");
58+
59+
data_acquisition_thread_.join();
4060
}
4161

4262
// PROTECTED FUNCTIONS
4363

4464
// PRIVATE FUNCTIONS
4565

46-
void LinuxThermalZoneBaseNode::timer_1s_callback()
66+
void LinuxThermalZoneBaseNode::data_acquisition_thread(void)
67+
{
68+
rclcpp::Rate rate(params.data_acquisition_rate_hz_);
69+
while (rclcpp::ok()) {
70+
RCLCPP_INFO_STREAM(
71+
this->get_logger(),
72+
"data_acquisition_thread executed on thread id: " << std::this_thread::get_id());
73+
auto msgs = GetZoneMsgVector();
74+
std::unique_lock<std::mutex> lock(linux_thermal_zone_msgs_mutex_);
75+
linux_thermal_zone_msgs_ = msgs;
76+
lock.unlock(); // unlock the mutex explicitly
77+
rate.sleep(); // sleep to maintain the loop rate
78+
}
79+
}
80+
81+
void LinuxThermalZoneBaseNode::data_pub_timer_callback()
4782
{
48-
RCLCPP_DEBUG_STREAM(this->get_logger(), "timer_1s_callback executed");
49-
std::vector<linux_thermal_zone_interfaces::msg::LinuxThermalZone> msgs = GetZoneMsgVector();
83+
RCLCPP_DEBUG_STREAM(this->get_logger(), "data_pub_timer_callback executed");
5084

5185
RCLCPP_INFO_STREAM(
52-
this->get_logger(), "Publishing: " << msgs.size() << " LinuxThermalZone messages");
86+
this->get_logger(),
87+
"Publishing: " << linux_thermal_zone_msgs_.size() << " LinuxThermalZone messages");
88+
89+
const std::lock_guard<std::mutex> lock(
90+
linux_thermal_zone_msgs_mutex_); // lock until end of scope
5391
for (uint8_t index = 0; index < publishers_linux_thermal_zone_.size(); index++) {
54-
publishers_linux_thermal_zone_.at(index)->publish(msgs.at(index));
92+
publishers_linux_thermal_zone_.at(index)->publish(linux_thermal_zone_msgs_.at(index));
5593
linux_thermal_zone_pub_count_++;
5694
}
5795
}
5896

59-
void LinuxThermalZoneBaseNode::timer_10s_callback()
97+
void LinuxThermalZoneBaseNode::hk_pub_timer_callback()
6098
{
61-
RCLCPP_DEBUG_STREAM(this->get_logger(), "timer_10s_callback executed");
99+
RCLCPP_DEBUG_STREAM(this->get_logger(), "hk_pub_timer_callback executed");
62100
linux_thermal_zone_interfaces::msg::LinuxThermalZoneBaseNodeHk message;
63101
message.set__linux_thermal_zone_publish_count(linux_thermal_zone_pub_count_);
64102
publisher_node_hk_->publish(message);
@@ -107,11 +145,15 @@ linux_thermal_zone_interfaces::msg::LinuxThermalZone LinuxThermalZoneBaseNode::G
107145
std::string id = key + std::to_string(zone_index);
108146
std::string thermal_zone_dir = prefix + id;
109147

148+
// header
110149
msg.header.set__stamp(now());
150+
msg.header.set__frame_id(id);
111151
// temperature
112152
msg.temperature.header.set__stamp(now());
113153
msg.temperature.header.set__frame_id(id);
114154
msg.temperature.temperature = GetZoneTemperature(thermal_zone_dir);
155+
// type
156+
msg.type = GetZoneString(thermal_zone_dir + "/type");
115157

116158
return msg;
117159
}
@@ -146,3 +188,29 @@ double LinuxThermalZoneBaseNode::GetZoneTemperature(std::string thermal_zone_dir
146188

147189
return temperature;
148190
}
191+
192+
std::string LinuxThermalZoneBaseNode::GetZoneString(std::string filepath)
193+
{
194+
std::ifstream file(filepath);
195+
std::string return_string;
196+
197+
if (file.is_open()) {
198+
std::string line;
199+
std::getline(file, line); // Read the first line (assuming it contains the value)
200+
file.close();
201+
202+
// Copy string to return and handle errors
203+
try {
204+
return_string = line;
205+
RCLCPP_DEBUG_STREAM(this->get_logger(), filepath << " value: " << return_string);
206+
} catch (const std::invalid_argument & e) {
207+
RCLCPP_WARN_STREAM(this->get_logger(), "Invalid type data in file: " << filepath);
208+
} catch (const std::out_of_range & e) {
209+
RCLCPP_WARN_STREAM(this->get_logger(), "Type value out of range in file: " << filepath);
210+
}
211+
} else {
212+
std::cerr << "Failed to open file " << filepath << std::endl;
213+
}
214+
215+
return return_string;
216+
}

0 commit comments

Comments
 (0)