diff --git a/RELEASING.md b/RELEASING.md deleted file mode 100644 index 37c52701f..000000000 --- a/RELEASING.md +++ /dev/null @@ -1,541 +0,0 @@ -# SMACC2 Release Process - -This document details the process for creating a new SMACC2 release for ROS2 apt packages. The workflow involves Claude Code generating commands in a Docker container, while the human developer executes them on the host system due to GitHub authentication requirements. - -## Workflow Overview - -**Division of Labor:** -- **Claude Code (Docker)**: Analyzes code, prepares files, generates commands, creates documentation -- **Human Developer (Host)**: Executes git commands, handles GitHub authentication, runs bloom-release, creates PRs - -**Why This Split?** -- Docker container lacks GitHub credentials for push/PR operations -- Host system has configured git identity and GitHub access tokens -- Bloom requires rosdep and GitHub API access from host environment - -## Prerequisites (Host System) - -### Required Tools - -```bash -# Install bloom via pip (apt version may be outdated/unavailable) -pip3 install --user bloom - -# Add to PATH (add to ~/.bashrc for persistence) -export PATH="$HOME/.local/bin:$PATH" - -# Verify installation -which bloom-release # Should show ~/.local/bin/bloom-release -``` - -### Git Configuration - -```bash -# Configure git identity (if not already set) -git config user.email "your-email@example.com" -git config user.name "Your Name" - -# Verify GitHub authentication -ssh -T git@github.com # OR -gh auth status # If using GitHub CLI -``` - -### Required Forks - -1. Fork `ros/rosdistro` to your GitHub account -2. Ensure write access to `robosoft-ai/SMACC2` (maintainers only) -3. Ensure write access to `robosoft-ai/SMACC2-release` (maintainers only) - -## Release Phases - -### Phase 1: Pre-Release Verification (Claude in Docker) - -Claude will: -1. Verify the bug fix or feature exists in source code -2. Review commit history since last release -3. Determine appropriate version number (major.minor.patch) -4. Analyze changes to categorize (fixes, features, breaking changes) - -**Example:** -```bash -# Claude runs these internally: -git log 2.3.19..HEAD --oneline -git diff 2.3.19..HEAD -- "*.hpp" "*.cpp" -``` - -### Phase 2: Version & Documentation Updates (Claude in Docker) - -Claude will: -1. Update all package.xml files (42+ packages) to new version -2. Generate comprehensive CHANGELOG.rst entry -3. Prepare commit message - -**Human verifies and reviews changes before committing** - -### Phase 3: Commit, Tag, and Push (Human on Host) - -**Commands generated by Claude, executed by human:** - -```bash -# Navigate to SMACC2 repository -cd /path/to/SMACC2 - -# Stage all version changes -git add -A - -# Commit (Claude provides the commit message) -git commit -m "Prepare release X.Y.Z - -[Claude-generated detailed commit message] - -🤖 Generated with Claude Code -Co-Authored-By: Claude " - -# Create annotated release tag -git tag -a X.Y.Z -m "Release X.Y.Z - [Primary fix/feature]" - -# Verify tag includes critical commits -git log X.Y.Z --oneline | grep "critical-commit-hash" - -# Push to feature branch first (for PR workflow) -git push origin your-branch-name -git push origin X.Y.Z - -# Create PR to jazzy branch on GitHub -# Review and merge PR -``` - -**Important:** After PR is merged, ensure the tag X.Y.Z is on the jazzy branch. You may need to re-create the tag after merge if it was on a feature branch. - -### Phase 4: Bloom Release Process (Human on Host) - -**Fix Common Issues First:** - -```bash -# Fix rosdep configuration (if needed) -# Check for broken rosdep sources -rosdep update - -# If you see errors about missing local files: -sudo mv /etc/ros/rosdep/sources.list.d/10-debian.list \ - /etc/ros/rosdep/sources.list.d/10-debian.list.disabled - -# Verify rosdep works -rosdep update # Should complete without fatal errors -``` - -**Run Bloom Release:** - -```bash -# Clone or navigate to release repository -cd /tmp -git clone https://github.com/robosoft-ai/SMACC2-release.git -cd SMACC2-release - -# CRITICAL: Update tracks.yaml if needed -# If bloom previously failed or used wrong version: -sed -i 's/last_version: OLD_VERSION/last_version: X.Y.Z/g' tracks.yaml -git add tracks.yaml -git commit -m "Update tracks.yaml to version X.Y.Z" - -# Run bloom release -bloom-release smacc2 --rosdistro jazzy --track jazzy --unsafe - -# When prompted about missing dependencies: -# - Type 'y' if dependency is optional (e.g., demo packages) -# - Type 'n' if dependency is critical - -# When prompted about creating fork/PR: -# - Type 'y' to attempt automatic PR creation -# - If it fails (403 error), you'll create PR manually -``` - -**Expected Output:** -``` -Releasing package 'smacc2' for 'jazzy' to: 'release/jazzy/smacc2' -[... many package releases ...] -==> git-bloom-generate -y rosdebian --prefix release/jazzy jazzy -i 1 -[... debian branch generation ...] - -Open a pull request from 'username/rosdistro:bloom-smacc2-0' into 'ros/rosdistro:master'? -Continue [Y/n]? y -``` - -**If Automatic PR Fails:** - -Bloom creates the commit locally but can't push due to authentication. The commit is in a temporary directory that gets cleaned up. You'll need to manually create the rosdistro PR. - -### Phase 5: Manual rosdistro PR Creation (Human on Host) - -**If bloom's automatic PR failed:** - -```bash -# Clone your rosdistro fork -cd /tmp -git clone https://github.com/YOUR_USERNAME/rosdistro.git -cd rosdistro - -# Create release branch from latest upstream -git remote add upstream https://github.com/ros/rosdistro.git -git fetch upstream -git checkout -b smacc2-X.Y.Z-release upstream/master - -# Find the smacc2 entry -grep -n "smacc2:" jazzy/distribution.yaml -# Output: 10934: smacc2: - -# Update the version (Claude will provide the sed command) -sed -i 's/version: OLD_VERSION-REV/version: X.Y.Z-REV/g' jazzy/distribution.yaml - -# Verify the change -sed -n 'LINE_NUMBER,LINE_NUMBER+15p' jazzy/distribution.yaml | grep version - -# Commit and push -git add jazzy/distribution.yaml -git commit -m "smacc2: X.Y.Z-REV in 'jazzy/distribution.yaml' [bloom]" -git push origin smacc2-X.Y.Z-release -``` - -**Create PR on GitHub:** -- Go to your fork: `https://github.com/YOUR_USERNAME/rosdistro` -- Click "Compare & pull request" -- **Base:** `ros/rosdistro:master` -- **Title:** `smacc2: X.Y.Z-REV in 'jazzy/distribution.yaml' [bloom]` -- **Description:** - ```markdown - Increasing version of package(s) in repository `smacc2` to `X.Y.Z-REV`: - - - upstream repository: https://github.com/robosoft-ai/SMACC2.git - - release repository: https://github.com/robosoft-ai/SMACC2-release.git - - distro file: `jazzy/distribution.yaml` - - bloom version: `0.13.0` - - previous version for package: `OLD_VERSION-REV` - ``` - -### Phase 6: Documentation & Communication (Claude + Human) - -**Claude generates, human publishes:** - -**1. GitHub Release Notes** -- Go to: `https://github.com/robosoft-ai/SMACC2/releases/new` -- Select tag: `X.Y.Z` -- Copy title and description from Claude's prepared notes -- Publish release - -**2. Issue Update (if release fixes an issue)** -- Post Claude-generated comment on relevant issue -- Include installation instructions for both apt and source users -- Note expected timeline for apt availability (24-48 hours) - -**3. rosdistro PR Link** -- Update issue/release notes with rosdistro PR link once created - -### Phase 7: Monitor & Verify (Human on Host) - -**Timeline:** -- **Day 0:** Release created, rosdistro PR submitted -- **Day 1-2:** ROS maintainers review and merge rosdistro PR -- **Day 2-3:** Buildfarm compiles packages -- **Day 3-4:** Packages sync to apt.ros.org - -**Monitoring Commands:** - -```bash -# Check rosdistro PR status -# Visit: https://github.com/ros/rosdistro/pulls - -# Check buildfarm status (after PR merge) -# Visit: https://build.ros2.org/job/Hbin_uJ64__smacc2__ubuntu_jammy_amd64__binary/ - -# Check apt package availability -apt-cache policy ros-jazzy-smacc2 -# Should eventually show: Version: X.Y.Z-REVjammy... - -# Verify on clean system -docker run -it ros:jazzy-ros-base bash -apt update -apt install ros-jazzy-smacc2 -apt show ros-jazzy-smacc2 | grep Version -``` - -**Final Steps:** -- Update issue with confirmation of apt availability -- Close related issues -- Announce release in appropriate channels - -## Common Issues & Solutions - -### Issue 1: Bloom Uses Wrong Version - -**Symptom:** -``` -Releasing package 'smacc2' for 'jazzy' to: 'release/jazzy/smacc2' -ros-jazzy-smacc2 (2.3.18-1jammy) jammy; urgency=high # <-- OLD VERSION! -``` - -**Solution:** -```bash -cd /tmp/SMACC2-release -# Manually update tracks.yaml -sed -i 's/last_version: OLD_VERSION/last_version: X.Y.Z/g' tracks.yaml -git add tracks.yaml -git commit -m "Update tracks.yaml to version X.Y.Z" -# Re-run bloom-release -bloom-release smacc2 --rosdistro jazzy --track jazzy --unsafe -``` - -### Issue 2: rosdep Update Fails - -**Symptom:** -``` -ERROR: unable to process source [file:///usr/share/python3-rosdep2/debian.yaml]: -Failed to update rosdep, did you run 'rosdep init' first? -``` - -**Solution:** -```bash -# Disable broken local rosdep source -sudo mv /etc/ros/rosdep/sources.list.d/10-debian.list \ - /etc/ros/rosdep/sources.list.d/10-debian.list.disabled - -# Verify fix -rosdep update -# Should show warnings but complete successfully -``` - -### Issue 3: Missing Dependency in Bloom - -**Symptom:** -``` -Could not resolve rosdep key 'some_package' -Failed to resolve some_package on ubuntu:jammy -``` - -**Solution:** -- If dependency is for optional/demo packages: Answer **'y'** to continue -- If dependency is critical: Fix the dependency issue before proceeding -- Most SMACC2 demo state machines have optional dependencies that can be skipped - -### Issue 4: Tag Not on Correct Branch - -**Symptom:** -Tag was created on feature branch, then PR was merged to jazzy, but tag isn't on jazzy branch. - -**Solution:** -```bash -# After PR is merged to jazzy -git checkout jazzy -git pull origin jazzy - -# Re-create tag on jazzy branch -git tag -d X.Y.Z # Delete local tag -git push origin :refs/tags/X.Y.Z # Delete remote tag -git tag -a X.Y.Z -m "Release X.Y.Z - [description]" -git push origin X.Y.Z - -# Verify tag is on jazzy -git branch --contains X.Y.Z -# Should show: jazzy -``` - -### Issue 5: GitHub Authentication Fails - -**Symptom:** -``` -fatal: could not read Username for 'https://github.com': No such device or address -``` - -**Solution:** -Ensure you're on the host system (not Docker) with configured GitHub credentials: -```bash -# Use SSH URLs (recommended) -git remote set-url origin git@github.com:robosoft-ai/SMACC2.git - -# OR use GitHub CLI -gh auth login - -# OR use personal access token -# Create token at: https://github.com/settings/tokens -git config --global credential.helper store -git push # Will prompt for username and token -``` - -## Version Numbering Guidelines - -**Semantic Versioning (MAJOR.MINOR.PATCH):** - -- **PATCH (X.Y.Z → X.Y.Z+1):** Bug fixes, no API changes - - Example: Fixing double onExit() calls - - Most common for maintenance releases - -- **MINOR (X.Y.Z → X.Y+1.0):** New features, backward compatible - - Example: New client library (cl_moveit2z) - - Component additions - - Non-breaking API extensions - -- **MAJOR (X.Y.Z → X+1.0.0):** Breaking changes - - Example: Namespace restructuring that breaks user code - - Signature changes to public APIs - - Removed deprecated features - -**Debian Revision (-REV):** -- Increments with each bloom release for same upstream version -- Usually `-1` for first release, `-2` if you need to re-release -- Example: `2.3.20-1`, `2.3.20-2` - -## Release Checklist - -**Before Starting:** -- [ ] Verify you have maintainer access to SMACC2 repositories -- [ ] Fork `ros/rosdistro` to your GitHub account -- [ ] Install bloom on host: `pip3 install --user bloom` -- [ ] Configure git identity on host -- [ ] Test GitHub authentication - -**Release Steps:** -- [ ] Claude verifies fix/feature in code -- [ ] Claude reviews commits and determines version -- [ ] Claude updates package.xml files (42 packages) -- [ ] Claude generates CHANGELOG entry -- [ ] Human commits and pushes changes -- [ ] Human creates and merges PR to jazzy branch -- [ ] Human creates and pushes release tag -- [ ] Human fixes rosdep issues (if any) -- [ ] Human runs bloom-release -- [ ] Human creates rosdistro PR (manual if bloom fails) -- [ ] Human creates GitHub release with Claude's notes -- [ ] Human posts issue updates -- [ ] Human monitors rosdistro PR merge (1-2 days) -- [ ] Human monitors buildfarm (1-2 days after merge) -- [ ] Human verifies apt package availability -- [ ] Human closes related issues - -**Time Estimates:** -- Active work: 2-4 hours (spread across Claude + Human) -- Total calendar time: 3-5 days (waiting for buildfarm) - -## Reference Files - -**Version Locations:** -- All package.xml files: `find . -name package.xml | xargs grep ""` -- Main package: `smacc2/package.xml` -- Messages: `smacc2_msgs/package.xml` - -**Documentation:** -- Main CHANGELOG: `smacc2/CHANGELOG.rst` -- Release tracks: `https://github.com/robosoft-ai/SMACC2-release/blob/master/tracks.yaml` -- rosdistro entry: `https://github.com/ros/rosdistro/blob/master/jazzy/distribution.yaml` - -**Monitoring:** -- Buildfarm: `https://build.ros2.org/` -- Apt packages: `http://packages.ros.org/ros2/ubuntu/pool/main/r/ros-jazzy-smacc2/` -- rosdistro PRs: `https://github.com/ros/rosdistro/pulls` - -## Example: Release 2.3.20 Process - -This section documents the actual release process for version 2.3.20, which fixed the critical double onExit() bug (#556). - -### Initial Analysis - -```bash -# Claude verified the fix -git log --oneline | grep "double finishing" -# Output: 1fabc680 remove double finishing (#558) - -# Reviewed commits since 2.3.19 -git log 2.3.19..HEAD --oneline -# Found 54 commits including the fix and major refactoring - -# Decision: 2.3.20 (patch release for critical bug fix) -``` - -### Version Updates - -```bash -# Claude updated all 42 package.xml files -find . -name "package.xml" -exec sed -i 's/2\.3\.19<\/version>/2.3.20<\/version>/g' {} \; - -# Verified -find . -name "package.xml" -exec grep -H "" {} \; | grep -v "2.3.20" | wc -l -# Output: 0 (all updated) -``` - -### Commit and Tag - -```bash -# Configured git on host -git config user.email "brett@robosoft.ai" -git config user.name "brettpac" - -# Committed changes -git add -A -git commit -m "Prepare release 2.3.20..." - -# Created tag -git tag -a 2.3.20 -m "Release 2.3.20 - Fix double onExit() calls (#556)" - -# Pushed (after PR merge to jazzy) -git push origin jazzy -git push origin 2.3.20 -``` - -### Bloom Release - -```bash -# Fixed rosdep issue -sudo mv /etc/ros/rosdep/sources.list.d/10-debian.list \ - /etc/ros/rosdep/sources.list.d/10-debian.list.disabled - -# Updated tracks.yaml (bloom initially used old version) -cd /tmp/SMACC2-release -sed -i 's/last_version: 2\.3\.18/last_version: 2.3.20/g' tracks.yaml -git add tracks.yaml -git commit -m "Update tracks.yaml to version 2.3.20" - -# Ran bloom -bloom-release smacc2 --rosdistro jazzy --track jazzy --unsafe -# Answered 'y' to missing ros_publisher_client dependency (optional demo package) -# Automatic PR failed with 403 error -``` - -### Manual rosdistro PR - -```bash -# Cloned fork -cd /tmp -git clone https://github.com/brettpac/rosdistro.git -cd rosdistro -git remote add upstream https://github.com/ros/rosdistro.git -git fetch upstream -git checkout -b smacc2-2.3.20-release upstream/master - -# Updated version -grep -n "smacc2:" jazzy/distribution.yaml -# Output: 10934: smacc2: -sed -i 's/version: 2\.3\.18-1/version: 2.3.20-2/g' jazzy/distribution.yaml - -# Committed and pushed -git add jazzy/distribution.yaml -git commit -m "smacc2: 2.3.20-2 in 'jazzy/distribution.yaml' [bloom]" -git push origin smacc2-2.3.20-release - -# Created PR on GitHub -# PR link: [to be filled after creation] -``` - -### Outcome - -- ✅ Version 2.3.20 released with double onExit() fix -- ✅ All 42 packages version-locked at 2.3.20 -- ✅ Comprehensive CHANGELOG entry created -- ✅ Debian release branches created with 2.3.20-2 -- ✅ rosdistro PR submitted -- ⏳ Awaiting buildfarm (24-48 hours) - -## References - -- [Bloom Documentation](http://wiki.ros.org/bloom) -- [ROS2 Release Process](https://docs.ros.org/en/rolling/How-To-Guides/Releasing/First-Time-Release.html) -- [rosdistro Repository](https://github.com/ros/rosdistro) -- [Semantic Versioning](https://semver.org/) -- [ROS2 Buildfarm](https://build.ros2.org/) diff --git a/smacc2/include/smacc2/client_behaviors/cb_call_service.hpp b/smacc2/include/smacc2/client_behaviors/cb_call_service.hpp index 532c6f78e..8d9274be6 100644 --- a/smacc2/include/smacc2/client_behaviors/cb_call_service.hpp +++ b/smacc2/include/smacc2/client_behaviors/cb_call_service.hpp @@ -86,14 +86,13 @@ class CbServiceCall : public smacc2::SmaccAsyncClientBehavior std::shared_future> resultFuture_; - typename std::shared_ptr result_; - std::chrono::milliseconds pollRate_; - protected: //rclcpp::NodeHandle nh_; std::shared_ptr> client_; std::string serviceName_; std::shared_ptr request_; + typename std::shared_ptr result_; + std::chrono::milliseconds pollRate_; virtual void onServiceResponse(std::shared_ptr /*result*/) { diff --git a/smacc2/package.xml b/smacc2/package.xml index ac45b94b2..21b7b6707 100644 --- a/smacc2/package.xml +++ b/smacc2/package.xml @@ -8,8 +8,7 @@ Pablo Inigo Blasco Brett Aldrich - Pablo Inigo Blasco - Denis Stogl + Brett Aldrich Apache-2.0 ament_cmake diff --git a/smacc2_client_library/cl_nav2z/src/cl_nav2z/client_behaviors/cb_position_control_free_space.cpp b/smacc2_client_library/cl_nav2z/src/cl_nav2z/client_behaviors/cb_position_control_free_space.cpp index 28a81832e..64aa9de5a 100644 --- a/smacc2_client_library/cl_nav2z/src/cl_nav2z/client_behaviors/cb_position_control_free_space.cpp +++ b/smacc2_client_library/cl_nav2z/src/cl_nav2z/client_behaviors/cb_position_control_free_space.cpp @@ -50,8 +50,6 @@ void CbPositionControlFreeSpace::onEntry() geometry_msgs::msg::Pose currentPose = pose->toPoseMsg(); rclcpp::Rate loop_rate(10); - double countAngle = 0; - auto prevyaw = tf2::getYaw(currentPose.orientation); // PID controller gains (proportional, integral, and derivative) double kp_linear = 0.5; diff --git a/smacc2_client_library/cl_nav2z/src/cl_nav2z/client_behaviors/cb_spiral_motion.cpp b/smacc2_client_library/cl_nav2z/src/cl_nav2z/client_behaviors/cb_spiral_motion.cpp index bdff2ade7..4358cc93f 100644 --- a/smacc2_client_library/cl_nav2z/src/cl_nav2z/client_behaviors/cb_spiral_motion.cpp +++ b/smacc2_client_library/cl_nav2z/src/cl_nav2z/client_behaviors/cb_spiral_motion.cpp @@ -99,7 +99,6 @@ void CbSpiralMotion::onEntry() cmd_vel.linear.x = maxLinearVelocity; } - float signVal = (cmd_vel.angular.z >= 0.0f) ? 1.0f : -1.0f; // cmd_vel.angular.z -= signVal * angularAcceleration * dt; float ellapsedTimeFactor = current_time.seconds() / spiralMotionDuration.seconds(); diff --git a/smacc2_client_library/cl_nav2z/src/cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator.cpp b/smacc2_client_library/cl_nav2z/src/cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator.cpp index 770fc1928..e2a86869c 100644 --- a/smacc2_client_library/cl_nav2z/src/cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator.cpp +++ b/smacc2_client_library/cl_nav2z/src/cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator.cpp @@ -478,7 +478,7 @@ void CpWaypointNavigatorBase::loadWayPointsFromFile(std::string filepath) if (wp_node != NULL) { - for (int64_t i = 0; i < wp_node->size(); ++i) + for (std::size_t i = 0; i < wp_node->size(); ++i) { // Parse waypoint entries on YAML geometry_msgs::msg::Pose wp; @@ -551,7 +551,7 @@ void CpWaypointNavigatorBase::loadWayPointsFromFile2(std::string filepath) if (wp_node != NULL) { - for (int64_t i = 0; i < wp_node->size(); ++i) + for (std::size_t i = 0; i < wp_node->size(); ++i) { // Parse waypoint entries on YAML geometry_msgs::msg::Pose wp; diff --git a/smacc2_dev_tools/sm_reference_lib_run_commands.md b/smacc2_dev_tools/sm_reference_lib_run_commands.md index 8e0101640..6360f61e4 100644 --- a/smacc2_dev_tools/sm_reference_lib_run_commands.md +++ b/smacc2_dev_tools/sm_reference_lib_run_commands.md @@ -1,5 +1,21 @@ ``` -ros2 launch sm_cl_ros2_timer_unit_test_1 sm_cl_ros2_timer_unit_test_1.py +ros2 launch sm_advanced_recovery_1 sm_advanced_recovery_1.py +``` + +``` +ros2 launch sm_atomic sm_atomic.py +``` + +``` +ros2 launch sm_atomic_lifecycle sm_atomic_lifecycle.py +``` + +``` +ros2 launch sm_atomic_mode_states sm_atomic_mode_states.py +``` + +``` +ros2 launch sm_branching sm_branching.py ``` ``` @@ -7,17 +23,33 @@ ros2 launch sm_cl_keyboard_unit_test_1 sm_cl_keyboard_unit_test_1.py ``` ``` -ros2 launch sm_panda_cl_moveit2z_cb_inventory sm_panda_cl_moveit2z_cb_inventory.launch.py +ros2 launch sm_cl_ros2_timer_unit_test_1 sm_cl_ros2_timer_unit_test_1.py ``` ``` -ros2 launch sm_multi_stage_1 sm_multi_stage_1.launch +ros2 launch sm_multi_stage_1 sm_multi_stage_1.py ``` ``` -ros2 launch sm_atomic_mode_states sm_atomic_mode_states.py +ros2 launch sm_multithread_test_1 sm_multithread_test_1.py ``` ``` -ros2 launch sm_atomic_lifecycle sm_atomic_lifecycle.py +ros2 launch sm_multithread_test_1 sm_multithread_test_1_single.py +``` + +``` +ros2 launch sm_pack_ml sm_pack_ml.py +``` + +``` +ros2 launch sm_panda_cl_moveit2z_cb_inventory sm_panda_cl_moveit2z_cb_inventory.py +``` + +``` +ros2 launch sm_simple_action_client sm_simple_action_client.py +``` + +``` +ros2 launch sm_three_some sm_three_some.py ``` diff --git a/smacc2_sm_reference_library/sm_advanced_recovery_1/README.md b/smacc2_sm_reference_library/sm_advanced_recovery_1/README.md index b88fa7541..0d7854aa9 100644 --- a/smacc2_sm_reference_library/sm_advanced_recovery_1/README.md +++ b/smacc2_sm_reference_library/sm_advanced_recovery_1/README.md @@ -32,7 +32,7 @@ source install/setup.bash And then run the launch file... ``` -ros2 launch sm_advanced_recovery_1 sm_advanced_recovery_1.launch +ros2 launch sm_advanced_recovery_1 sm_advanced_recovery_1.py ```

