devagent-physical-engine 1.8.2__tar.gz → 1.8.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {devagent_physical_engine-1.8.2/src/devagent_physical_engine.egg-info → devagent_physical_engine-1.8.5}/PKG-INFO +40 -6
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/README.md +39 -5
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/pyproject.toml +2 -2
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/__init__.py +1 -1
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/workpiece_scene_probe.py +137 -31
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5/src/devagent_physical_engine.egg-info}/PKG-INFO +40 -6
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine.egg-info/SOURCES.txt +4 -1
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_industrial_motion_v170.py +2 -2
- devagent_physical_engine-1.8.5/tests/test_package_metadata_v184.py +23 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_transfer_place_diagnostic_v172.py +5 -3
- devagent_physical_engine-1.8.5/tests/test_workpiece_attach_semantics_v183.py +38 -0
- devagent_physical_engine-1.8.5/tests/test_workpiece_scene_probe_v185.py +52 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/NOTICE +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/setup.cfg +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/__init__.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/compiler.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/contracts.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/coordinator.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/critic.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/evidence.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/interpreter.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/planner.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/recovery.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/routing.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/runtime.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/semantic.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/structured.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ai_cli.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/cli.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_campaign.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_cli.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_importer.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_intelligence.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_readiness.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_repository.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/continuous_clearance.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/controller_runtime_hotfix_v181.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/doctor.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/engineering_agent.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/engineering_request.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/evidence_replay.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/evidence_trust.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/execution.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/industrial_motion_hotfix_v170.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/industrial_motion_v170.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/industrial_motion_v182.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/models.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/one_command.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/one_command_runtime.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/one_command_v15.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/one_command_v16.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/operating_envelope.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/__init__.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/benchmark.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/candidates.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/contracts.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/evaluator.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/evidence.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/experience.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/measured.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/optimizer.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/orchestrator.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/physical_campaign.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/physical_evidence.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/physical_motion.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/planning.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/pose_math.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/preexecution_contract.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/production_authority.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/production_grade.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/project.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/__init__.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/anthropic.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/common.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/factory.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/gemini.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/openai.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_criterion.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_qualification.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/providers.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/qualification.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/qualification_cli.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/qualification_harness.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/reference_workcell.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/report_test_execution.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/report_test_execution_strict.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/robot_platform.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/robot_support_v18.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/robots.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/__init__.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/abb_irb1200.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/abb_irb1200_preview.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/acceptance.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/commands.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/continuous_clearance_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/controller_action_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/destination_support_contact_v182.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/doctor.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/fk_pose.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/fk_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/frame_alignment.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/gazebo_cli.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/gazebo_pose.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/gazebo_world.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/industrial_sequence_planner_v170.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/industrial_sequence_planner_v171.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/industrial_sequence_planner_v172.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/industrial_sequence_planner_v182.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/joint_state_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/joint_state_recorder.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/measured_motion.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/moveit_joint_plan_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/moveit_joint_plan_v161_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/moveit_scene.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/moveit_task_planner.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/pilz_sequence_plan_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/pilz_sequence_plan_probe_v182.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/preexecution.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/qualification.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/qualification_v10.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/qualification_v11.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/qualification_v12.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/report_test_visualization.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/report_test_visualization_v170.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/scene_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/state_validity_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/support_contact_acm_probe_v170.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/support_contact_lease_v170.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/support_contact_runner_v161.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/support_contact_v161.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/task_adapter.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/task_visualization.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/tf_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/tool_scene.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/tool_scene_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/trajectory.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/trajectory_action_probe.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/trajectory_tracking.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/ur5e.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/ur5e_adapter.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/ur5e_v10_adapter.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/workpiece_follow.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/workpiece_gazebo_follower.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/workpiece_scene.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/selective_verification.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/selective_verification_v16.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/setup_profile.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/sim_real_qualification.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/simulation.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/simulation_platform.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/smooth_motion_hotfix_v162.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/support_contact_hotfix_v161.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/tool_collision.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/trajectory_qualification.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/twin.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/twin_builder.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/twin_codec.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/twin_materialization.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/user_cli.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/user_cli_v15.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/user_cli_v16.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/user_cli_v18.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/verification.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/workpiece_lifecycle.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine.egg-info/dependency_links.txt +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine.egg-info/entry_points.txt +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine.egg-info/requires.txt +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine.egg-info/top_level.txt +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_abb_irb1200_visual_v18.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_agent_core.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_agent_semantic_hardening.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_ai_cli.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_ai_cli_v07.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_commercial_importer_v1.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_commercial_intelligence_v15.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_commercial_readiness_v1.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_commercial_v1.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_continuous_clearance_v011.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_controller_runtime_hotfix_v181.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_core.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_destination_support_contact_v182.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_engineering_request_v07.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_evidence_replay_v12.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_evidence_trust_coverage_v12.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_evidence_trust_transport_v12.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_evidence_trust_v12.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_evidence_viewer_palette_v130.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_gazebo_cli_v0122.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_golden_abb_runner_v171.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_golden_abb_showcase.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_interpreter_profiles_v08.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_joint_state_probe_v0125.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_live_provider_qualification.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_measured_motion_v10.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_moveit_planning_diagnostics_v0125.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_moveit_scene_v0123.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_natural_language_agent_v07.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_one_command_hardening_v13.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_one_command_pose_hardening_v15.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_one_command_regression_v141.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_one_command_v13.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_openai_strict_schema_v0113.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_optimization_v05.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_physical_campaign_v09.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_physical_evidence_v09.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_physical_motion_v09.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_planning_fallback_v012.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_pose_math_v0125.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_preexecution_contract_v10.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_production_authority_v11.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_production_grade_coverage_v11.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_production_grade_v11.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_project_spine_v013.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_provider_and_qualification.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_provider_criterion_v15.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_qualification_cli_lifecycle_v06.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_qualification_harness_v06.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_readme_pypi.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_real_provider_adapters.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_reference_workcell_ros_frames_v0125.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_reference_workcell_v012.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_report_test_contract_coverage_v16.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_report_test_lineage_v16.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_report_test_visual_execution_v16.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_robot_platform_v08.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_ros2_production_receipts_v011.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_ros2_simulation.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_ros_trajectory_v09.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_selective_verification_v14.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_setup_profile.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_sim_real_qualification_v011.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_simulation_platform_v08.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_smooth_motion_hotfix_v162.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_support_contact_hotfix_v161.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_tool_collision_v011.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_tool_scene_v0124.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_trajectory_action_probe_v0125.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_trajectory_qualification_v09.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_trajectory_tracking_v0125.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_twin_materialization_v10.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_twin_v08.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_ur5e_adapter_scopes_v09.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_ur5e_v10_adapter_scopes.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_user_cli_interactive_v131.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_user_cli_progress_v131.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_user_cli_report_visual_v16.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_user_cli_selective_v14.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_user_cli_v15.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_user_cli_v15_hotfix_inheritance.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_v052_stabilization.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_v08_catalog_mapping_regression.py +0 -0
- {devagent_physical_engine-1.8.2 → devagent_physical_engine-1.8.5}/tests/test_workpiece_lifecycle_v011.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devagent-physical-engine
|
|
3
|
-
Version: 1.8.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 1.8.5
|
|
4
|
+
Summary: Verification-first robotics commissioning runtime with exact-Twin evidence, qualified UR5e Gazebo/MoveIt report execution, truthful robot support tiers, selective verification, replay, regression, and FAT reporting.
|
|
5
5
|
Author: Tom Ha
|
|
6
6
|
License: All Rights Reserved
|
|
7
7
|
Project-URL: Homepage, https://github.com/tomha85/devagent-physical-engine
|
|
@@ -76,7 +76,7 @@ regression + FAT report + Evidence Viewer
|
|
|
76
76
|
Python 3.11+ is required.
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
|
-
python -m pip install --upgrade devagent-physical-engine==1.8.
|
|
79
|
+
python -m pip install --upgrade devagent-physical-engine==1.8.5
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
Verify the installed package:
|
|
@@ -88,7 +88,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
|
|
|
88
88
|
Expected:
|
|
89
89
|
|
|
90
90
|
```text
|
|
91
|
-
1.8.
|
|
91
|
+
1.8.5
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
Run the normal customer workflow:
|
|
@@ -394,6 +394,38 @@ The v1.8.2 place receipt records the exact destination support id, workpiece id,
|
|
|
394
394
|
|
|
395
395
|
The release does **not** change real-execution authority, site qualification, target poses, conservative motion scales, or the rule that every motion group must preflight successfully before execution begins.
|
|
396
396
|
|
|
397
|
+
## v1.8.3 synchronous verified workpiece attach
|
|
398
|
+
|
|
399
|
+
A clean v1.8.2 target-stack run proved all five industrial preflight groups and actual `approach_pick` execution, then failed closed at GRASP with `workpiece_lifecycle_failed:apply_planning_scene_rejected`.
|
|
400
|
+
|
|
401
|
+
The attach request previously combined an `AttachedCollisionObject.ADD` with a redundant same-ID world `CollisionObject.REMOVE`. MoveIt applies attached-object state first, which already transitions the same-ID object out of the world. Processing the later redundant world REMOVE can therefore make synchronous `/apply_planning_scene` report failure even though the attachment transition was already attempted.
|
|
402
|
+
|
|
403
|
+
v1.8.3 makes the attach transition service-safe and deterministic: the request contains only the authoritative attached-object ADD. DevAgent then synchronously reads the PlanningScene back and requires all of the following before motion may continue:
|
|
404
|
+
|
|
405
|
+
```text
|
|
406
|
+
workpiece absent from world
|
|
407
|
+
exactly one attached object with the expected id
|
|
408
|
+
attached link == verified tool mount link
|
|
409
|
+
attached primitive geometry is valid
|
|
410
|
+
attachment pose/geometry hash matches the expected attachment hash
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Detach semantics remain explicit attached-object REMOVE plus world-object ADD at the verified placement pose. No collision rule, tool/workpiece geometry, TCP, touch link, target pose, motion speed, planner, site-qualification boundary, or real-execution authority is relaxed.
|
|
414
|
+
|
|
415
|
+
## v1.8.4 PyPI metadata compliance hotfix
|
|
416
|
+
|
|
417
|
+
v1.8.4 carries the exact v1.8.3 runtime semantics and shortens only the package Core Metadata `Summary` so it satisfies PyPI's 512-character limit. A regression test now parses `pyproject.toml` and rejects an empty or over-limit project description before release.
|
|
418
|
+
|
|
419
|
+
This metadata hotfix does not change the UR5e attach/detach lifecycle, collision policy, motion planning, Twin lineage, site-qualification boundary, or real-execution authority.
|
|
420
|
+
|
|
421
|
+
## v1.8.5 quaternion-invariant verified workpiece attach
|
|
422
|
+
|
|
423
|
+
A clean v1.8.4 UR5e target-stack run proved that synchronous `/apply_planning_scene` attachment now succeeds, world/attached state reaches strict read-back, and the remaining GRASP blocker is `workpiece_attachment_hash_mismatch`.
|
|
424
|
+
|
|
425
|
+
MoveIt round-trips attached-object rotations through Eigen. Unit quaternions `q` and `-q` represent the same physical rotation, but a raw component hash treats those two equivalent representations as different. v1.8.5 canonicalizes equivalent quaternion signs before workpiece attachment hashing using the same deterministic positive-`w` / first-nonzero-component rule already used by the qualified tool-scene path.
|
|
426
|
+
|
|
427
|
+
Verification remains strict for attachment identity, link, geometry contract, position, and physical rotation. This is not a tolerance-based PASS and does not change target geometry, TCP, collision policy, planner types, motion speeds, controller binding, Twin lineage, site qualification, or real-execution authority. If a hash mismatch remains, DevAgent records expected and observed hashes plus canonical expected/object/primitive/effective attachment poses for target diagnosis.
|
|
428
|
+
|
|
397
429
|
## Qualified visual-execution scope
|
|
398
430
|
|
|
399
431
|
Measured report-test execution remains intentionally narrow:
|
|
@@ -594,9 +626,9 @@ devagent-physical-ai optional provider-backed engineering front end
|
|
|
594
626
|
|
|
595
627
|
# Project status
|
|
596
628
|
|
|
597
|
-
**v1.8.
|
|
629
|
+
**v1.8.5 — Production/Stable software workflow**
|
|
598
630
|
|
|
599
|
-
v1.8.
|
|
631
|
+
v1.8.5 retains v1.8.4 PyPI metadata compliance, v1.8.3 synchronous service-safe workpiece attachment, v1.8.2 scoped destination-support place contact, v1.8.1 direct UR5e controller/action binding, truthful robot support tiers, and the ABB IRB1200 experimental visual runtime. It makes strict workpiece attachment verification invariant to the mathematically equivalent quaternion representations `q` and `-q` and persists exact pose/hash diagnostics for any remaining mismatch.
|
|
600
632
|
|
|
601
633
|
Production-oriented software capabilities include:
|
|
602
634
|
|
|
@@ -611,6 +643,8 @@ exact Requirement → Mapping → Verification Plan → Case provenance
|
|
|
611
643
|
truthful robot support tiers
|
|
612
644
|
qualified UR5e report-test visual execution contract
|
|
613
645
|
direct UR5e controller-manager/action readiness binding
|
|
646
|
+
synchronous verified workpiece attach/detach lifecycle
|
|
647
|
+
quaternion-invariant strict attachment hashing
|
|
614
648
|
scoped destination-support place contact
|
|
615
649
|
experimental exact ABB IRB1200 Gazebo/MoveIt/RViz preview
|
|
616
650
|
industrial Pilz PTP / LIN planning
|
|
@@ -35,7 +35,7 @@ regression + FAT report + Evidence Viewer
|
|
|
35
35
|
Python 3.11+ is required.
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
python -m pip install --upgrade devagent-physical-engine==1.8.
|
|
38
|
+
python -m pip install --upgrade devagent-physical-engine==1.8.5
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
Verify the installed package:
|
|
@@ -47,7 +47,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
|
|
|
47
47
|
Expected:
|
|
48
48
|
|
|
49
49
|
```text
|
|
50
|
-
1.8.
|
|
50
|
+
1.8.5
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
Run the normal customer workflow:
|
|
@@ -353,6 +353,38 @@ The v1.8.2 place receipt records the exact destination support id, workpiece id,
|
|
|
353
353
|
|
|
354
354
|
The release does **not** change real-execution authority, site qualification, target poses, conservative motion scales, or the rule that every motion group must preflight successfully before execution begins.
|
|
355
355
|
|
|
356
|
+
## v1.8.3 synchronous verified workpiece attach
|
|
357
|
+
|
|
358
|
+
A clean v1.8.2 target-stack run proved all five industrial preflight groups and actual `approach_pick` execution, then failed closed at GRASP with `workpiece_lifecycle_failed:apply_planning_scene_rejected`.
|
|
359
|
+
|
|
360
|
+
The attach request previously combined an `AttachedCollisionObject.ADD` with a redundant same-ID world `CollisionObject.REMOVE`. MoveIt applies attached-object state first, which already transitions the same-ID object out of the world. Processing the later redundant world REMOVE can therefore make synchronous `/apply_planning_scene` report failure even though the attachment transition was already attempted.
|
|
361
|
+
|
|
362
|
+
v1.8.3 makes the attach transition service-safe and deterministic: the request contains only the authoritative attached-object ADD. DevAgent then synchronously reads the PlanningScene back and requires all of the following before motion may continue:
|
|
363
|
+
|
|
364
|
+
```text
|
|
365
|
+
workpiece absent from world
|
|
366
|
+
exactly one attached object with the expected id
|
|
367
|
+
attached link == verified tool mount link
|
|
368
|
+
attached primitive geometry is valid
|
|
369
|
+
attachment pose/geometry hash matches the expected attachment hash
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Detach semantics remain explicit attached-object REMOVE plus world-object ADD at the verified placement pose. No collision rule, tool/workpiece geometry, TCP, touch link, target pose, motion speed, planner, site-qualification boundary, or real-execution authority is relaxed.
|
|
373
|
+
|
|
374
|
+
## v1.8.4 PyPI metadata compliance hotfix
|
|
375
|
+
|
|
376
|
+
v1.8.4 carries the exact v1.8.3 runtime semantics and shortens only the package Core Metadata `Summary` so it satisfies PyPI's 512-character limit. A regression test now parses `pyproject.toml` and rejects an empty or over-limit project description before release.
|
|
377
|
+
|
|
378
|
+
This metadata hotfix does not change the UR5e attach/detach lifecycle, collision policy, motion planning, Twin lineage, site-qualification boundary, or real-execution authority.
|
|
379
|
+
|
|
380
|
+
## v1.8.5 quaternion-invariant verified workpiece attach
|
|
381
|
+
|
|
382
|
+
A clean v1.8.4 UR5e target-stack run proved that synchronous `/apply_planning_scene` attachment now succeeds, world/attached state reaches strict read-back, and the remaining GRASP blocker is `workpiece_attachment_hash_mismatch`.
|
|
383
|
+
|
|
384
|
+
MoveIt round-trips attached-object rotations through Eigen. Unit quaternions `q` and `-q` represent the same physical rotation, but a raw component hash treats those two equivalent representations as different. v1.8.5 canonicalizes equivalent quaternion signs before workpiece attachment hashing using the same deterministic positive-`w` / first-nonzero-component rule already used by the qualified tool-scene path.
|
|
385
|
+
|
|
386
|
+
Verification remains strict for attachment identity, link, geometry contract, position, and physical rotation. This is not a tolerance-based PASS and does not change target geometry, TCP, collision policy, planner types, motion speeds, controller binding, Twin lineage, site qualification, or real-execution authority. If a hash mismatch remains, DevAgent records expected and observed hashes plus canonical expected/object/primitive/effective attachment poses for target diagnosis.
|
|
387
|
+
|
|
356
388
|
## Qualified visual-execution scope
|
|
357
389
|
|
|
358
390
|
Measured report-test execution remains intentionally narrow:
|
|
@@ -553,9 +585,9 @@ devagent-physical-ai optional provider-backed engineering front end
|
|
|
553
585
|
|
|
554
586
|
# Project status
|
|
555
587
|
|
|
556
|
-
**v1.8.
|
|
588
|
+
**v1.8.5 — Production/Stable software workflow**
|
|
557
589
|
|
|
558
|
-
v1.8.
|
|
590
|
+
v1.8.5 retains v1.8.4 PyPI metadata compliance, v1.8.3 synchronous service-safe workpiece attachment, v1.8.2 scoped destination-support place contact, v1.8.1 direct UR5e controller/action binding, truthful robot support tiers, and the ABB IRB1200 experimental visual runtime. It makes strict workpiece attachment verification invariant to the mathematically equivalent quaternion representations `q` and `-q` and persists exact pose/hash diagnostics for any remaining mismatch.
|
|
559
591
|
|
|
560
592
|
Production-oriented software capabilities include:
|
|
561
593
|
|
|
@@ -570,6 +602,8 @@ exact Requirement → Mapping → Verification Plan → Case provenance
|
|
|
570
602
|
truthful robot support tiers
|
|
571
603
|
qualified UR5e report-test visual execution contract
|
|
572
604
|
direct UR5e controller-manager/action readiness binding
|
|
605
|
+
synchronous verified workpiece attach/detach lifecycle
|
|
606
|
+
quaternion-invariant strict attachment hashing
|
|
573
607
|
scoped destination-support place contact
|
|
574
608
|
experimental exact ABB IRB1200 Gazebo/MoveIt/RViz preview
|
|
575
609
|
industrial Pilz PTP / LIN planning
|
|
@@ -623,4 +657,4 @@ Original creator: Tom Ha
|
|
|
623
657
|
Original project: https://github.com/tomha85/devagent-physical-engine
|
|
624
658
|
All rights reserved.
|
|
625
659
|
|
|
626
|
-
See repository `LICENSE`, `NOTICE`, and `COPYRIGHT` for complete ownership and usage terms.
|
|
660
|
+
See repository `LICENSE`, `NOTICE`, and `COPYRIGHT` for complete ownership and usage terms.
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "devagent-physical-engine"
|
|
7
|
-
version = "1.8.
|
|
8
|
-
description = "
|
|
7
|
+
version = "1.8.5"
|
|
8
|
+
description = "Verification-first robotics commissioning runtime with exact-Twin evidence, qualified UR5e Gazebo/MoveIt report execution, truthful robot support tiers, selective verification, replay, regression, and FAT reporting."
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
requires-python = ">=3.11"
|
|
11
11
|
dependencies = ["PyYAML>=6.0,<7"]
|
|
@@ -26,6 +26,24 @@ def _qnorm(q):
|
|
|
26
26
|
return tuple(float(value) / norm for value in q)
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
def _qcanonical(q):
|
|
30
|
+
"""Canonicalize equivalent q/-q rotations to one deterministic form."""
|
|
31
|
+
|
|
32
|
+
quaternion = _qnorm(q)
|
|
33
|
+
# A quaternion and its negation represent the same physical rotation. MoveIt
|
|
34
|
+
# round-trips poses through Eigen, which may legitimately return the opposite
|
|
35
|
+
# quaternion sign. Hash the rotation, not an arbitrary representation of it.
|
|
36
|
+
# Prefer positive w; for exact 180-degree rotations use the first non-zero xyz
|
|
37
|
+
# component as the deterministic sign discriminator.
|
|
38
|
+
for component in (quaternion[3], quaternion[0], quaternion[1], quaternion[2]):
|
|
39
|
+
if abs(component) <= 1e-15:
|
|
40
|
+
continue
|
|
41
|
+
if component < 0.0:
|
|
42
|
+
quaternion = tuple(-value for value in quaternion)
|
|
43
|
+
break
|
|
44
|
+
return tuple(_canon_float(value) for value in quaternion)
|
|
45
|
+
|
|
46
|
+
|
|
29
47
|
def _qmul(first, second):
|
|
30
48
|
ax, ay, az, aw = first
|
|
31
49
|
bx, by, bz, bw = second
|
|
@@ -60,10 +78,22 @@ def _compose(first_position, first_q, second_position, second_q):
|
|
|
60
78
|
def _pose_from_msg(pose):
|
|
61
79
|
return (
|
|
62
80
|
(float(pose.position.x), float(pose.position.y), float(pose.position.z)),
|
|
63
|
-
(
|
|
81
|
+
(
|
|
82
|
+
float(pose.orientation.x),
|
|
83
|
+
float(pose.orientation.y),
|
|
84
|
+
float(pose.orientation.z),
|
|
85
|
+
float(pose.orientation.w),
|
|
86
|
+
),
|
|
64
87
|
)
|
|
65
88
|
|
|
66
89
|
|
|
90
|
+
def _pose_payload(position, quaternion) -> dict[str, list[float]]:
|
|
91
|
+
return {
|
|
92
|
+
"position_m": [_canon_float(value) for value in position],
|
|
93
|
+
"quaternion_xyzw": list(_qcanonical(quaternion)),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
67
97
|
def _pose_to_msg(position, quaternion, Pose):
|
|
68
98
|
pose = Pose()
|
|
69
99
|
pose.position.x, pose.position.y, pose.position.z = (float(value) for value in position)
|
|
@@ -73,14 +103,19 @@ def _pose_to_msg(position, quaternion, Pose):
|
|
|
73
103
|
return pose
|
|
74
104
|
|
|
75
105
|
|
|
76
|
-
def _canonical_attachment(
|
|
106
|
+
def _canonical_attachment(
|
|
107
|
+
link_name: str,
|
|
108
|
+
item: dict[str, Any],
|
|
109
|
+
position,
|
|
110
|
+
quaternion,
|
|
111
|
+
) -> dict[str, Any]:
|
|
77
112
|
return {
|
|
78
113
|
"link_name": link_name,
|
|
79
114
|
"id": str(item["id"]),
|
|
80
115
|
"geometry_kind": str(item["geometry_kind"]),
|
|
81
116
|
"dimensions_m": [_canon_float(value) for value in item["dimensions_m"]],
|
|
82
117
|
"position_m": [_canon_float(value) for value in position],
|
|
83
|
-
"quaternion_xyzw":
|
|
118
|
+
"quaternion_xyzw": list(_qcanonical(quaternion)),
|
|
84
119
|
}
|
|
85
120
|
|
|
86
121
|
|
|
@@ -99,7 +134,17 @@ def _primitive(item, SolidPrimitive):
|
|
|
99
134
|
return primitive
|
|
100
135
|
|
|
101
136
|
|
|
102
|
-
def _collision_object(
|
|
137
|
+
def _collision_object(
|
|
138
|
+
item,
|
|
139
|
+
frame_id: str,
|
|
140
|
+
position,
|
|
141
|
+
quaternion,
|
|
142
|
+
*,
|
|
143
|
+
operation: int,
|
|
144
|
+
CollisionObject,
|
|
145
|
+
Pose,
|
|
146
|
+
SolidPrimitive,
|
|
147
|
+
):
|
|
103
148
|
collision = CollisionObject()
|
|
104
149
|
collision.header.frame_id = frame_id
|
|
105
150
|
collision.id = str(item["id"])
|
|
@@ -116,11 +161,19 @@ def _collision_object(item, frame_id: str, position, quaternion, *, operation: i
|
|
|
116
161
|
|
|
117
162
|
def _wait_future(node, future, timeout_s: float) -> bool:
|
|
118
163
|
import rclpy
|
|
164
|
+
|
|
119
165
|
rclpy.spin_until_future_complete(node, future, timeout_sec=timeout_s)
|
|
120
166
|
return future.done()
|
|
121
167
|
|
|
122
168
|
|
|
123
|
-
def _lookup_transform(
|
|
169
|
+
def _lookup_transform(
|
|
170
|
+
node,
|
|
171
|
+
buffer,
|
|
172
|
+
*,
|
|
173
|
+
target_frame: str,
|
|
174
|
+
source_frame: str,
|
|
175
|
+
timeout_s: float,
|
|
176
|
+
):
|
|
124
177
|
import rclpy
|
|
125
178
|
from rclpy.time import Time
|
|
126
179
|
|
|
@@ -148,9 +201,12 @@ def _read_state(get_client, node, timeout_s: float, workpiece_id: str):
|
|
|
148
201
|
response = future.result()
|
|
149
202
|
if response is None:
|
|
150
203
|
raise RuntimeError("get_planning_scene_empty")
|
|
151
|
-
world_present = any(
|
|
204
|
+
world_present = any(
|
|
205
|
+
item.id == workpiece_id for item in response.scene.world.collision_objects
|
|
206
|
+
)
|
|
152
207
|
attached = [
|
|
153
|
-
item
|
|
208
|
+
item
|
|
209
|
+
for item in response.scene.robot_state.attached_collision_objects
|
|
154
210
|
if item.object.id == workpiece_id
|
|
155
211
|
]
|
|
156
212
|
return world_present, attached
|
|
@@ -186,11 +242,14 @@ def transition(path: Path, *, operation: str, timeout_s: float) -> dict[str, Any
|
|
|
186
242
|
|
|
187
243
|
pose_data = item["pose"]
|
|
188
244
|
world_position = tuple(float(value) for value in pose_data["position_m"])
|
|
189
|
-
world_quaternion = tuple(
|
|
245
|
+
world_quaternion = tuple(
|
|
246
|
+
float(value) for value in pose_data["quaternion_xyzw"]
|
|
247
|
+
)
|
|
190
248
|
scene = PlanningScene()
|
|
191
249
|
scene.is_diff = True
|
|
192
250
|
scene.robot_state.is_diff = True
|
|
193
251
|
attachment_hash = None
|
|
252
|
+
expected_attachment_pose = None
|
|
194
253
|
|
|
195
254
|
if operation == "attach":
|
|
196
255
|
transform = _lookup_transform(
|
|
@@ -217,18 +276,14 @@ def transition(path: Path, *, operation: str, timeout_s: float) -> dict[str, Any
|
|
|
217
276
|
world_position,
|
|
218
277
|
world_quaternion,
|
|
219
278
|
)
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
Pose=Pose,
|
|
229
|
-
SolidPrimitive=SolidPrimitive,
|
|
230
|
-
)
|
|
231
|
-
)
|
|
279
|
+
|
|
280
|
+
# MoveIt applies robot_state.attached_collision_objects before processing
|
|
281
|
+
# world.collision_objects in a PlanningScene diff. Adding the attached body
|
|
282
|
+
# automatically removes an existing same-ID world object. Sending a second
|
|
283
|
+
# explicit world REMOVE therefore makes synchronous ApplyPlanningScene
|
|
284
|
+
# report failure because that later REMOVE targets an object that no longer
|
|
285
|
+
# exists. Keep ATTACH as one authoritative attached-object ADD and verify the
|
|
286
|
+
# resulting world/attached state by synchronous read-back below.
|
|
232
287
|
attached = AttachedCollisionObject()
|
|
233
288
|
attached.link_name = tool_link
|
|
234
289
|
attached.touch_links = touch_links
|
|
@@ -244,9 +299,16 @@ def transition(path: Path, *, operation: str, timeout_s: float) -> dict[str, Any
|
|
|
244
299
|
)
|
|
245
300
|
scene.robot_state.attached_collision_objects.append(attached)
|
|
246
301
|
expected_attachment = _canonical_attachment(
|
|
247
|
-
tool_link,
|
|
302
|
+
tool_link,
|
|
303
|
+
item,
|
|
304
|
+
relative_position,
|
|
305
|
+
relative_quaternion,
|
|
248
306
|
)
|
|
249
307
|
attachment_hash = _hash(expected_attachment)
|
|
308
|
+
expected_attachment_pose = _pose_payload(
|
|
309
|
+
relative_position,
|
|
310
|
+
relative_quaternion,
|
|
311
|
+
)
|
|
250
312
|
elif operation == "detach":
|
|
251
313
|
attached = AttachedCollisionObject()
|
|
252
314
|
attached.link_name = tool_link
|
|
@@ -278,12 +340,21 @@ def transition(path: Path, *, operation: str, timeout_s: float) -> dict[str, Any
|
|
|
278
340
|
return {"success": False, "code": "apply_planning_scene_rejected"}
|
|
279
341
|
|
|
280
342
|
world_present, attached_items = _read_state(
|
|
281
|
-
get_client,
|
|
343
|
+
get_client,
|
|
344
|
+
node,
|
|
345
|
+
timeout_s,
|
|
346
|
+
str(item["id"]),
|
|
347
|
+
)
|
|
348
|
+
observed_attached_link = (
|
|
349
|
+
attached_items[0].link_name if len(attached_items) == 1 else None
|
|
282
350
|
)
|
|
283
|
-
observed_attached_link = attached_items[0].link_name if len(attached_items) == 1 else None
|
|
284
351
|
|
|
285
352
|
if operation == "attach":
|
|
286
|
-
if
|
|
353
|
+
if (
|
|
354
|
+
world_present
|
|
355
|
+
or len(attached_items) != 1
|
|
356
|
+
or observed_attached_link != tool_link
|
|
357
|
+
):
|
|
287
358
|
return {
|
|
288
359
|
"success": False,
|
|
289
360
|
"code": "workpiece_attach_readback_mismatch",
|
|
@@ -291,15 +362,28 @@ def transition(path: Path, *, operation: str, timeout_s: float) -> dict[str, Any
|
|
|
291
362
|
"observed_attached_link": observed_attached_link,
|
|
292
363
|
}
|
|
293
364
|
observed_object = attached_items[0].object
|
|
294
|
-
if
|
|
365
|
+
if (
|
|
366
|
+
len(observed_object.primitives) != 1
|
|
367
|
+
or len(observed_object.primitive_poses) != 1
|
|
368
|
+
):
|
|
295
369
|
return {"success": False, "code": "workpiece_attached_shape_invalid"}
|
|
296
370
|
object_position, object_q = _pose_from_msg(observed_object.pose)
|
|
297
|
-
primitive_position, primitive_q = _pose_from_msg(
|
|
371
|
+
primitive_position, primitive_q = _pose_from_msg(
|
|
372
|
+
observed_object.primitive_poses[0]
|
|
373
|
+
)
|
|
298
374
|
observed_position, observed_q = _compose(
|
|
299
|
-
object_position,
|
|
375
|
+
object_position,
|
|
376
|
+
object_q,
|
|
377
|
+
primitive_position,
|
|
378
|
+
primitive_q,
|
|
300
379
|
)
|
|
301
380
|
observed_attachment_hash = _hash(
|
|
302
|
-
_canonical_attachment(
|
|
381
|
+
_canonical_attachment(
|
|
382
|
+
tool_link,
|
|
383
|
+
item,
|
|
384
|
+
observed_position,
|
|
385
|
+
observed_q,
|
|
386
|
+
)
|
|
303
387
|
)
|
|
304
388
|
if observed_attachment_hash != attachment_hash:
|
|
305
389
|
return {
|
|
@@ -307,6 +391,18 @@ def transition(path: Path, *, operation: str, timeout_s: float) -> dict[str, Any
|
|
|
307
391
|
"code": "workpiece_attachment_hash_mismatch",
|
|
308
392
|
"observed_world_present": world_present,
|
|
309
393
|
"observed_attached_link": observed_attached_link,
|
|
394
|
+
"expected_attachment_hash": attachment_hash,
|
|
395
|
+
"observed_attachment_hash": observed_attachment_hash,
|
|
396
|
+
"expected_attachment_pose": expected_attachment_pose,
|
|
397
|
+
"observed_object_pose": _pose_payload(object_position, object_q),
|
|
398
|
+
"observed_primitive_pose": _pose_payload(
|
|
399
|
+
primitive_position,
|
|
400
|
+
primitive_q,
|
|
401
|
+
),
|
|
402
|
+
"observed_attachment_pose": _pose_payload(
|
|
403
|
+
observed_position,
|
|
404
|
+
observed_q,
|
|
405
|
+
),
|
|
310
406
|
}
|
|
311
407
|
return {
|
|
312
408
|
"success": True,
|
|
@@ -316,16 +412,23 @@ def transition(path: Path, *, operation: str, timeout_s: float) -> dict[str, Any
|
|
|
316
412
|
"observed_world_present": False,
|
|
317
413
|
"observed_attached_link": tool_link,
|
|
318
414
|
"attachment_hash": attachment_hash,
|
|
415
|
+
"attachment_pose": expected_attachment_pose,
|
|
319
416
|
}
|
|
320
417
|
|
|
321
418
|
success = world_present and not attached_items
|
|
322
419
|
return {
|
|
323
420
|
"success": success,
|
|
324
|
-
"code":
|
|
421
|
+
"code": (
|
|
422
|
+
"workpiece_detach_verified"
|
|
423
|
+
if success
|
|
424
|
+
else "workpiece_detach_readback_mismatch"
|
|
425
|
+
),
|
|
325
426
|
"materialization_hash": materialization_hash,
|
|
326
427
|
"twin_hash": twin_hash,
|
|
327
428
|
"observed_world_present": world_present,
|
|
328
|
-
"observed_attached_link":
|
|
429
|
+
"observed_attached_link": (
|
|
430
|
+
None if not attached_items else observed_attached_link
|
|
431
|
+
),
|
|
329
432
|
}
|
|
330
433
|
finally:
|
|
331
434
|
del listener
|
|
@@ -346,7 +449,10 @@ def main() -> int:
|
|
|
346
449
|
timeout_s=float(args.timeout),
|
|
347
450
|
)
|
|
348
451
|
except Exception as exc:
|
|
349
|
-
result = {
|
|
452
|
+
result = {
|
|
453
|
+
"success": False,
|
|
454
|
+
"code": f"workpiece_scene_probe_error:{type(exc).__name__}",
|
|
455
|
+
}
|
|
350
456
|
print(json.dumps(result, sort_keys=True))
|
|
351
457
|
return 0 if result.get("success") else 2
|
|
352
458
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devagent-physical-engine
|
|
3
|
-
Version: 1.8.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 1.8.5
|
|
4
|
+
Summary: Verification-first robotics commissioning runtime with exact-Twin evidence, qualified UR5e Gazebo/MoveIt report execution, truthful robot support tiers, selective verification, replay, regression, and FAT reporting.
|
|
5
5
|
Author: Tom Ha
|
|
6
6
|
License: All Rights Reserved
|
|
7
7
|
Project-URL: Homepage, https://github.com/tomha85/devagent-physical-engine
|
|
@@ -76,7 +76,7 @@ regression + FAT report + Evidence Viewer
|
|
|
76
76
|
Python 3.11+ is required.
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
|
-
python -m pip install --upgrade devagent-physical-engine==1.8.
|
|
79
|
+
python -m pip install --upgrade devagent-physical-engine==1.8.5
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
Verify the installed package:
|
|
@@ -88,7 +88,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
|
|
|
88
88
|
Expected:
|
|
89
89
|
|
|
90
90
|
```text
|
|
91
|
-
1.8.
|
|
91
|
+
1.8.5
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
Run the normal customer workflow:
|
|
@@ -394,6 +394,38 @@ The v1.8.2 place receipt records the exact destination support id, workpiece id,
|
|
|
394
394
|
|
|
395
395
|
The release does **not** change real-execution authority, site qualification, target poses, conservative motion scales, or the rule that every motion group must preflight successfully before execution begins.
|
|
396
396
|
|
|
397
|
+
## v1.8.3 synchronous verified workpiece attach
|
|
398
|
+
|
|
399
|
+
A clean v1.8.2 target-stack run proved all five industrial preflight groups and actual `approach_pick` execution, then failed closed at GRASP with `workpiece_lifecycle_failed:apply_planning_scene_rejected`.
|
|
400
|
+
|
|
401
|
+
The attach request previously combined an `AttachedCollisionObject.ADD` with a redundant same-ID world `CollisionObject.REMOVE`. MoveIt applies attached-object state first, which already transitions the same-ID object out of the world. Processing the later redundant world REMOVE can therefore make synchronous `/apply_planning_scene` report failure even though the attachment transition was already attempted.
|
|
402
|
+
|
|
403
|
+
v1.8.3 makes the attach transition service-safe and deterministic: the request contains only the authoritative attached-object ADD. DevAgent then synchronously reads the PlanningScene back and requires all of the following before motion may continue:
|
|
404
|
+
|
|
405
|
+
```text
|
|
406
|
+
workpiece absent from world
|
|
407
|
+
exactly one attached object with the expected id
|
|
408
|
+
attached link == verified tool mount link
|
|
409
|
+
attached primitive geometry is valid
|
|
410
|
+
attachment pose/geometry hash matches the expected attachment hash
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Detach semantics remain explicit attached-object REMOVE plus world-object ADD at the verified placement pose. No collision rule, tool/workpiece geometry, TCP, touch link, target pose, motion speed, planner, site-qualification boundary, or real-execution authority is relaxed.
|
|
414
|
+
|
|
415
|
+
## v1.8.4 PyPI metadata compliance hotfix
|
|
416
|
+
|
|
417
|
+
v1.8.4 carries the exact v1.8.3 runtime semantics and shortens only the package Core Metadata `Summary` so it satisfies PyPI's 512-character limit. A regression test now parses `pyproject.toml` and rejects an empty or over-limit project description before release.
|
|
418
|
+
|
|
419
|
+
This metadata hotfix does not change the UR5e attach/detach lifecycle, collision policy, motion planning, Twin lineage, site-qualification boundary, or real-execution authority.
|
|
420
|
+
|
|
421
|
+
## v1.8.5 quaternion-invariant verified workpiece attach
|
|
422
|
+
|
|
423
|
+
A clean v1.8.4 UR5e target-stack run proved that synchronous `/apply_planning_scene` attachment now succeeds, world/attached state reaches strict read-back, and the remaining GRASP blocker is `workpiece_attachment_hash_mismatch`.
|
|
424
|
+
|
|
425
|
+
MoveIt round-trips attached-object rotations through Eigen. Unit quaternions `q` and `-q` represent the same physical rotation, but a raw component hash treats those two equivalent representations as different. v1.8.5 canonicalizes equivalent quaternion signs before workpiece attachment hashing using the same deterministic positive-`w` / first-nonzero-component rule already used by the qualified tool-scene path.
|
|
426
|
+
|
|
427
|
+
Verification remains strict for attachment identity, link, geometry contract, position, and physical rotation. This is not a tolerance-based PASS and does not change target geometry, TCP, collision policy, planner types, motion speeds, controller binding, Twin lineage, site qualification, or real-execution authority. If a hash mismatch remains, DevAgent records expected and observed hashes plus canonical expected/object/primitive/effective attachment poses for target diagnosis.
|
|
428
|
+
|
|
397
429
|
## Qualified visual-execution scope
|
|
398
430
|
|
|
399
431
|
Measured report-test execution remains intentionally narrow:
|
|
@@ -594,9 +626,9 @@ devagent-physical-ai optional provider-backed engineering front end
|
|
|
594
626
|
|
|
595
627
|
# Project status
|
|
596
628
|
|
|
597
|
-
**v1.8.
|
|
629
|
+
**v1.8.5 — Production/Stable software workflow**
|
|
598
630
|
|
|
599
|
-
v1.8.
|
|
631
|
+
v1.8.5 retains v1.8.4 PyPI metadata compliance, v1.8.3 synchronous service-safe workpiece attachment, v1.8.2 scoped destination-support place contact, v1.8.1 direct UR5e controller/action binding, truthful robot support tiers, and the ABB IRB1200 experimental visual runtime. It makes strict workpiece attachment verification invariant to the mathematically equivalent quaternion representations `q` and `-q` and persists exact pose/hash diagnostics for any remaining mismatch.
|
|
600
632
|
|
|
601
633
|
Production-oriented software capabilities include:
|
|
602
634
|
|
|
@@ -611,6 +643,8 @@ exact Requirement → Mapping → Verification Plan → Case provenance
|
|
|
611
643
|
truthful robot support tiers
|
|
612
644
|
qualified UR5e report-test visual execution contract
|
|
613
645
|
direct UR5e controller-manager/action readiness binding
|
|
646
|
+
synchronous verified workpiece attach/detach lifecycle
|
|
647
|
+
quaternion-invariant strict attachment hashing
|
|
614
648
|
scoped destination-support place contact
|
|
615
649
|
experimental exact ABB IRB1200 Gazebo/MoveIt/RViz preview
|
|
616
650
|
industrial Pilz PTP / LIN planning
|
|
@@ -196,6 +196,7 @@ tests/test_one_command_regression_v141.py
|
|
|
196
196
|
tests/test_one_command_v13.py
|
|
197
197
|
tests/test_openai_strict_schema_v0113.py
|
|
198
198
|
tests/test_optimization_v05.py
|
|
199
|
+
tests/test_package_metadata_v184.py
|
|
199
200
|
tests/test_physical_campaign_v09.py
|
|
200
201
|
tests/test_physical_evidence_v09.py
|
|
201
202
|
tests/test_physical_motion_v09.py
|
|
@@ -245,4 +246,6 @@ tests/test_user_cli_v15.py
|
|
|
245
246
|
tests/test_user_cli_v15_hotfix_inheritance.py
|
|
246
247
|
tests/test_v052_stabilization.py
|
|
247
248
|
tests/test_v08_catalog_mapping_regression.py
|
|
248
|
-
tests/
|
|
249
|
+
tests/test_workpiece_attach_semantics_v183.py
|
|
250
|
+
tests/test_workpiece_lifecycle_v011.py
|
|
251
|
+
tests/test_workpiece_scene_probe_v185.py
|
|
@@ -34,8 +34,8 @@ from devagent_physical_engine.ros2.report_test_visualization_v170 import (
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
class IndustrialMotionV170Tests(unittest.TestCase):
|
|
37
|
-
def
|
|
38
|
-
self.assertEqual(package.__version__, "1.8.
|
|
37
|
+
def test_release_version_is_v185(self) -> None:
|
|
38
|
+
self.assertEqual(package.__version__, "1.8.5")
|
|
39
39
|
|
|
40
40
|
def test_reference_groups_cover_every_task_phase_once_in_order(self) -> None:
|
|
41
41
|
groups = reference_industrial_groups()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import tomllib
|
|
5
|
+
import unittest
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PackageMetadataV184Tests(unittest.TestCase):
|
|
9
|
+
def test_pypi_summary_respects_core_metadata_limit(self) -> None:
|
|
10
|
+
root = Path(__file__).resolve().parents[1]
|
|
11
|
+
metadata = tomllib.loads((root / "pyproject.toml").read_text(encoding="utf-8"))
|
|
12
|
+
summary = str(metadata["project"]["description"])
|
|
13
|
+
self.assertTrue(summary.strip())
|
|
14
|
+
self.assertLessEqual(len(summary), 512)
|
|
15
|
+
|
|
16
|
+
def test_package_version_is_v185(self) -> None:
|
|
17
|
+
root = Path(__file__).resolve().parents[1]
|
|
18
|
+
metadata = tomllib.loads((root / "pyproject.toml").read_text(encoding="utf-8"))
|
|
19
|
+
self.assertEqual(metadata["project"]["version"], "1.8.5")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if __name__ == "__main__":
|
|
23
|
+
unittest.main()
|
|
@@ -153,9 +153,11 @@ class TransferPlaceDiagnosticV172Tests(unittest.TestCase):
|
|
|
153
153
|
self.assertTrue(payload["plan_only"])
|
|
154
154
|
self.assertEqual(payload["result_code"], "pilz_place_segment_planning_failed")
|
|
155
155
|
|
|
156
|
-
def
|
|
157
|
-
self.assertEqual(package.__version__, "1.8.
|
|
158
|
-
self.assertTrue(
|
|
156
|
+
def test_v185_release_preserves_v172_diagnostics_and_v182_planner(self) -> None:
|
|
157
|
+
self.assertEqual(package.__version__, "1.8.5")
|
|
158
|
+
self.assertTrue(
|
|
159
|
+
issubclass(PilzIndustrialSequencePlannerV182, PilzIndustrialSequencePlannerV172)
|
|
160
|
+
)
|
|
159
161
|
self.assertIs(
|
|
160
162
|
visual_v170.PilzIndustrialSequencePlannerV170,
|
|
161
163
|
PilzIndustrialSequencePlannerV182,
|