fix run node fail, modify arm control panel

This commit is contained in:
2025-10-28 11:53:25 +08:00
parent 78811099d8
commit f4912b9711
2 changed files with 81 additions and 30 deletions

View File

@@ -209,6 +209,9 @@ def build_ui(node: CtrlGuiNode) -> None:
ui.button('Cancel', on_click=dialog.close).classes('text-white bg-red-500')
dialog.open()
# Shared variables for arm control
arm_inputs = {}
with ui.row():
# send action package
@@ -372,25 +375,51 @@ def build_ui(node: CtrlGuiNode) -> None:
#move arm
with ui.column():
with ui.row():
left_arm_position_pose = ui.input('LEFT_ARM_POSE: x, y, z, rx, ry, rz, w', value='0, 0, 0, 0, 0, 0, 0').style('width: 550px')
arm_mode_select = ui.select(['MoveJ', 'MoveP'], value='MoveP').style('width: 100px')
with ui.row():
right_arm_position_pose = ui.input('RIGHT_ARM_POSE: x, y, z, rx, ry, rz, w', value='0, 0, 0, 0, 0, 0, 0').style('width: 550px')
with ui.column():
arm_inputs_container = ui.column()
# TODO check input data
def update_arm_inputs():
arm_inputs_container.clear()
arm_inputs.clear()
if arm_mode_select.value == 'MoveJ':
with arm_inputs_container:
with ui.row():
arm_inputs['left'] = ui.input('LEFT_ARM_JOINT: j1, j2, j3, j4, j5, j6', value='0, 0, 0, 0, 0, 0').style('width: 550px')
with ui.row():
arm_inputs['right'] = ui.input('RIGHT_ARM_JOINT: j1, j2, j3, j4, j5, j6', value='0, 0, 0, 0, 0, 0').style('width: 550px')
elif arm_mode_select.value == 'MoveP':
with arm_inputs_container:
with ui.row():
arm_inputs['left'] = ui.input('LEFT_ARM_POSE: x, y, z, rx, ry, rz, w', value='0, 0, 0, 0, 0, 0, 0').style('width: 550px')
with ui.row():
arm_inputs['right'] = ui.input('RIGHT_ARM_POSE: x, y, z, rx, ry, rz, w', value='0, 0, 0, 0, 0, 0, 0').style('width: 550px')
def move_arm_() -> None:
node.file_logger.info('Running move_arm_...')
action_name = "Arm"
text = f"body_id: 0\ndata_type: 3\ndata_length: 14\ncommand_id: 0\nframe_time_stamp: {node.get_clock().now().to_msg().sec}\ndata_array: [{left_arm_position_pose.value}, {right_arm_position_pose.value}]\n"
# send_action_package(action_name, text)
rebuild_now("Remote", action_name, text)
# Initial update
update_arm_inputs()
ui.button('Arm Control', on_click=lambda: show_confirm_dialog(
f'Confirm Move Arm operation?\nleft_arm_pose: {left_arm_position_pose.value}\nright_arm_pose: {right_arm_position_pose.value}\n',
move_arm_
)).classes('self-end')
# Update inputs when select value changes
arm_mode_select.on('update:model-value', lambda e: update_arm_inputs())
def move_arm_() -> None:
node.file_logger.info('Running move_arm_...')
action_name = "Arm"
if arm_mode_select.value == 'MoveJ':
data_type = 2
data_length = 12
elif arm_mode_select.value == 'MoveP':
data_type = 3
data_length = 14
text = f"body_id: 0\ndata_type: {data_type}\ndata_length: {data_length}\ncommand_id: 0\nframe_time_stamp: {node.get_clock().now().to_msg().sec}\ndata_array: [{arm_inputs['left'].value}, {arm_inputs['right'].value}]\n"
# send_action_package(action_name, text)
rebuild_now("Remote", action_name, text)
ui.button('Arm Control', on_click=lambda: show_confirm_dialog(
f'Confirm Move Arm operation?\nMove: {arm_mode_select.value}\nleft_arm_params: {arm_inputs["left"].value}\nright_arm_params: {arm_inputs["right"].value}\n',
move_arm_
)).classes('self-end')
# Add statistics display
# ui.separator()
@@ -489,10 +518,30 @@ def main() -> None:
spin_thread = threading.Thread(target=rclpy.spin, args=(node,), daemon=True)
spin_thread.start()
# Add static file serving for background image
# Add static file serving: prefer workspace ../static (with background.png), fallback to package static
from nicegui import app
static_path = os.path.join(os.path.dirname(__file__), '..', 'static')
app.mount('/static', StaticFiles(directory=static_path), name='static')
pkg_static = os.path.join(os.path.dirname(__file__), 'static')
# Allow explicit override via environment variable
override_static = os.getenv('CTRLGUI_STATIC_DIR')
static_path = None
if override_static and os.path.isdir(override_static):
static_path = override_static
else:
# Prefer share-installed static (from package data_files)
try:
from ament_index_python.packages import get_package_share_directory
share_dir = get_package_share_directory('ctrlgui')
share_static = os.path.join(share_dir, 'static')
if os.path.isdir(share_static):
static_path = share_static
except Exception:
static_path = None
# Fallback to packaged static inside site-packages
if not static_path:
static_path = pkg_static
print("static_path: " + static_path)
if os.path.isdir(static_path):
app.mount('/static', StaticFiles(directory=static_path), name='static')
# Build UI for the default page
@ui.page('/')
@@ -523,18 +572,15 @@ def main() -> None:
atexit.register(shutdown)
if __name__ in {"__main__", "__mp_main__"}:
# Import StaticFiles for serving static files
from starlette.staticfiles import StaticFiles
# Start NiceGUI honoring HOST/PORT environment variables (configurable via ROS launch)
# Start NiceGUI honoring HOST/PORT environment variables (works with ros2 launch env)
host = os.getenv('HOST', '0.0.0.0')
try:
port = int(os.getenv('PORT', '8080'))
except ValueError:
port = 8080
print(f'Starting NiceGUI on {host}:{port}...')
main()
ui.run(title='HiveCore Robot Control Panel', host=host, port=port, reload=False, uvicorn_logging_level='info')
else:
ui.run(main, title='HiveCore Robot Control Panel')
if __name__ in {"__main__", "__mp_main__"}:
main()

View File

@@ -1,6 +1,6 @@
from setuptools import find_packages, setup
import os
from glob import glob
import os
package_name = 'ctrlgui'
@@ -8,14 +8,19 @@ setup(
name=package_name,
version='0.0.0',
packages=find_packages(exclude=['test']),
include_package_data=True,
package_data={
'ctrlgui': ['static/*'],
},
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
('share/' + package_name + '/launch', ['launch/ctrlgui.launch.py']),
('share/' + package_name + '/static',
[os.path.join('static', 'background.png'),
os.path.join('static', 'favicon.ico')]),
# Install top-level static assets into share for runtime serving
('share/' + package_name + '/static', [
*glob(os.path.join('static', '*'))
]),
],
install_requires=['setuptools', 'nicegui>=1.4.0'],
zip_safe=True,