Viewer Instructions

diff --git a/smacc2_sm_reference_library/sm_advanced_recovery_1/launch/sm_advanced_recovery_1.launch b/smacc2_sm_reference_library/sm_advanced_recovery_1/launch/sm_advanced_recovery_1.launch deleted file mode 100644 index 0296f5208..000000000 --- a/smacc2_sm_reference_library/sm_advanced_recovery_1/launch/sm_advanced_recovery_1.launch +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/smacc2_sm_reference_library/sm_advanced_recovery_1/launch/sm_advanced_recovery_1.py b/smacc2_sm_reference_library/sm_advanced_recovery_1/launch/sm_advanced_recovery_1.py index 213058c2f..41a9fc821 100644 --- a/smacc2_sm_reference_library/sm_advanced_recovery_1/launch/sm_advanced_recovery_1.py +++ b/smacc2_sm_reference_library/sm_advanced_recovery_1/launch/sm_advanced_recovery_1.py @@ -59,17 +59,17 @@ def generate_launch_description(): # Construct logging prefix for state machine node if log_dir: - state_machine_log = os.path.join(log_dir, f"sm_advanced_recovery_1_node_{timestamp}.log") - state_machine_prefix = f"konsole --hold -p tabtitle='SM Advanced Recovery 1' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {state_machine_log}; exec bash' -- " + state_machine_log = os.path.join(log_dir, f"state_machine_{timestamp}.log") + state_machine_prefix = f"konsole --hold -p tabtitle='SM Advanced Recovery' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {state_machine_log}; exec bash' -- " else: - state_machine_prefix = "konsole --hold -p tabtitle='SM Advanced Recovery 1' -e" + state_machine_prefix = "konsole --hold -p tabtitle='SM Advanced Recovery' -e" - # Construct logging prefix for keyboard client node + # Construct logging prefix for keyboard server node if log_dir: - keyboard_log = os.path.join(log_dir, f"keyboard_server_node_{timestamp}.log") - keyboard_prefix = f"konsole --hold -p tabtitle='Keyboard Client' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {keyboard_log}; exec bash' -- " + keyboard_log = os.path.join(log_dir, f"keyboard_server_{timestamp}.log") + keyboard_prefix = f"konsole --hold -p tabtitle='Keyboard Server' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {keyboard_log}; exec bash' -- " else: - keyboard_prefix = "konsole --hold -p tabtitle='Keyboard Client' -e" + keyboard_prefix = "konsole --hold -p tabtitle='Keyboard Server' -e" return LaunchDescription( [ @@ -79,6 +79,7 @@ def generate_launch_description(): name="sm_advanced_recovery_1", output="screen", prefix=state_machine_prefix, + arguments=["--ros-args", "--log-level", "DEBUG"], ), Node( package="cl_keyboard", @@ -86,6 +87,7 @@ def generate_launch_description(): name="keyboard_server_node", output="screen", prefix=keyboard_prefix, + arguments=["--ros-args", "--log-level", "INFO"], ), - ] + ], ) diff --git a/smacc2_sm_reference_library/sm_atomic/config/sm_atomic_test.yaml b/smacc2_sm_reference_library/sm_atomic/config/sm_atomic_test.yaml deleted file mode 100644 index 1a8b170a7..000000000 --- a/smacc2_sm_reference_library/sm_atomic/config/sm_atomic_test.yaml +++ /dev/null @@ -1,7 +0,0 @@ -state_machine_rosparam_ws: /SmAtomic -success_switch: - - type: state_reached - state_name: "sm_atomic::State2" -failure_switch: - - type: timeout - duration: 10.0 # sec diff --git a/smacc2_sm_reference_library/sm_atomic/launch/sm_atomic.launch b/smacc2_sm_reference_library/sm_atomic/launch/sm_atomic.launch deleted file mode 100644 index e4e8e51cb..000000000 --- a/smacc2_sm_reference_library/sm_atomic/launch/sm_atomic.launch +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/smacc2_sm_reference_library/sm_atomic_http/config/sm_atomic_http_test.yaml b/smacc2_sm_reference_library/sm_atomic_http/config/sm_atomic_http_test.yaml deleted file mode 100644 index 2a81cc1f0..000000000 --- a/smacc2_sm_reference_library/sm_atomic_http/config/sm_atomic_http_test.yaml +++ /dev/null @@ -1,7 +0,0 @@ -state_machine_rosparam_ws: /SmAtomicHttp -success_switch: - - type: state_reached - state_name: "sm_atomic_http::State2" -failure_switch: - - type: timeout - duration: 10.0 # sec diff --git a/smacc2_sm_reference_library/sm_atomic_http/launch/sm_atomic_http.launch b/smacc2_sm_reference_library/sm_atomic_http/launch/sm_atomic_http.launch deleted file mode 100644 index 217a24cb3..000000000 --- a/smacc2_sm_reference_library/sm_atomic_http/launch/sm_atomic_http.launch +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/smacc2_sm_reference_library/sm_atomic_lifecycle/launch/sm_atomic_lifecycle.py b/smacc2_sm_reference_library/sm_atomic_lifecycle/launch/sm_atomic_lifecycle.py index 3a28e6d70..f553c2371 100755 --- a/smacc2_sm_reference_library/sm_atomic_lifecycle/launch/sm_atomic_lifecycle.py +++ b/smacc2_sm_reference_library/sm_atomic_lifecycle/launch/sm_atomic_lifecycle.py @@ -67,9 +67,9 @@ def generate_launch_description(): # Construct logging prefix for lifecycle example node if log_dir: lifecycle_log = os.path.join(log_dir, f"lifecycle_example_node_{timestamp}.log") - lifecycle_prefix = f"konsole --hold -p tabtitle='Lifecycle Example' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {lifecycle_log}; exec bash' -- " + lifecycle_prefix = f"konsole --hold -p tabtitle='Lifecycle Example Node' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {lifecycle_log}; exec bash' -- " else: - lifecycle_prefix = "konsole --hold -p tabtitle='Lifecycle Example' -e" + lifecycle_prefix = "konsole --hold -p tabtitle='Lifecycle Example Node' -e" return LaunchDescription( [ diff --git a/smacc2_sm_reference_library/sm_atomic_mode_states/config/sm_atomic_config.yaml b/smacc2_sm_reference_library/sm_atomic_mode_states/config/sm_atomic_mode_states_config.yaml similarity index 100% rename from smacc2_sm_reference_library/sm_atomic_mode_states/config/sm_atomic_config.yaml rename to smacc2_sm_reference_library/sm_atomic_mode_states/config/sm_atomic_mode_states_config.yaml diff --git a/smacc2_sm_reference_library/sm_atomic_mode_states/config/sm_atomic_test.yaml b/smacc2_sm_reference_library/sm_atomic_mode_states/config/sm_atomic_test.yaml deleted file mode 100644 index 65c2cd957..000000000 --- a/smacc2_sm_reference_library/sm_atomic_mode_states/config/sm_atomic_test.yaml +++ /dev/null @@ -1,7 +0,0 @@ -state_machine_rosparam_ws: /SmAtomicModeStates -success_switch: - - type: state_reached - state_name: "sm_atomic_mode_states::State2" -failure_switch: - - type: timeout - duration: 10.0 # sec diff --git a/smacc2_sm_reference_library/sm_branching/README.md b/smacc2_sm_reference_library/sm_branching/README.md index cd2fc74cf..93ebf74ac 100644 --- a/smacc2_sm_reference_library/sm_branching/README.md +++ b/smacc2_sm_reference_library/sm_branching/README.md @@ -30,10 +30,9 @@ source install/setup.bash ``` And then run the launch file... -! refactor state machine name ``` -ros2 launch sm_branching sm_branching.launch +ros2 launch sm_branching sm_branching.py ```

