smiller29
Hello @Athena,
I am currently exploring the feasibility of using a Windows 11-compatible controller to execute a Python client script that transmits XInput data to a Python server script on the ARC Skill Control Board. My objective is to manage an H-Bridge with PWM speed control to facilitate tank track movement using the Synthiam ARC platform. Do you think this setup can be achieved?
I am employing the Anbernic Win600 controller, as depicted in the image below:
At present, I am endeavoring to deploy a Python-coded server on my ARC-enabled PC to process control signals. I’ve included the Python script I’m using for this configuration below.
#!/usr/bin/env python3
# Async TCP receiver that prints controller events and maintains a latest_state snapshot.
import asyncio, json, signal, sys
from collections import defaultdict
HOST = "0.0.0.0"
PORT = 5555
PRINT_EVENTS = True
latest_state = {
"buttons": defaultdict(lambda: False),
"axes": defaultdict(lambda: 0.0),
"hat": {"x": 0, "y": 0},
"t": 0.0,
}
def apply_event(ev):
et = ev.get("type")
latest_state["t"] = ev.get("t", latest_state["t"])
if et == "button":
name = ev.get("name", f"BTN{ev.get('index', -1)}")
pressed = bool(ev.get("pressed", False))
latest_state["buttons"][name] = pressed
if PRINT_EVENTS:
print(f"[BTN] {name}: {'DOWN' if pressed else 'UP'}")
elif et == "axis":
name = ev.get("name", f"AXIS{ev.get('index', -1)}")
val = float(ev.get("value", 0.0))
latest_state["axes"][name] = val
if PRINT_EVENTS:
print(f"[AXIS] {name}: {val:+.3f}")
elif et == "hat":
v = ev.get("value", {"x": 0, "y": 0})
latest_state["hat"] = {"x": int(v.get("x", 0)), "y": int(v.get("y", 0))}
if PRINT_EVENTS:
x, y = latest_state["hat"]["x"], latest_state["hat"]["y"]
dirs = []
if y == 1: dirs.append("Up")
if y == -1: dirs.append("Down")
if x == -1: dirs.append("Left")
if x == 1: dirs.append("Right")
print(f"[HAT] DPad: {'+'.join(dirs) if dirs else 'Neutral'}")
async def handle_client(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
peer = writer.get_extra_info("peername")
print(f"[server] Client connected: {peer}")
try:
while True:
line = await reader.readline()
if not line:
break
try:
ev = json.loads(line.decode("utf-8"))
except json.JSONDecodeError:
continue
apply_event(ev)
except asyncio.CancelledError:
pass
finally:
print(f"[server] Client disconnected: {peer}")
try:
writer.close()
await writer.wait_closed()
except Exception:
pass
async def status_printer():
while True:
await asyncio.sleep(0.5)
lx = latest_state["axes"]["LX"]; ly = latest_state["axes"]["LY"]
rx = latest_state["axes"]["RX"]; ry = latest_state["axes"]["RY"]
lt = latest_state["axes"]["LT"]; rt = latest_state["axes"]["RT"]
a = latest_state["buttons"]["A"]; b = latest_state["buttons"]["B"]
d = latest_state["hat"]
print(f"[state] LX:{lx:+.2f} LY:{ly:+.2f} RX:{rx:+.2f} RY:{ry:+.2f} LT:{lt:.2f} RT:{rt:.2f} A:{int(a)} B:{int(b)} D:{d}")
async def main():
server = await asyncio.start_server(handle_client, HOST, PORT)
print(f"[server] Listening on {HOST}:{PORT}")
sp = asyncio.create_task(status_printer())
# Graceful shutdown for Windows
stop = asyncio.Future()
def _sig():
if not stop.done():
stop.set_result(True)
loop = asyncio.get_running_loop()
try:
loop.add_signal_handler(signal.SIGINT, _sig) # may raise on Windows for some signals
loop.add_signal_handler(signal.SIGTERM, _sig)
except (NotImplementedError, AttributeError):
# Fallback: rely on KeyboardInterrupt
pass
async with server:
await asyncio.gather(server.serve_forever(), stop)
sp.cancel()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
sys.exit(0)
I am eager to understand how to integrate this Python script to efficiently utilize the XInput data along with the ARC platform's capabilities for controlling tank tracks via the H-Bridge with PWM speed control. The H-Bridge interfaces with an Arduino Nano running the EZB firmware. Any insights or guidance on effectively achieving this setup would be greatly appreciated. Additionally, I aim to program other buttons for various ARC skills or script triggers.


Below is an overview of how you can integrate your Windows 11 controller (via your Python scripts) with Synthiam ARC to control your tank tracks using an H-Bridge (via PWM control) on your Arduino Nano running EZB Firmware.
Overview of the Approach
Controller to Python Server Communication
Your Python server script (running on your ARC-enabled PC) listens on a TCP port (in your case, port 5555) for XInput events from your Windows 11 controller.
When a controller button is pressed or an analog axis moves, your server receives the event, updates an internal state (such as duty cycle values or directional flags), and prints/logs the information.
Python Server to ARC Integration
Once the controller events are processed, you want to forward these events (or trigger actions) inside ARC.
There are two common ways to do this:
Option A: Update ARC Global Variables and Call ARC Commands in a Python Script Running Within ARC
You can create an ARC Python script (or a robot skill that supports Python) that monitors variables (like
$LeftMotorPWMand$RightMotorPWM) and then calls the built-inPWM.set()function to adjust the tank motors.Option B: Write an ARC robot skill with a Built-in TCP Client
Implement a TCP client within an ARC Python script that directly connects to your Python server. Once connected, when you receive the controller events, you immediately trigger ARC commands (for example,
PWM.set(d0, dutyCycle)) to update motor speeds.Mapping Controller Events to H-Bridge Motor Control
Depending on your tank drive setup, you’ll likely have two PWM channels (one for each track).
For example, you might assign:
In your ARC Python script, you could map the analog joystick values (or the trigger values) to duty cycles (0-100) and then call:
ARC’s built-in
sleep()(which uses milliseconds) and global variable functions (getVar()/setVar()) can help you manage timing and share state between scripts.Step-by-Step Integration
Testing Your Controller Input
First, verify that your Anbernic Win600 controller is correctly detected and that your Python server script (provided in your example) is receiving the XInput events.
You can use the printed output (for example, verifying the values for
LX,LY, triggers, and DPad events) to ensure the mapping is as you expect.Mapping Input to PWM Duty Cycle
Once you have confirmed the controller input is received, decide how you wish to map the analog inputs (e.g., left joystick X and Y, triggers) to the motor speeds.
For instance, a simple mapping might mean:
You can adjust the mapping depending on whether you want differential steering (one motor increasing speed and the other decreasing).
Integrating With ARC Python Scripting
ARC allows you to run Python scripts that can call functions like
PWM.set()and update global variables withsetVar()/getVar().For example, create an ARC Python script (inside a Script Skill) with code similar to:
Modify the above code to fit your mapping strategy. The basic idea is to update ARC with PWM commands based on the incoming controller data.
Mapping Additional Buttons
For extra functions (such as triggering other ARC skills or script events based on button presses), you can similarly use ARC’s commands.
For example, if button A is pressed, you might call a command via:
Define a mapping from your controller button names (as processed in your Python server) to global variables inside ARC, and then have your ARC Python script or Script Skill poll and react.
Running the Integrated Setup
Ensure that both the external Python server and your ARC Python integration are running on the same PC (or have a reliable network connection if on separate systems).
Test the entire flow:
PWM.set()commands to control your motors properly.Additional Considerations
Direct ARC XInput Skill:
Before building a completely custom solution, consider that ARC already includes a Joystick (XInput) Skill. This native skill may handle mapping of analog values and button presses, and you might be able to modify or extend it (or merely use some of its functionality) to suit your tank track control needs.
Creating Custom Robot Skills:
If you need features not offered in default ARC skills, you can create your own robot skill following the guide here:
Create robot skill Overview
Documentation and Resources:
Synthiam ARC Downloads
PWM Python API Documentation
Python API Overview
Final Thoughts and Questions
Yes, it is feasible to use your Windows 11 controller with your Python server to handle XInput and then integrate with Synthiam ARC for controlling the tank tracks via PWM to an H-Bridge. The key points are:
Do you have any questions on any specific part of this setup? For example, would you like more detailed guidance on the TCP/client integration with ARC Python, or further help on mapping the controller's analog values to PWM duty cycle percentages? Feel free to ask!
I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
@Athena where do you define global variables in ARC?
Global variables in ARC are managed through ARC’s Global Variable Storage Manager. This means you can set and access global variables from any ARC skill using functions like setVar() and getVar().
Here are some key points:
Declaring Global Variables:
When you want a variable to be global (accessible by all robot skills and across different script engines), add a leading dollar sign ($) to its name. For example:
Accessing Global Variables:
You can retrieve the value of a global variable from any script using getVar(), like so:
Where to Define Them:
You can define these globals in any ARC script (Python or JavaScript) or within a custom robot skill. It’s common to initialize them in a startup or initialization script so that they’re ready for access by other parts of your project.
Usage Across Skills:
Even though variables created in one script engine (like Python) are private by default, using global variable commands (i.e. with the $ prefix) ensures they are shared across all ARC scripts.
Are you interested in a demo of setting and getting these global variables in one of your ARC scripts? Let me know if you need further details or additional examples!
I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
Doesn't that handheld device run Windows? Wouldn't it make sense to put ARC on the handheld computer? And therefore, do as Athena suggested earlier by simply adding the xinput joystick robot skill to use the joystick that's on the handheld computer?
-- Or--
If the computer is somewhere else, or in the robot, or whatever, why not just use a regular joystick and use the xinput joystick robot skill? And not have to spend 100x on a handheld computer?
Could you provide insight into why you're trying to turn an entire handheld computer into a dedicated joystick?
I googled for something similar and found several suggestions that already exist for using a joystick from a remote computer. Doing get same should help without reinventing the wheel..
smiller29, I know @Athena answered your question of where and how to Declare Global Variables. I'll just validate what it says is true. For me, Declaring Global Variables that need to be used after startup by different scripts throughout my project, I'll declare them all in my INT script with the start up value..
I do have scripts that need to pass a changed Global Variable to other scripts to use (usually if that variable needs to be changed for another script to use te new value).. For these Global Variables, I'll declare the new value at the end of the script passing on the change.
I hope this makes sense.
Hi Dave_Schulpius - thanks for sharing your approach!
You're absolutely right about declaring global variables in ARC. Just to recap and add a bit more detail:
Declaring Global Variables:
As Athena mentioned, when you want a variable to be accessible from anywhere in your project, prefix its name with a dollar sign (e.g., $MyGlobalVar). You typically declare these in your initialization (INT) script, where you can assign them a startup value. This ensures that every script in your ARC project will have a consistent starting point.
Updating Global Variables:
When a script needs to change a global variable's value for use by other scripts, you update it at the end of that script. Any subsequent calls to getVar($MyGlobalVar) in other scripts will then see the new value. This method makes it easy to pass dynamic data between scripts.
Best Practices:
Your approach of declaring them in your INT script and then updating their values later aligns well with typical ARC practices. This helps maintain consistent state across various parts of your project without extra overhead.
Do you have any further questions on handling global variables or integrating them with your specific robot skills? Happy to help!
I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
DJ, the reason I am using this device is because it is also being used as the user interface to my AI system on the Jetson that I have created a web interface for that the touch screen is used for. I have found that having options allows for more flexibility.
The Jetson currently is the LLM TTS STT RAG Vadar and more. It also supports 50% of the vision system for my robot as it has two cameras ARC has the other 50% of the vision processing. The ARC system will be dealing with other sensors and all the servos and lidars.
It sounds like you’ve built a very robust system with distinct responsibilities for each component. Using the handheld device as both the user interface for your AI system on the Jetson (with your web interface and touch screen) and as a controller (in this case, transmitting XInput events) has its benefits. Here are a few insights and tips for your setup:
Dual-Purpose Handheld Device:
Since your handheld device runs Windows, it can easily serve as your AI system’s user interface while also sending controller data. This flexibility lets you display status information, adjust settings, or initiate commands directly via the touch screen-a convenient way to integrate and monitor multiple systems.
Separation of Concerns:
You’re partitioning your processing between the Jetson (LLM, TTS, STT, vision, etc.) and ARC (servos, sensors, lidars, and additional vision processing). This can simplify debugging and maintenance because each platform handles the tasks it’s most suited for. For example:
Controller Integration Options:
With your Windows device already performing as the UI, you now have flexibility in how you capture XInput data. As DJ_Sures mentioned, you could run ARC directly on the handheld device and simply add the XInput joystick robot skill to access the built-in controls. Alternatively, if you prefer keeping ARC on a dedicated system (or in the robot itself), you can use your Python server approach to relay the controller events back to ARC. Either approach can work well-your choice depends on balancing cost, performance, and overall system complexity.
Modularity and Flexibility:
Your design already highlights a modular approach that offers more options. For instance, if you ever wish to extend functionality (say, by adding more buttons for triggering other ARC skills), you’re well set up to do so through global variables and ARC scripting. This modularity is very much in the spirit of the Synthiam ARC platform.
Integration Between Systems:
To integrate the controller data with ARC’s PWM-based H-Bridge control:
This method keeps your systems in sync and leverages ARC’s built-in functions for motor control.
Overall, your setup is quite sophisticated-and using the handheld device to manage both the AI interface on the Jetson and control aspects with ARC gives you multiple avenues for improving the robot’s functionality without unnecessary hardware expenses.
Do you have any questions on how to further integrate the Python server with ARC, or would you like more details on mapping the controller data to specific ARC commands? I’m here to help with more specifics if needed!
I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.