Skip to content

Commit

Permalink
changes submodules to debians (#76)
Browse files Browse the repository at this point in the history
# PR Summary
PR Link: [Link](#76)

Issue Link: [Link](#75)

### Description
Switches compilation-heavy submodules for pre-compiled debians to assist
CI pipeline and embedded devices.

### Reviewers
- Required: @MaxxWilson 

---
### Changelog
- Switches submodules to track VEXU_GHOST forks.
- Changes setup_submodules.sh script to pull debians from new
ghost_dependencies repository instead of compiling from source locally.
- Skips debianized submodules in build and test scripts.
- Skips building visualization packages on arm machines (jetson).
- Adds reverse-ssh tunnel to CI pipeline for post-failure debugging.
  • Loading branch information
xwilson03 authored May 29, 2024
1 parent 5bcf42a commit 77e483a
Show file tree
Hide file tree
Showing 13 changed files with 290 additions and 66 deletions.
18 changes: 16 additions & 2 deletions .github/workflows/workflows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ on:
branches:
- master
- develop
workflow_dispatch:
inputs:
debug_enabled:
type: boolean
description: 'Host tmate session on failure for debugging.'
required: false
default: false

jobs:
build-and-test:
Expand Down Expand Up @@ -54,14 +61,21 @@ jobs:

- name: Build Submodules
run: ./scripts/setup_submodules.sh

- name: Build
run: |
env > ~/temp_env_1
./scripts/build.sh -r
source $VEXU_HOME/install/setup.bash
env > ~/temp_env_2
diff ~/temp_env_1 ~/temp_env_2 | sed '/^[^>]/d' | sed 's/> //'g | xargs -n1 echo >> $GITHUB_ENV
- name: Test
run: ./scripts/test_full.sh

- name: Open TMate Session
if: ${{ failure() }}
# && github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
uses: mxschmitt/action-tmate@v3
with:
detached: true
37 changes: 27 additions & 10 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,32 +1,49 @@
[submodule "01_Libraries/ghost_estimation/src/shared"]
path = 01_Libraries/ghost_estimation/src/shared
url = [email protected]:MaxxWilson/amrl_shared_lib.git
url = [email protected]:VEXU-GHOST/amrl_shared_lib.git

[submodule "09_External/yaml-cpp"]
path = 09_External/yaml-cpp
url = [email protected]:jbeder/yaml-cpp.git
url = [email protected]:VEXU-GHOST/yaml-cpp.git

[submodule "09_External/Casadi-Tutorial-CPP"]
path = 09_External/Casadi-Tutorial-CPP
url = [email protected]:zehuilu/Tutorial-on-CasADi-with-CPP.git
url = [email protected]:VEXU-GHOST/Tutorial-on-CasADi-with-CPP.git

[submodule "09_External/casadi"]
path = 09_External/casadi
url = https://github.com/casadi/casadi.git
url = [email protected]:VEXU-GHOST/casadi.git

[submodule "09_External/Ipopt"]
path = 09_External/Ipopt
url = [email protected]:MaxxWilson/Ipopt.git
url = [email protected]:VEXU-GHOST/Ipopt.git

[submodule "09_External/rplidar_ros"]
path = 09_External/rplidar_ros
url = [email protected]:Slamtec/rplidar_ros.git
url = [email protected]:VEXU-GHOST/rplidar_ros.git
branch = ros2

[submodule "09_External/matplotlib-cpp"]
path = 09_External/matplotlib-cpp
url = [email protected]:MaxxWilson/matplotlib-cpp.git
url = [email protected]:VEXU-GHOST/matplotlib-cpp.git

[submodule "09_External/ThirdParty-Mumps"]
path = 09_External/ThirdParty-Mumps
url = [email protected]:MaxxWilson/ThirdParty-Mumps.git
url = [email protected]:VEXU-GHOST/ThirdParty-Mumps.git
branch = with-src

[submodule "09_External/BehaviorTree.CPP"]
path = 09_External/BehaviorTree.CPP
url = [email protected]:BehaviorTree/BehaviorTree.CPP.git
url = [email protected]:VEXU-GHOST/BehaviorTree.CPP.git

[submodule "09_External/BehaviorTree.ROS2"]
path = 09_External/BehaviorTree.ROS2
url = https://github.com/JakeWendling/BehaviorTree.ROS2
url = [email protected]:VEXU-GHOST/BehaviorTree.ROS2.git

[submodule "09_External/plotjuggler"]
path = 09_External/plotjuggler
url = [email protected]:VEXU-GHOST/PlotJuggler.git

[submodule "09_External/plotjuggler-ros-plugins"]
path = 09_External/plotjuggler-ros-plugins
url = [email protected]:VEXU-GHOST/plotjuggler-ros-plugins.git
27 changes: 27 additions & 0 deletions 03_ROS/ghost_viz/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
cmake_minimum_required(VERSION 3.8)
project(ghost_viz)

# Add Global CMake Config for Ghost Packages
set(Ghost_DIR "$ENV{VEXU_HOME}/cmake")
find_package(Ghost CONFIG REQUIRED)

# Adds all our package dependencies to one list
set(DEPENDENCIES
ament_cmake
)

# Iterates through the list and finds the packages!
foreach(pkg ${DEPENDENCIES})
find_package(${pkg} REQUIRED)
endforeach()

# Tell any packages that depend on us what dependencies we need.
ament_export_dependencies(${DEPENDENCIES})

install(DIRECTORY
config
launch
DESTINATION share/${PROJECT_NAME})

# This generates the ROS2 package and should always be the last line.
ament_package()
64 changes: 64 additions & 0 deletions 03_ROS/ghost_viz/config/plotjuggler_config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?xml version='1.0' encoding='UTF-8'?>
<root>
<tabbed_widget parent="main_window" name="Main Window">
<Tab tab_name="tab1" containers="1">
<Container>
<DockSplitter count="1" sizes="1" orientation="-">
<DockArea name="...">
<plot mode="TimeSeries" flip_y="false" flip_x="false" style="Lines">
<range left="0.000000" top="1.000000" bottom="0.000000" right="1.000000"/>
<limitY/>
</plot>
</DockArea>
</DockSplitter>
</Container>
</Tab>
<currentTabIndex index="0"/>
</tabbed_widget>
<use_relative_time_offset enabled="1"/>
<!-- - - - - - - - - - - - - - - -->
<!-- - - - - - - - - - - - - - - -->
<Plugins>
<plugin ID="DataLoad CSV">
<parameters time_axis="" delimiter="0"/>
</plugin>
<plugin ID="DataLoad MCAP"/>
<plugin ID="DataLoad ROS2 bags">
<use_header_stamp value="false"/>
<discard_large_arrays value="true"/>
<max_array_size value="1000"/>
<boolean_strings_to_number value="true"/>
<remove_suffix_from_strings value="true"/>
<selected_topics value="/sensors/wheel_odom"/>
</plugin>
<plugin ID="DataLoad ULog"/>
<plugin ID="ROS2 Topic Subscriber">
<use_header_stamp value="false"/>
<discard_large_arrays value="true"/>
<max_array_size value="100"/>
<boolean_strings_to_number value="true"/>
<remove_suffix_from_strings value="true"/>
<selected_topics value="/trajectory/swerve_mpc_trajectory"/>
</plugin>
<plugin ID="UDP Server"/>
<plugin ID="WebSocket Server"/>
<plugin ID="ZMQ Subscriber"/>
<plugin ID="Fast Fourier Transform"/>
<plugin ID="Quaternion to RPY"/>
<plugin ID="Reactive Script Editor">
<library code="--[[ Helper function to create a series from arrays&#xa;&#xa; new_series: a series previously created with ScatterXY.new(name)&#xa; prefix: prefix of the timeseries, before the index of the array&#xa; suffix_X: suffix to complete the name of the series containing the X value. If [nil], use the index of the array.&#xa; suffix_Y: suffix to complete the name of the series containing the Y value&#xa; timestamp: usually the tracker_time variable&#xa; &#xa; Example:&#xa; &#xa; Assuming we have multiple series in the form:&#xa; &#xa; /trajectory/node.{X}/position/x&#xa; /trajectory/node.{X}/position/y&#xa; &#xa; where {N} is the index of the array (integer). We can create a reactive series from the array with:&#xa; &#xa; new_series = ScatterXY.new(&quot;my_trajectory&quot;) &#xa; CreateSeriesFromArray( new_series, &quot;/trajectory/node&quot;, &quot;position/x&quot;, &quot;position/y&quot;, tracker_time );&#xa;--]]&#xa;&#xa;function CreateSeriesFromArray( new_series, prefix, suffix_X, suffix_Y, timestamp )&#xa; &#xa; --- clear previous values&#xa; new_series:clear()&#xa; &#xa; --- Append points to new_series&#xa; index = 0&#xa; while(true) do&#xa;&#xa; x = index;&#xa; -- if not nil, get the X coordinate from a series&#xa; if suffix_X ~= nil then &#xa; series_x = TimeseriesView.find( string.format( &quot;%s.%d/%s&quot;, prefix, index, suffix_X) )&#xa; if series_x == nil then break end&#xa; x = series_x:atTime(timestamp)&#x9; &#xa; end&#xa; &#xa; series_y = TimeseriesView.find( string.format( &quot;%s.%d/%s&quot;, prefix, index, suffix_Y) )&#xa; if series_y == nil then break end &#xa; y = series_y:atTime(timestamp)&#xa; &#xa; new_series:push_back(x,y)&#xa; index = index+1&#xa; end&#xa;end&#xa;&#xa;--[[ Similar to the built-in function GetSeriesNames(), but select only the names with a give prefix. --]]&#xa;&#xa;function GetSeriesNamesByPrefix(prefix)&#xa; -- GetSeriesNames(9 is a built-in function&#xa; all_names = GetSeriesNames()&#xa; filtered_names = {}&#xa; for i, name in ipairs(all_names) do&#xa; -- check the prefix&#xa; if name:find(prefix, 1, #prefix) then&#xa; table.insert(filtered_names, name);&#xa; end&#xa; end&#xa; return filtered_names&#xa;end&#xa;&#xa;--[[ Modify an existing series, applying offsets to all their X and Y values&#xa;&#xa; series: an existing timeseries, obtained with TimeseriesView.find(name)&#xa; delta_x: offset to apply to each x value&#xa; delta_y: offset to apply to each y value &#xa; &#xa;--]]&#xa;&#xa;function ApplyOffsetInPlace(series, delta_x, delta_y)&#xa; -- use C++ indeces, not Lua indeces&#xa; for index=0, series:size()-1 do&#xa; x,y = series:at(index)&#xa; series:set(index, x + delta_x, y + delta_y)&#xa; end&#xa;end&#xa;&#xa;function TopicSplitter(inputstr)&#xa; local t = {}&#xa; for str in string.gmatch(inputstr, &quot;[^/]+&quot;) do&#xa; table.insert(t, str)&#xa; end&#xa; return t&#xa;end&#xa;&#xa;function getDataFromSeriesName(name, time_sample)&#xa; local data = {}&#xa; local count = 0&#xa; while(true) do&#xa; local series_name = string.format(&quot;%s/%d&quot;, name, count)&#xa; local series = TimeseriesView.find(series_name)&#xa; &#xa; if(series == nil) then&#xa; break&#xa; end&#xa; &#xa; table.insert(data, series:atTime(time_sample))&#xa; count = count + 1&#xa; end&#xa; return data&#xa;end&#xa;"/>
<scripts>
<script function="series_names = GetSeriesNamesByPrefix(&quot;trajectory&quot;)&#xa; &#xa;-- Adds new trajectories when received&#xa;for i, name in ipairs(series_names) do&#xa; t = TopicSplitter(name)&#xa; local group_name = t[2]&#xa; local trajectory_name = t[3]&#xa; &#xa; -- If we haven't seen this trajectory group before, add table for group&#xa; if(trajectory_groups[group_name] == nil) then&#xa; trajectory_groups[group_name] = {}&#xa; end&#xa; -- If we haven't seen this trajectory within the group before, add series for it&#xa; if(trajectory_groups[group_name][trajectory_name] == nil) then&#xa; if(trajectory_name == &quot;time&quot;)then&#xa; trajectory_groups[group_name][trajectory_name] = true&#xa; else &#xa; new_series_name = string.format(&quot;%s/%s&quot;, group_name, trajectory_name)&#xa; print(&quot;Creating new trajectory category&quot;, new_series_name)&#xa; trajectory_groups[group_name][trajectory_name] = ScatterXY.new(new_series_name)&#xa; end&#xa; end&#xa;end&#xa;&#xa;-- Update existing trajectories --&#xa;for group_name, trajectory_map in pairs(trajectory_groups) do&#xa; -- Abort for groups without a time vector&#xa; if(trajectory_map[&quot;time&quot;] == nil)then&#xa; print(&quot;No Time series found! Cannot continue for group: &quot;, group_name)&#xa; break&#xa; end&#xa; -- Process time vector first&#xa; time_str = string.format(&quot;/trajectory/%s/%s&quot;, group_name, &quot;time&quot;)&#xa; time_array = getDataFromSeriesName(time_str, tracker_time);&#xa; &#xa; for traj_name, data in pairs(trajectory_map) do&#xa; local series = trajectory_groups[group_name][traj_name]&#xa; if(traj_name ~= &quot;time&quot;) then&#xa; series:clear()&#xa; local data_str = string.format(&quot;/trajectory/%s/%s&quot;, group_name, traj_name)&#xa; local data_array = getDataFromSeriesName(data_str, tracker_time)&#xa; &#xa; for index, val in ipairs(data_array) do&#xa; series:push_back(time_array[index], val)&#xa; end&#xa; end&#xa; end&#xa;end&#xa; " name="trajectory_plotter" global="trajectory_groups = {}&#xa;printed_already = false"/>
</scripts>
</plugin>
<plugin ID="CSV Exporter"/>
<plugin ID="ROS2 Topic Re-Publisher"/>
</Plugins>
<!-- - - - - - - - - - - - - - - -->
<previouslyLoaded_Datafiles/>
<!-- - - - - - - - - - - - - - - -->
<customMathEquations/>
<snippets/>
<!-- - - - - - - - - - - - - - - -->
</root>

23 changes: 23 additions & 0 deletions 03_ROS/ghost_viz/launch/trajectory_plotter.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import os
from launch import LaunchDescription
from launch_ros.actions import Node


def generate_launch_description():
home_dir = os.path.expanduser("~")
pkg_share_dir = os.path.join(
home_dir, "VEXU_GHOST", "03_ROS", "ghost_viz"
)

# This contains all the parameters for our ROS nodes
pt_config_path = os.path.join(pkg_share_dir, "config/plotjuggler_config.xml")


plotjuggler_node = Node(
package="plotjuggler",
executable="plotjuggler",
output="screen",
arguments=["-n", "-l", pt_config_path]
)

return LaunchDescription([plotjuggler_node])
21 changes: 21 additions & 0 deletions 03_ROS/ghost_viz/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>ghost_viz</name>
<version>1.0.0</version>
<description>Provides tools for vizualization and plotting for GHOST projects</description>
<maintainer email="[email protected]">maxx</maintainer>
<license>MIT</license>

<buildtool_depend>ament_cmake</buildtool_depend>

<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>

<exec_depend>plotjuggler</exec_depend>
<exec_depend>plotjuggler_ros</exec_depend>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>
1 change: 1 addition & 0 deletions 09_External/plotjuggler
Submodule plotjuggler added at f3eabf
1 change: 1 addition & 0 deletions 09_External/plotjuggler-ros-plugins
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ int main(int argc, char * argv[])

auto node_ptr = std::make_shared<rclcpp::Node>("swerve_mpc_node");
auto mpc_trajectory_publisher = node_ptr->create_publisher<ghost_msgs::msg::LabeledVectorMap>(
"/swerve_mpc_trajectory", 10);
"/trajectory/swerve_mpc_trajectory", 10);

std::thread node_thread([&]() {
rclcpp::spin(node_ptr);
Expand Down Expand Up @@ -359,6 +359,14 @@ int main(int argc, char * argv[])
}
}

// Allocate timeseries vector for each state/input variable
solution_map["time"] = std::vector<double>(NUM_KNOTS);

// Iterate through timeseries and add final state values to solution vector
for (int k = 0; k < NUM_KNOTS; k++) {
solution_map["time"][k] = DT * ((double) k);
}

return solution_map;
};

Expand Down
12 changes: 10 additions & 2 deletions scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,23 @@ arch=$(uname -p)
cd $VEXU_HOME
echo "---Building Ghost ROS Packages---"

skip=(
behaviortree_cpp
behaviortree_ros2
btcpp_ros2_interfaces
btcpp_ros2_samples
rplidar_ros
)

# Build ignores simulator packages on embedded devices
if [ "$arch" == 'x86_64' ];
then
colcon build --symlink-install --packages-skip --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON || exit -1
colcon build --symlink-install --packages-skip ${skip[@]} --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON || exit -1
fi

if [ "$arch" == 'aarch64' ];
then
colcon build --symlink-install --packages-skip ghost_sim --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON || exit -1
colcon build --symlink-install --packages-skip ${skip[@]} ghost_sim ghost_viz plotjuggler plotjuggler-ros-plugins --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON || exit -1
fi

if [ "$1" != "-r" ];
Expand Down
Loading

0 comments on commit 77e483a

Please sign in to comment.