Viewer Instructions

diff --git a/smacc2_sm_reference_library/sm_branching/config/sm_branching_test.yaml b/smacc2_sm_reference_library/sm_branching/config/sm_branching_test.yaml deleted file mode 100644 index 1a8b170a7..000000000 --- a/smacc2_sm_reference_library/sm_branching/config/sm_branching_test.yaml +++ /dev/null @@ -1,7 +0,0 @@ -state_machine_rosparam_ws: /SmAtomic -success_switch: - - type: state_reached - state_name: "sm_atomic::State2" -failure_switch: - - type: timeout - duration: 10.0 # sec diff --git a/smacc2_sm_reference_library/sm_branching/launch/sm_branching.launch b/smacc2_sm_reference_library/sm_branching/launch/sm_branching.launch deleted file mode 100644 index f25ec2e92..000000000 --- a/smacc2_sm_reference_library/sm_branching/launch/sm_branching.launch +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/smacc2_sm_reference_library/sm_branching/launch/sm_branching.py b/smacc2_sm_reference_library/sm_branching/launch/sm_branching.py new file mode 100644 index 000000000..8ea1d48ca --- /dev/null +++ b/smacc2_sm_reference_library/sm_branching/launch/sm_branching.py @@ -0,0 +1,81 @@ +# Copyright 2021 RobosoftAI Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +from datetime import datetime +from launch import LaunchDescription +from launch_ros.actions import Node +from ament_index_python.packages import get_package_share_directory + + +def setup_log_directory(): + """ + Creates timestamped log directory with error handling. + Returns: (log_dir_path, timestamp) tuple + """ + timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S") + + # Primary log directory location + log_dir = os.path.join(os.path.expanduser("~"), ".ros", "log", f"{timestamp}-sm_branching") + + try: + os.makedirs(log_dir, mode=0o755, exist_ok=True) + print(f"[Launch] Log directory created: {log_dir}") + return log_dir, timestamp + except PermissionError as e: + # Fallback to /tmp if ~/.ros is not writable + fallback_dir = os.path.join("/tmp", "sm_branching_logs", timestamp) + print(f"[Launch] WARNING: Cannot create log directory at {log_dir}") + print(f"[Launch] Permission denied: {e}") + print(f"[Launch] Using fallback directory: {fallback_dir}") + try: + os.makedirs(fallback_dir, mode=0o755, exist_ok=True) + return fallback_dir, timestamp + except Exception as fallback_error: + print(f"[Launch] ERROR: Cannot create fallback directory: {fallback_error}") + print(f"[Launch] Logs will only be displayed in konsole terminals") + return None, timestamp + except OSError as e: + print(f"[Launch] ERROR: Failed to create log directory: {e}") + print(f"[Launch] Logs will only be displayed in konsole terminals") + return None, timestamp + + +def generate_launch_description(): + # Setup logging directory + log_dir, timestamp = setup_log_directory() + + # Get package share directory for config file + package_share_dir = get_package_share_directory("sm_branching") + config_file = os.path.join(package_share_dir, "config", "sm_branching_config.yaml") + + # Construct logging prefix for state machine node + if log_dir: + state_machine_log = os.path.join(log_dir, f"state_machine_{timestamp}.log") + state_machine_prefix = f"konsole --hold -p tabtitle='SM Branching' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {state_machine_log}; exec bash' -- " + else: + state_machine_prefix = "konsole --hold -p tabtitle='SM Branching' -e" + + return LaunchDescription( + [ + Node( + package="sm_branching", + executable="sm_branching_node", + name="sm_branching", + output="screen", + prefix=state_machine_prefix, + parameters=[config_file], + ), + ], + ) diff --git a/smacc2_sm_reference_library/sm_cl_keyboard_unit_test_1/launch/sm_cl_keyboard_unit_test_1.py b/smacc2_sm_reference_library/sm_cl_keyboard_unit_test_1/launch/sm_cl_keyboard_unit_test_1.py index 88d189c0b..e481a514d 100644 --- a/smacc2_sm_reference_library/sm_cl_keyboard_unit_test_1/launch/sm_cl_keyboard_unit_test_1.py +++ b/smacc2_sm_reference_library/sm_cl_keyboard_unit_test_1/launch/sm_cl_keyboard_unit_test_1.py @@ -27,9 +27,9 @@ def generate_launch_description(): Node( package="cl_keyboard", executable="keyboard_server_node.py", - name="cl_keyboard", + name="keyboard_server_node", output="screen", - prefix="xterm -hold -e", + prefix="konsole --hold -p tabtitle='Keyboard Server' -e", arguments=["--ros-args", "--log-level", "INFO"], ), ] diff --git a/smacc2_sm_reference_library/sm_cl_keyboard_unit_test_1/package.xml b/smacc2_sm_reference_library/sm_cl_keyboard_unit_test_1/package.xml index 07b538769..252079dc7 100644 --- a/smacc2_sm_reference_library/sm_cl_keyboard_unit_test_1/package.xml +++ b/smacc2_sm_reference_library/sm_cl_keyboard_unit_test_1/package.xml @@ -4,7 +4,7 @@ sm_cl_keyboard_unit_test_1 3.0.1 The sm_cl_keyboard_unit_test_1 package - Pablo Inigo Blasco + Brett Aldrich Apache-2.0 ament_cmake @@ -13,7 +13,7 @@ cl_keyboard smacc2 - xterm + konsole ament_cmake diff --git a/smacc2_sm_reference_library/sm_cl_ros2_timer_unit_test_1/package.xml b/smacc2_sm_reference_library/sm_cl_ros2_timer_unit_test_1/package.xml index c25177a6c..c00f74e56 100644 --- a/smacc2_sm_reference_library/sm_cl_ros2_timer_unit_test_1/package.xml +++ b/smacc2_sm_reference_library/sm_cl_ros2_timer_unit_test_1/package.xml @@ -4,7 +4,7 @@ sm_cl_ros2_timer_unit_test_1 3.0.1 The sm_cl_ros2_timer_unit_test_1 package - Pablo Inigo Blasco + Brett Aldrich Apache-2.0 ament_cmake @@ -12,8 +12,6 @@ cl_ros2_timer smacc2 - xterm - ament_cmake diff --git a/smacc2_sm_reference_library/sm_multi_stage_1/README.md b/smacc2_sm_reference_library/sm_multi_stage_1/README.md index 4ae66d289..9f81527fe 100644 --- a/smacc2_sm_reference_library/sm_multi_stage_1/README.md +++ b/smacc2_sm_reference_library/sm_multi_stage_1/README.md @@ -32,7 +32,7 @@ source install/setup.bash And then run the launch file... ``` -ros2 launch sm_multi_stage_1 sm_multi_stage_1.launch +ros2 launch sm_multi_stage_1 sm_multi_stage_1.py ```

