Skip to content

Comments

Scaling tweaks#9653

Open
NomDeTom wants to merge 10 commits intomeshtastic:developfrom
NomDeTom:scaling_tweaks
Open

Scaling tweaks#9653
NomDeTom wants to merge 10 commits intomeshtastic:developfrom
NomDeTom:scaling_tweaks

Conversation

@NomDeTom
Copy link
Contributor

@Jorropo did the thing. Have a look.

🤝 Attestations

  • I have tested that my proposed changes behave as described.
  • I have tested that my proposed changes do not cause any obvious regressions on the following devices:
    • Heltec (Lora32) V3
    • LilyGo T-Deck
    • LilyGo T-Beam
    • RAK WisBlock 4631
    • Seeed Studio T-1000E tracker card
    • Other (please specify below)

@github-actions github-actions bot added needs-review Needs human review enhancement New feature or request labels Feb 15, 2026
@Jorropo Jorropo requested review from Jorropo and Copilot and removed request for Jorropo February 15, 2026 01:07
@Jorropo Jorropo added the cleanup Code cleanup or refactor label Feb 15, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request attempts to improve the congestion scaling algorithm in Meshtastic by replacing hardcoded throttling factors with a dynamic formula based on LoRa spread factor and bandwidth. The goal is to make the scaling more responsive to actual radio parameters rather than using preset-specific constants.

Changes:

  • Modified Default::congestionScalingCoefficient() to calculate throttling factors using pow(2, spread_factor) / (bandwidth * 100000) instead of hardcoded values
  • Added unit tests in test/test_default/test_main.cpp to verify scaling behavior for different device roles and presets
  • Updated comments to document the new formula values compared to original hardcoded factors

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.

File Description
src/mesh/Default.h Replaced hardcoded throttling factors (0.075, 0.04, 0.02, 0.01) with formula-based calculation using spread factor and bandwidth
test/test_default/test_main.cpp Added new test file with 4 test cases for router, client below threshold, client with default scaling, and client with MEDIUM_FAST preset

Comment on lines 21 to 27
void test_client_default_preset_scaling()
{
config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT;
config.lora.use_preset = false;
// nodesOverForty = 10 -> coefficient = 1 + 10 * 0.075 = 1.75 => 60000 * 1.75 = 105000
uint32_t res = Default::getConfiguredOrDefaultMsScaled(0, 60, 50);
TEST_ASSERT_EQUAL_UINT32(105000U, res);
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test doesn't set config.lora.bandwidth or config.lora.spread_factor when using use_preset = false. The new formula in Default.h directly accesses these fields, which will be 0 after initializeTestEnvironment() initializes config, leading to division by zero.

The test should explicitly set these fields, for example:

config.lora.bandwidth = 250;  // 250 kHz
config.lora.spread_factor = 11;  // LONG_FAST default

However, note that the formula in Default.h has bugs that need to be fixed first (see comments on Default.h).

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 53
// Unit tests for Default::getConfiguredOrDefaultMsScaled
#include "Default.h"
#include "TestUtil.h"
#include <unity.h>

void test_router_no_scaling()
{
config.device.role = meshtastic_Config_DeviceConfig_Role_ROUTER;
uint32_t res = Default::getConfiguredOrDefaultMsScaled(0, 60, 100);
TEST_ASSERT_EQUAL_UINT32(60000U, res);
}

void test_client_below_threshold()
{
config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT;
config.lora.use_preset = false;
uint32_t res = Default::getConfiguredOrDefaultMsScaled(0, 60, 40);
TEST_ASSERT_EQUAL_UINT32(60000U, res);
}

void test_client_default_preset_scaling()
{
config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT;
config.lora.use_preset = false;
// nodesOverForty = 10 -> coefficient = 1 + 10 * 0.075 = 1.75 => 60000 * 1.75 = 105000
uint32_t res = Default::getConfiguredOrDefaultMsScaled(0, 60, 50);
TEST_ASSERT_EQUAL_UINT32(105000U, res);
}

void test_client_medium_fast_preset_scaling()
{
config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT;
config.lora.use_preset = true;
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST;
// nodesOverForty = 30 -> coefficient = 1 + 30 * 0.02 = 1.6 => 60000 * 1.6 = 96000
uint32_t res = Default::getConfiguredOrDefaultMsScaled(0, 60, 70);
TEST_ASSERT_EQUAL_UINT32(96000U, res);
}

void setup()
{
// Small delay to match other test mains
delay(10);
initializeTestEnvironment();
UNITY_BEGIN();
RUN_TEST(test_router_no_scaling);
RUN_TEST(test_client_below_threshold);
RUN_TEST(test_client_default_preset_scaling);
RUN_TEST(test_client_medium_fast_preset_scaling);
exit(UNITY_END());
}

void loop() {}
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test suite is missing several important test cases:

  1. Test with explicitly set bandwidth and spread_factor: When use_preset = false, both fields should be explicitly set to avoid division by zero and test the actual formula behavior.

  2. Test for LONG_FAST preset: Should test the default preset (SF11, BW=250kHz) with use_preset = true.

  3. Test for edge cases:

    • Very high node counts (e.g., 100+ nodes)
    • Special bandwidth codes (31, 62, 200, 800, 1600) that map to non-integer kHz values
    • Different spread factors (SF7, SF12)
  4. Test for SENSOR and TRACKER roles: These roles also don't scale (like ROUTER), according to Default.cpp lines 45-46.

These additional tests would help ensure the formula works correctly across all supported configurations.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done it all again. Lets see what it looks like...

thebentern and others added 2 commits February 15, 2026 06:45
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@NomDeTom NomDeTom marked this pull request as ready for review February 20, 2026 14:04
@NomDeTom
Copy link
Contributor Author

Looks like the tests need some work:

Portduino is starting, VFS root at /home/runner/.portduino/default
Running in simulated mode.
DEBUG | ??:??:?? 0 Upgrade time to quality NTP
WARN  | 14:12:40 0 RTC not found (found address 0x00)
WARN  | 14:12:40 0 RTC not found (found address 0x00)
test/test_default/test_main.cpp:45:test_router_no_scaling:FAIL: Expected 133728 Was 60000
test/test_default/test_main.cpp:90:test_client_below_threshold:PASS
test/test_default/test_main.cpp:91:test_client_default_preset_scaling:PASS
test/test_default/test_main.cpp:80:test_client_medium_fast_preset_scaling:FAIL: Expected 96864 Was 96863

@NomDeTom
Copy link
Contributor Author

Better:

Processing test_default in coverage environment
--------------------------------------------------------------------------------
Building...
Testing...
Portduino is starting, VFS root at /home/runner/.portduino/default
Running in simulated mode.
DEBUG | ??:??:?? 0 Upgrade time to quality NTP
WARN  | 06:58:59 0 RTC not found (found address 0x00)
WARN  | 06:58:59 0 RTC not found (found address 0x00)
test/test_default/test_main.cpp:102:test_router_no_scaling:PASS
test/test_default/test_main.cpp:103:test_client_below_threshold:PASS
test/test_default/test_main.cpp:104:test_client_default_preset_scaling:PASS
test/test_default/test_main.cpp:105:test_client_medium_fast_preset_scaling:PASS
-----------------------
4 Tests 0 Failures 0 Ignored 
OK
-------------- coverage:test_default [PASSED] Took 14.49 seconds --------------

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cleanup Code cleanup or refactor enhancement New feature or request needs-review Needs human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants