Skip to content

Integrate DroidPad: Convert control value range from -100 to 100 to -1.0 to 1.0#20

Merged
dorkmo merged 3 commits intomainfrom
copilot/fix-d8a1df7a-2b93-4485-99d3-647c8130dbd6
Oct 4, 2025
Merged

Integrate DroidPad: Convert control value range from -100 to 100 to -1.0 to 1.0#20
dorkmo merged 3 commits intomainfrom
copilot/fix-d8a1df7a-2b93-4485-99d3-647c8130dbd6

Conversation

Copy link
Contributor

Copilot AI commented Oct 4, 2025

Overview

This PR addresses issue #14 by integrating native support for DroidPad and similar joystick interfaces that output values in the range of -1.0 to 1.0 (float) instead of the previous -100 to 100 (integer) range.

Problem

DroidPad (https://github.com/UmerCodez/DroidPad) outputs joystick values from 1.0 to -1.0, which is incompatible with the existing LifeTrac v25 control system that expected integer values from -100 to 100. This required changes across the ESP32 remote control, Arduino Opta controller, and ROS2 bridge to make all components natively interoperable.

Solution

Converted the entire control system to use floating-point values in the range -1.0 to 1.0 throughout the stack:

ESP32 Remote Control

  • Updated ControlData struct to use float instead of int
  • Implemented proper conversion: (joystick_value - 511.5) / 511.5 to map 0-1023 ADC range to -1.0 to 1.0
  • Updated deadzone from 10 to 0.1 (maintaining 10% threshold)

Arduino Opta Controller

  • Updated JoystickData struct to use float values
  • Modified DEADZONE constant from 10 to 0.1
  • Updated flow control calculation: 4 + (int)(maxInput * 16.0) to maintain proper 4-20mA output range
  • Updated function signatures for controlTrack() and controlValve() to accept float parameters

ROS2 Bridge

  • Changed ControlCommand.msg fields from int32 to float32
  • Updated validation logic to check ±1.0 range instead of ±100
  • Updated test publisher demo sequences to use float values
  • Updated all documentation and code examples

Test Scripts

  • Updated mqtt_test.py with float values in demo sequences and interactive mode

Key Technical Details

Value Conversion:

// ESP32: Convert 10-bit ADC (0-1023) to normalized range (-1.0 to 1.0)
currentControl.left_x = (leftX - 511.5) / 511.5;

Flow Control Mapping (unchanged behavior):

// Maps 0.0-1.0 input to 4-20mA output (same as before)
int currentValue = 4 + (int)(maxInput * 16.0);

MQTT Message Format:

{
  "left_x": 0.0,   // -1.0 to 1.0 (left/right turn)
  "left_y": 0.5,   // -1.0 to 1.0 (forward/backward)
  "right_x": 0.0,  // -1.0 to 1.0 (bucket control)
  "right_y": 0.7,  // -1.0 to 1.0 (arms control)
  "timestamp": 1234567890
}

Documentation

Added comprehensive DROIDPAD_INTEGRATION.md guide covering:

  • Component-by-component changes explanation
  • DroidPad setup instructions
  • MQTT message format and control mapping
  • Value interpretation and flow control formula
  • Migration guide for existing integrations
  • Testing procedures

Safety & Compatibility

✅ All safety features preserved:

  • Deadzone remains at 10% of range (0.1 instead of 10)
  • 1-second timeout protection unchanged
  • Emergency stop (all zeros) works identically
  • Input validation enforces ±1.0 limits

✅ Functional equivalence maintained:

  • 0.5 float = 50% power (same as integer 50 was before)
  • Flow control produces identical 4-20mA output curve
  • Tank steering calculations work identically

✅ Native DroidPad compatibility:

  • Accepts 1.0 to -1.0 values directly
  • No intermediate conversion needed
  • Works with any MQTT-capable joystick interface

Testing

Verified mathematical correctness of conversion:

  • Input 0 → -1.0 (full negative)
  • Input 511 → ~0.0 (center/neutral)
  • Input 1023 → 1.0 (full positive)

Flow control mapping verified:

  • 0.0 → 4mA (no flow)
  • 0.5 → 12mA (50% flow)
  • 1.0 → 20mA (100% flow)

Migration

Existing integrations need minimal changes:

# Old code
msg["left_y"] = 50  # 50% forward

# New code
msg["left_y"] = 0.5  # 50% forward

Fixes #14

Co-authored-by: dorkmo 1923070+dorkmo@users.noreply.github.com

Original prompt

This section details on the original issue you should resolve

<issue_title>Integrate DroidPad</issue_title>
<issue_description>> it looks like using https://github.com/UmerCodez/DroidPad will be a better option, the default outputs for the joysticks appear to be values from 1.0 to -1.0 we may need to change the logic on the arduino opta

Originally posted by @dorkmo in #14

For version v25, what changes need to be made to allow use of droidpad? What changes to the esp32, ros2 bridge and opta code need to be made to make them all natively interoperable? message command range need to change from 100 to -100 to 1.0 to -1.0 ? What else?</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #19

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI and others added 2 commits October 4, 2025 07:18
…ad compatibility

Co-authored-by: dorkmo <1923070+dorkmo@users.noreply.github.com>
Co-authored-by: dorkmo <1923070+dorkmo@users.noreply.github.com>
Copilot AI changed the title [WIP] Integrate DroidPad Integrate DroidPad: Convert control value range from -100 to 100 to -1.0 to 1.0 Oct 4, 2025
Copilot AI requested a review from dorkmo October 4, 2025 07:22
@dorkmo dorkmo marked this pull request as ready for review October 4, 2025 08:03
Copilot AI review requested due to automatic review settings October 4, 2025 08:03
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 PR converts the LifeTrac v25 control system from integer values (-100 to 100) to floating-point values (-1.0 to 1.0) to enable native compatibility with DroidPad and similar joystick interfaces.

  • Updated all control data structures to use float instead of int
  • Modified joystick conversion formulas and deadzone thresholds
  • Added comprehensive DroidPad integration documentation

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
lifetrac_v25_remote.ino Updated ESP32 control data structures and joystick conversion to float range
lifetrac_v25_controller.ino Modified Arduino Opta controller to accept float values and updated flow control mapping
ControlCommand.msg Changed ROS2 message fields from int32 to float32
mqtt_bridge_node.py Updated validation logic to check ±1.0 range instead of ±100
test_publisher.py Updated ROS2 test sequences to use float values
mqtt_test.py Updated MQTT test script with float values in demo sequences
README.md Added DroidPad compatibility feature and documentation reference
INTEGRATION_OVERVIEW.md Updated code examples to use new float value range
DROIDPAD_INTEGRATION.md Added comprehensive integration guide for DroidPad setup

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@dorkmo
Copy link
Contributor

dorkmo commented Oct 4, 2025

@copilot lets change the droidpad_integration.md to focus on how to implement the app and remove info about changes from the previous versions

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

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +205 to +206
leftTrackSpeed = constrain(leftTrackSpeed, -1.0, 1.0);
rightTrackSpeed = constrain(rightTrackSpeed, -1.0, 1.0);
Copy link

Copilot AI Oct 4, 2025

Choose a reason for hiding this comment

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

The constrain() function expects integer parameters but is being passed float values. Use fminf() and fmaxf() functions or cast the result to ensure proper float constraint handling.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

@copilot can you fix this?

@dorkmo
Copy link
Contributor

dorkmo commented Oct 4, 2025

@copilot The constrain() function expects integer parameters but is being passed float values. Use fminf() and fmaxf() functions or cast the result to ensure proper float constraint handling.

@dorkmo
Copy link
Contributor

dorkmo commented Oct 4, 2025

@copilot on lines 205 and 206 The constrain() function expects integer parameters but is being passed float values. Use fminf() and fmaxf() functions or cast the result to ensure proper float constraint handling.

@dorkmo dorkmo merged commit 8613bd3 into main Oct 4, 2025
4 checks passed
@dorkmo dorkmo deleted the copilot/fix-d8a1df7a-2b93-4485-99d3-647c8130dbd6 branch October 4, 2025 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integrate DroidPad android mqtt app option for v25

3 participants