Viewer Instructions

diff --git a/smacc2_sm_reference_library/sm_multi_stage_1/launch/sm_multi_stage_1.launch b/smacc2_sm_reference_library/sm_multi_stage_1/launch/sm_multi_stage_1.launch deleted file mode 100644 index 81afe4c6d..000000000 --- a/smacc2_sm_reference_library/sm_multi_stage_1/launch/sm_multi_stage_1.launch +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/smacc2_sm_reference_library/sm_multi_stage_1/launch/sm_multi_stage_1.py b/smacc2_sm_reference_library/sm_multi_stage_1/launch/sm_multi_stage_1.py index f35d88619..b5d886fe5 100644 --- a/smacc2_sm_reference_library/sm_multi_stage_1/launch/sm_multi_stage_1.py +++ b/smacc2_sm_reference_library/sm_multi_stage_1/launch/sm_multi_stage_1.py @@ -15,6 +15,7 @@ import os from datetime import datetime from launch import LaunchDescription +from launch.actions import OpaqueFunction from launch_ros.actions import Node @@ -26,7 +27,7 @@ def setup_log_directory(): timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S") # Primary log directory location - log_dir = os.path.join(os.path.expanduser("~"), ".ros", "log", f"{timestamp}-sm_multi_stage_1") + log_dir = os.path.join(os.path.expanduser("~"), ".ros", "log", timestamp) try: os.makedirs(log_dir, mode=0o755, exist_ok=True) @@ -52,38 +53,49 @@ def setup_log_directory(): def generate_launch_description(): + return LaunchDescription([OpaqueFunction(function=launch_setup)]) + + +def launch_setup(context, *args, **kwargs): + # Setup logging directory log_dir, timestamp = setup_log_directory() # Construct logging prefix for state machine node if log_dir: - state_machine_log = os.path.join(log_dir, f"sm_multi_stage_1_node_{timestamp}.log") - state_machine_prefix = f"konsole --hold -p tabtitle='SM Multi Stage 1' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {state_machine_log}; exec bash' -- " + state_machine_log = os.path.join(log_dir, f"state_machine_{timestamp}.log") + state_machine_prefix = f'konsole --hold -p tabtitle="State Machine" -e bash -c \'RCUTILS_COLORIZED_OUTPUT=1 "$@" 2>&1 | tee {state_machine_log}; exec bash\' -- ' else: - state_machine_prefix = "konsole --hold -p tabtitle='SM Multi Stage 1' -e" + state_machine_prefix = 'konsole --hold -p tabtitle="State Machine" -e' + + sm_multi_stage_1_node = Node( + package="sm_multi_stage_1", + executable="sm_multi_stage_1_node", + name="sm_multi_stage_1", + output="screen", + prefix=state_machine_prefix, + arguments=["--ros-args", "--log-level", "DEBUG"], + ) # Construct logging prefix for keyboard client node if log_dir: - keyboard_log = os.path.join(log_dir, f"keyboard_server_node_{timestamp}.log") - keyboard_prefix = f"konsole --hold -p tabtitle='Keyboard Client' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {keyboard_log}; exec bash' -- " + keyboard_log = os.path.join(log_dir, f"cl_keyboard_{timestamp}.log") + keyboard_prefix = f'konsole --hold -p tabtitle="Keyboard Server" -e bash -c \'RCUTILS_COLORIZED_OUTPUT=1 "$@" 2>&1 | tee {keyboard_log}; exec bash\' -- ' else: - keyboard_prefix = "konsole --hold -p tabtitle='Keyboard Client' -e" - - return LaunchDescription( - [ - Node( - package="sm_multi_stage_1", - executable="sm_multi_stage_1_node", - name="sm_multi_stage_1", - output="screen", - prefix=state_machine_prefix, - ), - Node( - package="cl_keyboard", - executable="keyboard_server_node.py", - name="keyboard_server_node", - output="screen", - prefix=keyboard_prefix, - ), - ] + keyboard_prefix = 'konsole --hold -p tabtitle="Keyboard Server" -e' + + keyboard_server_node = Node( + package="cl_keyboard", + executable="keyboard_server_node.py", + name="keyboard_server_node", + output="screen", + prefix=keyboard_prefix, + arguments=["--ros-args", "--log-level", "INFO"], ) + + nodes_to_start = [ + sm_multi_stage_1_node, + keyboard_server_node, + ] + + return nodes_to_start diff --git a/smacc2_sm_reference_library/sm_multithread_test_1/README.md b/smacc2_sm_reference_library/sm_multithread_test_1/README.md index f016d891a..6dd1e5a83 100644 --- a/smacc2_sm_reference_library/sm_multithread_test_1/README.md +++ b/smacc2_sm_reference_library/sm_multithread_test_1/README.md @@ -46,14 +46,14 @@ colcon build --packages-select sm_multithread_test_1 source install/setup.bash # Launch multi-threaded version -ros2 launch sm_multithread_test_1 sm_multithread_test_1.launch.py +ros2 launch sm_multithread_test_1 sm_multithread_test_1.py ``` ### Run Single-threaded Version (For Comparison) ```bash # Launch single-threaded version -ros2 launch sm_multithread_test_1 sm_multithread_test_1_single.launch.py +ros2 launch sm_multithread_test_1 sm_multithread_test_1_single.py ``` The state machine runs for **15 seconds** then enters a terminal state. Press `Ctrl+C` to exit. @@ -366,10 +366,10 @@ source install/setup.bash ```bash # Multi-threaded version (main demonstration) -ros2 launch sm_multithread_test_1 sm_multithread_test_1.launch.py +ros2 launch sm_multithread_test_1 sm_multithread_test_1.py # Single-threaded version (for comparison) -ros2 launch sm_multithread_test_1 sm_multithread_test_1_single.launch.py +ros2 launch sm_multithread_test_1 sm_multithread_test_1_single.py ``` --- diff --git a/smacc2_sm_reference_library/sm_multithread_test_1/launch/sm_multithread_test_1.launch.py b/smacc2_sm_reference_library/sm_multithread_test_1/launch/sm_multithread_test_1.py similarity index 100% rename from smacc2_sm_reference_library/sm_multithread_test_1/launch/sm_multithread_test_1.launch.py rename to smacc2_sm_reference_library/sm_multithread_test_1/launch/sm_multithread_test_1.py diff --git a/smacc2_sm_reference_library/sm_multithread_test_1/launch/sm_multithread_test_1_single.launch.py b/smacc2_sm_reference_library/sm_multithread_test_1/launch/sm_multithread_test_1_single.py similarity index 100% rename from smacc2_sm_reference_library/sm_multithread_test_1/launch/sm_multithread_test_1_single.launch.py rename to smacc2_sm_reference_library/sm_multithread_test_1/launch/sm_multithread_test_1_single.py diff --git a/smacc2_sm_reference_library/sm_pack_ml/README.md b/smacc2_sm_reference_library/sm_pack_ml/README.md index c077c0317..e5525b190 100644 --- a/smacc2_sm_reference_library/sm_pack_ml/README.md +++ b/smacc2_sm_reference_library/sm_pack_ml/README.md @@ -32,7 +32,7 @@ source install/setup.bash And then run the launch file... ``` -ros2 launch sm_pack_ml sm_pack_ml.launch +ros2 launch sm_pack_ml sm_pack_ml.py ```

