2023-06-26 04:01:32 -0500 | received badge | ● Famous Question
(source)
|
2023-06-26 04:01:32 -0500 | received badge | ● Popular Question
(source)
|
2023-06-26 04:01:32 -0500 | received badge | ● Notable Question
(source)
|
2023-02-19 07:57:04 -0500 | received badge | ● Famous Question
(source)
|
2022-12-22 04:38:07 -0500 | received badge | ● Famous Question
(source)
|
2022-12-22 04:38:07 -0500 | received badge | ● Notable Question
(source)
|
2022-11-29 14:44:48 -0500 | received badge | ● Famous Question
(source)
|
2022-11-29 14:44:48 -0500 | received badge | ● Notable Question
(source)
|
2022-09-23 13:57:12 -0500 | marked best answer | [ROS2 Foxy] Passing argument from one launch file to another I have compartmentalized my launch files into different purposes, I currently have a main launch file from which I would like to call one of the others. I have partly done this to be able to separate some of the functionalities, but also so the main launch doesn't become to verbose. The main launch file gets passed an argument for the vehicle platform architecture, such as to find a specific config file highlighting some necessary parameters. This argument that is to be passed is platform . How can I pass this argument from the main launch file to its children. I included an example of the main.launch.py so one can see how the platform arg is being used. import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions.declare_launch_argument import DeclareLaunchArgument
from launch.actions.include_launch_description import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
def generate_launch_description():
# defining platform
# select either newholland_t7 or fort_rd25
platforms = ["newholland_t7", "fort_rd25"]
for id, plat in enumerate(platforms):
print(f"\t{id} for {plat}")
platform_id = int(input("Select a platform: "))
try:
platform = platforms[platform_id]
except IndexError as ex:
print(f"[ERROR]: {ex}, please select valid index")
return LaunchDescription()
print(f"Selected {platform}")
urdf_path = os.path.join(
get_package_share_directory("main_pkg"), "urdf", platform + ".urdf.xml"
)
with open(urdf_path, "r") as infp:
robot_description = infp.read()
urdf_publisher = Node(
package="robot_state_publisher",
executable="robot_state_publisher",
name="robot_state_publisher",
parameters=[{"robot_description": robot_description}],
arguments=[urdf_path],
output="screen",
)
danger_zone_config = os.path.join(
get_package_share_directory("agrirobot"), "config", platform + ".yaml"
)
visualize_markers = Node(
package="visualize_markers",
executable="visualize_markers_node",
name="visualize_markers",
parameters=[danger_zone_config],
output="screen",
)
# some other things
ld = LaunchDescription()
ld.add_action(urdf_publisher)
ld.add_action(visualize_markers)
return ld
|
2022-09-13 07:33:10 -0500 | marked best answer | Robot localization ekf capped at 10Hz I'm using the ekf in robot_localization , for some reason it doesn't seem to want to go above the odd 10Hz. I've checked my imu and odometry rates, and they're both 50Hz as I've set them. I launch the ekf node by ros2 launch tractor_gazebo ekf.launch.py use_sim_time:=true and I check the individual frequencies: $ ros2 param get /ekf_localization_odom frequency
Double value is: 30.0
$ ros2 topic hz /imu/data
average rate: 49.887
min: 0.020s max: 0.021s std dev: 0.00020s window: 51
$ ros2 topic hz /odometry/wheel
average rate: 49.910
min: 0.020s max: 0.021s std dev: 0.00018s window: 51
average rate: 49.853
min: 0.020s max: 0.021s std dev: 0.00020s window: 101
$ ros2 topic hz /odometry/filtered/odom
average rate: 9.956
min: 0.100s max: 0.101s std dev: 0.00033s window: 11
average rate: 9.961
min: 0.099s max: 0.101s std dev: 0.00043s window: 21
with the launch and config files added at the bottom. Note: I have tried setting the ekf frequency to less than 10Hz, and this is can follow fine. So, e.g. changing the parameter in the yaml to 5Hz results in publishing to /odometry/filtered/odom at 5Hz, setting it to 15Hz instead results in the topic publishing at 10Hz. This is the core of the problem ekf.launch.py: import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
def generate_launch_description():
# get directories
tractor_gazebo_dir = get_package_share_directory("tractor_gazebo")
# Create the launch configuration variables
use_sim_time = LaunchConfiguration("use_sim_time")
# declare launch arguments
declare_use_sim_time = DeclareLaunchArgument("use_sim_time")
# Specify the actions
robot_localization_odom = Node(
package="robot_localization",
executable="ekf_node",
name="ekf_localization_odom",
output="screen",
parameters=[
{"use_sim_time": use_sim_time},
os.path.join(
tractor_gazebo_dir,
"config",
"dual_ekf_navsat_toolcarrier.yaml",
),
],
remappings=[("odometry/filtered", "odometry/filtered/odom")],
)
return LaunchDescription(
[
declare_use_sim_time,
robot_localization_odom,
]
)
config file: ekf_localization_odom:
ros__parameters:
frequency: 30.0
sensor_timeout: 0.0 #0.1
two_d_mode: true
transform_time_offset: 0.0 #0.01
transform_timeout: 0.0
print_diagnostics: true
debug: false
map_frame: map
odom_frame: odom
base_link_frame: base_link
world_frame: odom
odom0: odometry/wheel
odom0_config: [false, false, false,
false, false, false,
true, true, false,
false, false, true,
false, false, false]
odom0_queue_size: 10
odom0_nodelay: true
odom0_differential: false
odom0_relative: false
imu0: imu/data
imu0_config: [false, false, false,
true, true, true,
false, false, false,
true, true, true,
true, true, true]
imu0_nodelay: false
imu0_differential: false
imu0_relative: false
imu0_queue_size: 10
imu0_remove_gravitational_acceleration: true
use_control: false
Edit: Following @osilva's comments I have checked the sim time parameter of all the nodes: morten@agrirobot:~$ ros2 param list
/ackermann_drive:
use_sim_time
/camera_controller_front:
use_sim_time
/camera_controller_middle:
use_sim_time
/controller_manager:
use_sim_time
/ekf_localization_odom:
use_sim_time
/gazebo:
use_sim_time
/gazebo_ros2_control:
use_sim_time
/velodyne_front/gazebo_ros_laser_controller:
use_sim_time
/gps:
use_sim_time
/imu:
use_sim_time
/joint_state_publisher:
use_sim_time
/robot_state_publisher:
use_sim_time
Note, I've trimmed the other parameters so as not to go on too long, I have checked each and every one of these: morten@agrirobot:~$ ros2 param get /ackermann_drive use_sim_time
Boolean value is: True
morten@agrirobot:~$ ros2 param get /camera_controller_front use_sim_time
Boolean value is: True ... (more) |
2022-09-13 07:33:10 -0500 | received badge | ● Enlightened
(source)
|
2022-09-13 07:33:10 -0500 | received badge | ● Good Answer
(source)
|
2022-08-29 03:53:57 -0500 | received badge | ● Popular Question
(source)
|
2022-08-28 05:03:21 -0500 | commented answer | Publishing multiple messages on same topic at same time so each reading corresponds to a different viewpoint, this is to publish all clouds when the viewpoint transforms are up |
2022-08-27 12:21:28 -0500 | asked a question | Publishing multiple messages on same topic at same time Publishing multiple messages on same topic at same time
I need to publish a several messages containing point clouds fro |
2022-08-16 22:36:12 -0500 | received badge | ● Famous Question
(source)
|
2022-08-02 22:16:36 -0500 | marked best answer | ros2 foxy including header file from other package I have two packages, temp_lib and temp_pkg . In temp_lib I have a file temp.hpp that I would like to include in other packages, but when I attempt to do so by writing in #include "temp_lib/temp.hpp" in a cpp file in temp_pkg then it says this header cannot be found. The problem is i'm not really sure how to set up the CMakeLists file for the library. How can I set these packages up for this to be possible? LIBRARY CMAKE cmake_minimum_required(VERSION 3.5)
project(temp_lib)
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
install(TARGETS
DESTINATION lib/${PROJECT_NAME}
PUBLIC_HEADER DESTINATION include/${PROJECT_NAME}/
)
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION include/${PROJECT_NAME}
FILES_MATCHING PATTERN "*.h"
PATTERN ".git" EXCLUDE)
ament_package()
temp.hpp (from temp_lib ) #ifndef TEMP_LIB__TEMP_HPP_
#define TEMP_LIB__TEMP_HPP_
#include <iostream>
#endif // TEMP_LIB__TEMP_HPP_
PKG CMAKE cmake_minimum_required(VERSION 3.5)
project(temp_pkg)
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(temp_lib REQUIRED)
include_directories(
${temp_lib_INCLUDE_DIRS}
)
add_executable(test src/temp.cpp)
ament_target_dependencies(test rclcpp temp_lib)
install(TARGETS
test
DESTINATION lib/${PROJECT_NAME}
)
ament_package()
temp.cpp (from temp_pkg ) #include "temp_lib/temp.hpp"
int main(int argc, char *argv[]) {
std::cout << "it works" << std::endl;
return 0;
}
Edit: for legibility I removed some repeated standard parts of the CMake files, these are # Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
and if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# uncomment the line when a copyright and license is not present in all source files
#set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# uncomment the line when this package is not in a git repo
#set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
|
2022-07-13 07:00:09 -0500 | received badge | ● Nice Answer
(source)
|
2022-07-09 13:30:08 -0500 | received badge | ● Notable Question
(source)
|
2022-07-09 13:30:08 -0500 | received badge | ● Famous Question
(source)
|
2022-07-06 11:06:03 -0500 | received badge | ● Popular Question
(source)
|
2022-07-06 11:06:03 -0500 | received badge | ● Notable Question
(source)
|
2022-07-04 07:22:57 -0500 | received badge | ● Famous Question
(source)
|
2022-06-01 07:49:25 -0500 | received badge | ● Famous Question
(source)
|
2022-05-25 02:53:55 -0500 | received badge | ● Notable Question
(source)
|
2022-05-24 02:23:52 -0500 | received badge | ● Famous Question
(source)
|
2022-04-26 01:59:44 -0500 | marked best answer | Passing pcl::shared_ptr to subscriber (ROS2 Foxy) I am trying to write a pointcloud filtering node in ROS2 foxy using pcl but I am running into some problems I think are resulting from the publishing. The resulting error is ~/ros2_ws$ colcon build --symlink-install --packages-select pointcloud_filters
Starting >>> pointcloud_filters
--- stderr: pointcloud_filters
** WARNING ** io features related to pcap will be disabled
** WARNING ** io features related to png will be disabled
** WARNING ** io features related to libusb-1.0 will be disabled
/usr/bin/ld: CMakeFiles/pointcloud_filters_node.dir/src/pointcloud_filters_node.cpp.o: in function `rclcpp::Publisher<pcl::PointCloud<pcl::PointXYZI>, std::allocator<void> >::Publisher(rclcpp::node_interfaces::NodeBaseInterface*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rclcpp::QoS const&, rclcpp::PublisherOptionsWithAllocator<std::allocator<void> > const&)':
pointcloud_filters_node.cpp:(.text._ZN6rclcpp9PublisherIN3pcl10PointCloudINS1_9PointXYZIEEESaIvEEC2EPNS_15node_interfaces17NodeBaseInterfaceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3QoSERKNS_29PublisherOptionsWithAllocatorIS5_EE[_ZN6rclcpp9PublisherIN3pcl10PointCloudINS1_9PointXYZIEEESaIvEEC5EPNS_15node_interfaces17NodeBaseInterfaceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3QoSERKNS_29PublisherOptionsWithAllocatorIS5_EE]+0x6e): undefined reference to `rosidl_message_type_support_t const* rosidl_typesupport_cpp::get_message_type_support_handle<pcl::PointCloud<pcl::PointXYZI> >()'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/pointcloud_filters_node.dir/build.make:317: pointcloud_filters_node] Error 1
make[1]: *** [CMakeFiles/Makefile2:78: CMakeFiles/pointcloud_filters_node.dir/all] Error 2
make: *** [Makefile:141: all] Error 2
---
Failed <<< pointcloud_filters [12.3s, exited with code 2]
Summary: 0 packages finished [12.4s]
1 package failed: pointcloud_filters
1 package had stderr output: pointcloud_filters
so its complaining about some undefined reference. I'm not entirely sure what the problem is but it seems like it could be similar to https://answers.ros.org/question/3117.... I looked at the interfaces for sensor_msgs/msg/PointCloud2 and sensor_msgs/msg./PointField and it looks identical to pcl::PointCloud so maybe I should manually transfer the attributes? CPP file: #include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/point_cloud2.hpp"
#include "pcl_conversions/pcl_conversions.h"
#include "pcl/filters/radius_outlier_removal.h"
#include "pcl/impl/point_types.hpp"
#include "pcl/point_cloud.h"
class PCFilter : public rclcpp::Node {
public:
PCFilter() : Node("pointcloud_filters") {
pub_ = this->create_publisher<pcl::PointCloud<pcl::PointXYZI>>(
"filters_output", 1);
sub_ = this->create_subscription<sensor_msgs::msg::PointCloud2>(
"filters_input", 1,
std::bind(&PCFilter::cloud_callback, this, std::placeholders::_1));
this->declare_parameter("pointcloud_filters/neighbors", 1);
this->declare_parameter("pointcloud_filters/radius", 0.2);
this->declare_parameter("pointcloud_filters/distance", 5.0);
this->declare_parameter("pointcloud_filters/intensity_threshold", 8);
neighbors_ = this->get_parameter("pointcloud_filters/neighbors").as_int();
radius_ = this->get_parameter("pointcloud_filters/radius").as_double();
distance_ = this->get_parameter("pointcloud_filters/distance").as_double();
intensity_threshold_ =
this->get_parameter("pointcloud_filters/intensity_threshold").as_int();
RCLCPP_INFO(this->get_logger(),
"Filter "
"pararms:\n\tneighbors:%d\t\nradius:%f\n\tdistance:%"
"f\n\tintensity_threshold:%d",
neighbors_, radius_, distance_, intensity_threshold_);
}
private:
void cloud_callback(const sensor_msgs::msg::PointCloud2::SharedPtr msg) {
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZI>);
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered(
new pcl::PointCloud<pcl::PointXYZI>);
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_dust_filtered(
new pcl::PointCloud<pcl::PointXYZI>);
pcl::fromROSMsg(*msg, *cloud);
if (cloud->size() > 0) {
// Filter dust based on low intensity within a certain distance from the
// lidar
double dist = 0.0;
for (std::size_t n = 0; n < cloud->size(); n++) {
dist = std::sqrt(std::pow(cloud->points[n].x, 2) +
std::pow(cloud->points[n].y, 2) +
std::pow(cloud->points[n].z, 2));
if (dist < distance_) {
if (cloud->points[n].intensity > intensity_threshold_) {
cloud_dust_filtered->push_back(cloud->points[n]);
}
} else {
cloud_dust_filtered->push_back(cloud->points[n]);
}
}
cloud_dust_filtered->header.frame_id = cloud->header.frame_id;
cloud_dust_filtered->header.stamp = cloud->header.stamp;
// Create radius outlier removal filter
pcl::RadiusOutlierRemoval<pcl::PointXYZI> outrem;
outrem.setInputCloud(cloud_dust_filtered);
outrem.setRadiusSearch(radius_);
outrem.setMinNeighborsInRadius(neighbors_);
// Apply filter
outrem.filter ... (more) |
2022-04-26 01:59:44 -0500 | received badge | ● Self-Learner
(source)
|
2022-04-23 15:09:00 -0500 | received badge | ● Famous Question
(source)
|
2022-04-14 16:59:33 -0500 | received badge | ● Famous Question
(source)
|
2022-04-07 03:32:17 -0500 | received badge | ● Famous Question
(source)
|
2022-04-04 15:48:39 -0500 | received badge | ● Famous Question
(source)
|
2022-03-14 10:42:55 -0500 | received badge | ● Popular Question
(source)
|
2022-03-14 10:42:55 -0500 | received badge | ● Notable Question
(source)
|
2022-03-11 14:07:07 -0500 | received badge | ● Notable Question
(source)
|
2022-03-08 15:18:28 -0500 | received badge | ● Famous Question
(source)
|
2022-03-08 15:18:28 -0500 | received badge | ● Notable Question
(source)
|
2022-03-04 03:56:11 -0500 | asked a question | Best practices for CMake with nested libraries Best practices for CMake with nested libraries
I have, at least what I think is, a slightly unique setup currently with |
2022-03-01 15:23:48 -0500 | received badge | ● Famous Question
(source)
|
2022-03-01 15:23:48 -0500 | received badge | ● Notable Question
(source)
|
2022-03-01 15:23:48 -0500 | received badge | ● Popular Question
(source)
|
2022-02-23 06:24:08 -0500 | received badge | ● Famous Question
(source)
|
2022-02-22 15:49:24 -0500 | received badge | ● Notable Question
(source)
|
2022-02-22 11:56:00 -0500 | received badge | ● Necromancer
(source)
|
2022-02-22 11:56:00 -0500 | received badge | ● Self-Learner
(source)
|
2022-02-22 11:55:25 -0500 | received badge | ● Popular Question
(source)
|
2022-02-22 07:36:21 -0500 | marked best answer | Intra-Process Communication between Components in Container Is it possible to take advantage of Intra Process Comms (IPC) when starting nodes in a container? I've made an example, trying to made a basic subscriber and publisher and looking at the pointer address, it seems as though it only works when "manually" composing. This just seems surprising given the text in the composable nodes tutorial, which seems to indicate manually composing should somehow be "equivalent" to the container route. Especially given that manually composing using a multi-threaded executor also works fine. Find the demo project here. The following example outputs are directly taken from this. Example Outputs Expected With multi-threaded executor $ ros2 run ipc_demo manual_composition
[INFO] [1642518288.545003595] [ipc_talker]: Count: 0 Addr: 0x7f1dbc001300
[INFO] [1642518288.545393895] [ipc_listener]: Count: 0 Addr: 0x7f1dbc001300
[INFO] [1642518289.544906771] [ipc_talker]: Count: 1 Addr: 0x7f1dbc001400
[INFO] [1642518289.544989777] [ipc_listener]: Count: 1 Addr: 0x7f1dbc001400
[INFO] [1642518290.545010214] [ipc_talker]: Count: 2 Addr: 0x7f1dbc0032c0
[INFO] [1642518290.545243590] [ipc_listener]: Count: 2 Addr: 0x7f1dbc0032c0
[INFO] [1642518291.545039618] [ipc_talker]: Count: 3 Addr: 0x7f1dbc003f80
[INFO] [1642518291.545282153] [ipc_listener]: Count: 3 Addr: 0x7f1dbc003f80
[INFO] [1642518292.544973975] [ipc_talker]: Count: 4 Addr: 0x7f1db0001740
[INFO] [1642518292.545166314] [ipc_listener]: Count: 4 Addr: 0x7f1db0001740
Pointer addresses are the same, so should be working as expected. Container $ ros2 launch ipc_demo composition.launch.py
[INFO] [launch]: All log files can be found below /home/morten/.ros/log/2022-01-18-16-04-58-690321-agrirobot-44101
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [component_container-1]: process started with pid [44117]
[component_container-1] [INFO] [1642518299.060037442] [two_nodes]: Load Library: /home/morten/temp_ws/install/ipc_demo/lib/libtalker_component.so
[component_container-1] [INFO] [1642518299.061590715] [two_nodes]: Found class: rclcpp_components::NodeFactoryTemplate<composition::Talker>
[component_container-1] [INFO] [1642518299.061656586] [two_nodes]: Instantiate class: rclcpp_components::NodeFactoryTemplate<composition::Talker>
[INFO] [launch_ros.actions.load_composable_nodes]: Loaded node '/talker' in container '/two_nodes'
[component_container-1] [INFO] [1642518299.068096064] [two_nodes]: Load Library: /home/morten/temp_ws/install/ipc_demo/lib/liblistener_component.so
[component_container-1] [INFO] [1642518299.068447676] [two_nodes]: Found class: rclcpp_components::NodeFactoryTemplate<composition::Listener>
[component_container-1] [INFO] [1642518299.068460910] [two_nodes]: Instantiate class: rclcpp_components::NodeFactoryTemplate<composition::Listener>
[INFO] [launch_ros.actions.load_composable_nodes]: Loaded node '/listener' in container '/two_nodes'
[component_container-1] [INFO] [1642518300.067406025] [talker]: Count: 0 Addr: 0x557f63f68960
[component_container-1] [INFO] [1642518300.067869433] [listener]: Count: 0 Addr: 0x557f63e42fd0
[component_container-1] [INFO] [1642518301.067393044] [talker]: Count: 1 Addr: 0x557f63e04720
[component_container-1] [INFO] [1642518301.067703912] [listener]: Count: 1 Addr: 0x557f64035980
[component_container-1] [INFO] [1642518302.067380956] [talker]: Count: 2 Addr: 0x557f64053c20
[component_container-1] [INFO] [1642518302.067666810] [listener]: Count: 2 Addr: 0x557f63e42fd0
Different pointer addresses between corresponding talker/listener message. |
2022-02-22 07:36:18 -0500 | edited answer | Intra-Process Communication between Components in Container Way down the road found a way to make it work, no one's responded so I'll post my own answer. See here, an example launc |