Viewer Instructions

diff --git a/smacc2_sm_reference_library/sm_pack_ml/launch/sm_pack_ml.launch b/smacc2_sm_reference_library/sm_pack_ml/launch/sm_pack_ml.launch deleted file mode 100644 index 44f73c8f0..000000000 --- a/smacc2_sm_reference_library/sm_pack_ml/launch/sm_pack_ml.launch +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/smacc2_sm_reference_library/sm_multi_stage_1/launch/sm_multi_stage_1.launch.py b/smacc2_sm_reference_library/sm_pack_ml/launch/sm_pack_ml.py similarity index 60% rename from smacc2_sm_reference_library/sm_multi_stage_1/launch/sm_multi_stage_1.launch.py rename to smacc2_sm_reference_library/sm_pack_ml/launch/sm_pack_ml.py index b5d886fe5..09560b176 100644 --- a/smacc2_sm_reference_library/sm_multi_stage_1/launch/sm_multi_stage_1.launch.py +++ b/smacc2_sm_reference_library/sm_pack_ml/launch/sm_pack_ml.py @@ -15,7 +15,6 @@ import os from datetime import datetime from launch import LaunchDescription -from launch.actions import OpaqueFunction from launch_ros.actions import Node @@ -27,7 +26,7 @@ def setup_log_directory(): timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S") # Primary log directory location - log_dir = os.path.join(os.path.expanduser("~"), ".ros", "log", timestamp) + log_dir = os.path.join(os.path.expanduser("~"), ".ros", "log", f"{timestamp}-sm_pack_ml") try: os.makedirs(log_dir, mode=0o755, exist_ok=True) @@ -35,7 +34,7 @@ def setup_log_directory(): return log_dir, timestamp except PermissionError as e: # Fallback to /tmp if ~/.ros is not writable - fallback_dir = os.path.join("/tmp", "sm_multi_stage_1_logs", timestamp) + fallback_dir = os.path.join("/tmp", "sm_pack_ml_logs", timestamp) print(f"[Launch] WARNING: Cannot create log directory at {log_dir}") print(f"[Launch] Permission denied: {e}") print(f"[Launch] Using fallback directory: {fallback_dir}") @@ -53,49 +52,38 @@ def setup_log_directory(): def generate_launch_description(): - return LaunchDescription([OpaqueFunction(function=launch_setup)]) - - -def launch_setup(context, *args, **kwargs): - # Setup logging directory log_dir, timestamp = setup_log_directory() # Construct logging prefix for state machine node if log_dir: state_machine_log = os.path.join(log_dir, f"state_machine_{timestamp}.log") - state_machine_prefix = f'konsole --hold -p tabtitle="State Machine" -e bash -c \'RCUTILS_COLORIZED_OUTPUT=1 "$@" 2>&1 | tee {state_machine_log}; exec bash\' -- ' + state_machine_prefix = f"konsole --hold -p tabtitle='SM Pack ML' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {state_machine_log}; exec bash' -- " else: - state_machine_prefix = 'konsole --hold -p tabtitle="State Machine" -e' - - sm_multi_stage_1_node = Node( - package="sm_multi_stage_1", - executable="sm_multi_stage_1_node", - name="sm_multi_stage_1", - output="screen", - prefix=state_machine_prefix, - arguments=["--ros-args", "--log-level", "DEBUG"], - ) + state_machine_prefix = "konsole --hold -p tabtitle='SM Pack ML' -e" - # Construct logging prefix for keyboard client node + # Construct logging prefix for keyboard server node if log_dir: - keyboard_log = os.path.join(log_dir, f"cl_keyboard_{timestamp}.log") - keyboard_prefix = f'konsole --hold -p tabtitle="Keyboard Server" -e bash -c \'RCUTILS_COLORIZED_OUTPUT=1 "$@" 2>&1 | tee {keyboard_log}; exec bash\' -- ' + keyboard_log = os.path.join(log_dir, f"keyboard_server_{timestamp}.log") + keyboard_prefix = f"konsole --hold -p tabtitle='Keyboard Server' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {keyboard_log}; exec bash' -- " else: - keyboard_prefix = 'konsole --hold -p tabtitle="Keyboard Server" -e' - - keyboard_server_node = Node( - package="cl_keyboard", - executable="keyboard_server_node.py", - name="keyboard_server_node", - output="screen", - prefix=keyboard_prefix, - arguments=["--ros-args", "--log-level", "INFO"], + keyboard_prefix = "konsole --hold -p tabtitle='Keyboard Server' -e" + + return LaunchDescription( + [ + Node( + package="sm_pack_ml", + executable="sm_pack_ml_node", + name="sm_pack_ml", + output="screen", + prefix=state_machine_prefix, + ), + Node( + package="cl_keyboard", + executable="keyboard_server_node.py", + name="keyboard_server_node", + output="screen", + prefix=keyboard_prefix, + ), + ], ) - - nodes_to_start = [ - sm_multi_stage_1_node, - keyboard_server_node, - ] - - return nodes_to_start diff --git a/smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/README.md b/smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/README.md index b4c4eb639..b3bb5bdd3 100644 --- a/smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/README.md +++ b/smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/README.md @@ -27,7 +27,7 @@ source install/setup.bash And then run the launch file... ``` -ros2 launch sm_panda_cl_moveit2z_cb_inventory sm_panda_cl_moveit2z_cb_inventory.launch.py +ros2 launch sm_panda_cl_moveit2z_cb_inventory sm_panda_cl_moveit2z_cb_inventory.py ``` diff --git a/smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/launch/sm_panda_cl_moveit2z_cb_inventory.launch.py b/smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/launch/sm_panda_cl_moveit2z_cb_inventory.py similarity index 100% rename from smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/launch/sm_panda_cl_moveit2z_cb_inventory.launch.py rename to smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/launch/sm_panda_cl_moveit2z_cb_inventory.py diff --git a/smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/package.xml b/smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/package.xml index 8016b4d15..6913d36a2 100644 --- a/smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/package.xml +++ b/smacc2_sm_reference_library/sm_panda_cl_moveit2z_cb_inventory/package.xml @@ -4,9 +4,8 @@ sm_panda_cl_moveit2z_cb_inventory 3.0.1 The sm_panda_cl_moveit2z_cb_inventory package - SMACC2 is cool + Brett Aldrich Apache-2.0 - MyLicense ament_cmake @@ -31,8 +30,8 @@ rclcpp yaml-cpp - joint_trajectory_controller + konsole ament_cmake diff --git a/smacc2_sm_reference_library/sm_three_some/README.md b/smacc2_sm_reference_library/sm_three_some/README.md index 435c1a2b6..49c9b01b2 100644 --- a/smacc2_sm_reference_library/sm_three_some/README.md +++ b/smacc2_sm_reference_library/sm_three_some/README.md @@ -30,10 +30,9 @@ source install/setup.bash ``` And then run the launch file... -! refactor state machine name ``` -ros2 launch sm_three_some sm_three_some.launch +ros2 launch sm_three_some sm_three_some.py ```

Viewer Instructions

diff --git a/smacc2_sm_reference_library/sm_three_some/launch/sm_three_some.launch b/smacc2_sm_reference_library/sm_three_some/launch/sm_three_some.launch deleted file mode 100644 index 3c2a2e794..000000000 --- a/smacc2_sm_reference_library/sm_three_some/launch/sm_three_some.launch +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/smacc2_sm_reference_library/sm_three_some/launch/sm_three_some.py b/smacc2_sm_reference_library/sm_three_some/launch/sm_three_some.py new file mode 100644 index 000000000..264c08e8f --- /dev/null +++ b/smacc2_sm_reference_library/sm_three_some/launch/sm_three_some.py @@ -0,0 +1,89 @@ +# Copyright 2021 RobosoftAI Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +from datetime import datetime +from launch import LaunchDescription +from launch_ros.actions import Node + + +def setup_log_directory(): + """ + Creates timestamped log directory with error handling. + Returns: (log_dir_path, timestamp) tuple + """ + timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S") + + # Primary log directory location + log_dir = os.path.join(os.path.expanduser("~"), ".ros", "log", f"{timestamp}-sm_three_some") + + try: + os.makedirs(log_dir, mode=0o755, exist_ok=True) + print(f"[Launch] Log directory created: {log_dir}") + return log_dir, timestamp + except PermissionError as e: + # Fallback to /tmp if ~/.ros is not writable + fallback_dir = os.path.join("/tmp", "sm_three_some_logs", timestamp) + print(f"[Launch] WARNING: Cannot create log directory at {log_dir}") + print(f"[Launch] Permission denied: {e}") + print(f"[Launch] Using fallback directory: {fallback_dir}") + try: + os.makedirs(fallback_dir, mode=0o755, exist_ok=True) + return fallback_dir, timestamp + except Exception as fallback_error: + print(f"[Launch] ERROR: Cannot create fallback directory: {fallback_error}") + print(f"[Launch] Logs will only be displayed in konsole terminals") + return None, timestamp + except OSError as e: + print(f"[Launch] ERROR: Failed to create log directory: {e}") + print(f"[Launch] Logs will only be displayed in konsole terminals") + return None, timestamp + + +def generate_launch_description(): + # Setup logging directory + log_dir, timestamp = setup_log_directory() + + # Construct logging prefix for state machine node + if log_dir: + state_machine_log = os.path.join(log_dir, f"state_machine_{timestamp}.log") + state_machine_prefix = f"konsole --hold -p tabtitle='SM Three Some' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {state_machine_log}; exec bash' -- " + else: + state_machine_prefix = "konsole --hold -p tabtitle='SM Three Some' -e" + + # Construct logging prefix for keyboard server node + if log_dir: + keyboard_log = os.path.join(log_dir, f"keyboard_server_{timestamp}.log") + keyboard_prefix = f"konsole --hold -p tabtitle='Keyboard Server' -e bash -c 'RCUTILS_COLORIZED_OUTPUT=1 \"$@\" 2>&1 | tee {keyboard_log}; exec bash' -- " + else: + keyboard_prefix = "konsole --hold -p tabtitle='Keyboard Server' -e" + + return LaunchDescription( + [ + Node( + package="sm_three_some", + executable="sm_three_some_node", + name="sm_three_some", + output="screen", + prefix=state_machine_prefix, + ), + Node( + package="cl_keyboard", + executable="keyboard_server_node.py", + name="keyboard_server_node", + output="screen", + prefix=keyboard_prefix, + ), + ], + )