delete no used smacc2 code
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,48 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(cl_keyboard)
|
||||
|
||||
# Default to C++17
|
||||
if(NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(-Wall -Wextra -Wpedantic)
|
||||
endif()
|
||||
|
||||
# find dependencies
|
||||
find_package(ament_cmake REQUIRED)
|
||||
find_package(smacc2 REQUIRED)
|
||||
find_package(std_msgs REQUIRED)
|
||||
|
||||
include_directories(
|
||||
include
|
||||
${smacc2_INCLUDE_DIRS}
|
||||
${std_msgs_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES src *.cpp)
|
||||
#file(GLOB_RECURSE SRC_FILES "src/*.cpp" "src/client_behaviors/*.cpp")
|
||||
|
||||
add_library(${PROJECT_NAME}
|
||||
${SRC_FILES}
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} ${smacc2_LIBRARIES} ${std_msgs_LIBRARIES})
|
||||
ament_target_dependencies(${PROJECT_NAME} smacc2 std_msgs)
|
||||
ament_export_include_directories(include)
|
||||
ament_export_libraries(${PROJECT_NAME})
|
||||
|
||||
install(
|
||||
DIRECTORY include/
|
||||
DESTINATION include)
|
||||
|
||||
install(TARGETS
|
||||
${PROJECT_NAME}
|
||||
DESTINATION lib/)
|
||||
|
||||
install(PROGRAMS
|
||||
servers/keyboard_server_node.py
|
||||
DESTINATION lib/${PROJECT_NAME})
|
||||
|
||||
ament_package()
|
||||
@@ -1,58 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cl_keyboard/components/cp_keyboard_listener_1.hpp>
|
||||
|
||||
#include <smacc2/client_core_components/cp_topic_subscriber.hpp>
|
||||
|
||||
#include <smacc2/introspection/introspection.hpp>
|
||||
#include <smacc2/smacc.hpp>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/posix/stream_descriptor.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <std_msgs/msg/u_int16.hpp>
|
||||
|
||||
namespace cl_keyboard
|
||||
{
|
||||
class ClKeyboard : public smacc2::ISmaccClient
|
||||
{
|
||||
public:
|
||||
ClKeyboard();
|
||||
virtual ~ClKeyboard();
|
||||
|
||||
// Override the base class methods to call our setup
|
||||
template <typename TOrthogonal, typename TClient>
|
||||
void onComponentInitialization()
|
||||
|
||||
// Clients utilize a composition based architecture for their components.
|
||||
// In the function body below we create the components that will be used in this client.
|
||||
|
||||
{
|
||||
// We start by creating a topic subscriber component from SMACC2s client core components.
|
||||
// We use this to gain the topic funcionality interated with SMACC and the ability to post smacc events for transitions.
|
||||
// We are using it to handle the reception of ros topic messages and to notify the other components in the client.
|
||||
this->createComponent<
|
||||
smacc2::client_core_components::CpTopicSubscriber<std_msgs::msg::UInt16>, TOrthogonal,
|
||||
ClKeyboard>("/keyboard_unicode");
|
||||
|
||||
// This keyboard listener component requires CpTopicSubscriber.
|
||||
// It is notified by the CpTopicSubscriber and processes the messages to decide which keyboard event must be posted and then posts it.
|
||||
this->createComponent<cl_keyboard::components::CpKeyboardListener1, TOrthogonal, ClKeyboard>();
|
||||
}
|
||||
};
|
||||
} // namespace cl_keyboard
|
||||
@@ -1,110 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cl_keyboard/cl_keyboard.hpp>
|
||||
#include <smacc2/smacc_client_behavior.hpp>
|
||||
|
||||
#include <std_msgs/msg/u_int16.hpp>
|
||||
|
||||
namespace cl_keyboard
|
||||
{
|
||||
using namespace cl_keyboard::components;
|
||||
|
||||
class CbDefaultKeyboardBehavior : public smacc2::SmaccClientBehavior
|
||||
{
|
||||
public:
|
||||
components::CpKeyboardListener1 * cpSubscriber1;
|
||||
std::function<void(char)> postEventKeyPress;
|
||||
|
||||
void onEntry()
|
||||
{
|
||||
this->requiresComponent(this->cpSubscriber1);
|
||||
this->cpSubscriber1->OnKeyPress(&CbDefaultKeyboardBehavior::OnKeyPress, this);
|
||||
}
|
||||
|
||||
template <typename TOrthogonal, typename TSourceObject>
|
||||
void onStateOrthogonalAllocation()
|
||||
{
|
||||
postEventKeyPress = [=](char character)
|
||||
{
|
||||
if (character == 'a')
|
||||
postKeyEvent<EvKeyPressA<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'b')
|
||||
postKeyEvent<EvKeyPressB<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'c')
|
||||
postKeyEvent<EvKeyPressC<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'd')
|
||||
postKeyEvent<EvKeyPressD<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'e')
|
||||
postKeyEvent<EvKeyPressE<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'f')
|
||||
postKeyEvent<EvKeyPressF<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'g')
|
||||
postKeyEvent<EvKeyPressG<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'h')
|
||||
postKeyEvent<EvKeyPressH<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'i')
|
||||
postKeyEvent<EvKeyPressI<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'j')
|
||||
postKeyEvent<EvKeyPressJ<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'k')
|
||||
postKeyEvent<EvKeyPressK<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'l')
|
||||
postKeyEvent<EvKeyPressL<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'm')
|
||||
postKeyEvent<EvKeyPressM<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'n')
|
||||
postKeyEvent<EvKeyPressN<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'o')
|
||||
postKeyEvent<EvKeyPressO<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'p')
|
||||
postKeyEvent<EvKeyPressP<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'q')
|
||||
postKeyEvent<EvKeyPressQ<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'r')
|
||||
postKeyEvent<EvKeyPressR<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 's')
|
||||
postKeyEvent<EvKeyPressS<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 't')
|
||||
postKeyEvent<EvKeyPressT<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'u')
|
||||
postKeyEvent<EvKeyPressU<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'v')
|
||||
postKeyEvent<EvKeyPressV<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'w')
|
||||
postKeyEvent<EvKeyPressW<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'x')
|
||||
postKeyEvent<EvKeyPressX<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'y')
|
||||
postKeyEvent<EvKeyPressY<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
else if (character == 'z')
|
||||
postKeyEvent<EvKeyPressZ<CbDefaultKeyboardBehavior, TOrthogonal>>();
|
||||
};
|
||||
}
|
||||
|
||||
void OnKeyPress(char character) { postEventKeyPress(character); }
|
||||
|
||||
template <typename TEv>
|
||||
void postKeyEvent()
|
||||
{
|
||||
RCLCPP_WARN(
|
||||
getLogger(), "CbDefaultKeyboardBehavior %ld ev: %s", (long)(void *)this,
|
||||
smacc2::demangleSymbol(typeid(TEv).name()).c_str());
|
||||
auto event = new TEv();
|
||||
this->postEvent(event);
|
||||
}
|
||||
};
|
||||
} // namespace cl_keyboard
|
||||
@@ -1,269 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <smacc2/client_core_components/cp_topic_subscriber.hpp>
|
||||
#include <smacc2/introspection/introspection.hpp>
|
||||
#include <smacc2/smacc.hpp>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/posix/stream_descriptor.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <std_msgs/msg/u_int16.hpp>
|
||||
|
||||
namespace cl_keyboard::components
|
||||
{
|
||||
//----------------- KEYBOARD EVENT DEFINITIONS ----------------------------------------------
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressA : sc::event<EvKeyPressA<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressB : sc::event<EvKeyPressB<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressC : sc::event<EvKeyPressC<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressD : sc::event<EvKeyPressD<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressE : sc::event<EvKeyPressE<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressF : sc::event<EvKeyPressF<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressG : sc::event<EvKeyPressG<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressH : sc::event<EvKeyPressH<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressI : sc::event<EvKeyPressI<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressJ : sc::event<EvKeyPressJ<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressK : sc::event<EvKeyPressK<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressL : sc::event<EvKeyPressL<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressM : sc::event<EvKeyPressM<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressN : sc::event<EvKeyPressN<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressO : sc::event<EvKeyPressO<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressP : sc::event<EvKeyPressP<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressQ : sc::event<EvKeyPressQ<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressR : sc::event<EvKeyPressR<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressS : sc::event<EvKeyPressS<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressT : sc::event<EvKeyPressT<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressU : sc::event<EvKeyPressU<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressV : sc::event<EvKeyPressV<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressW : sc::event<EvKeyPressW<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressX : sc::event<EvKeyPressX<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressY : sc::event<EvKeyPressY<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TSource, typename TOrthogonal>
|
||||
struct EvKeyPressZ : sc::event<EvKeyPressZ<TSource, TOrthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
//------------------ KEYBOARD LISTENER COMPONENT ---------------------------------------------
|
||||
|
||||
class CpKeyboardListener1 : public smacc2::ISmaccComponent
|
||||
{
|
||||
public:
|
||||
CpKeyboardListener1() {}
|
||||
|
||||
virtual ~CpKeyboardListener1() {}
|
||||
|
||||
// Override the base class methods to call our setup
|
||||
template <typename TOrthogonal, typename TClient>
|
||||
void onComponentInitialization()
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "CpKeyboardListener1 initialization");
|
||||
smacc2::client_core_components::CpTopicSubscriber<std_msgs::msg::UInt16> * subscriber;
|
||||
this->requiresComponent(subscriber);
|
||||
|
||||
subscriber->onMessageReceived(&CpKeyboardListener1::onKeyboardMessage, this);
|
||||
|
||||
postEventKeyPress = [=](auto unicode_keychar)
|
||||
{
|
||||
char character = (char)unicode_keychar.data;
|
||||
RCLCPP_WARN(getLogger(), "detected keyboard: %c", character);
|
||||
|
||||
if (character == 'a')
|
||||
this->postKeyEvent<EvKeyPressA<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'b')
|
||||
this->postKeyEvent<EvKeyPressB<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'c')
|
||||
this->postKeyEvent<EvKeyPressC<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'd')
|
||||
this->postKeyEvent<EvKeyPressD<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'e')
|
||||
this->postKeyEvent<EvKeyPressE<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'f')
|
||||
this->postKeyEvent<EvKeyPressF<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'g')
|
||||
this->postKeyEvent<EvKeyPressG<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'h')
|
||||
this->postKeyEvent<EvKeyPressH<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'i')
|
||||
this->postKeyEvent<EvKeyPressI<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'j')
|
||||
this->postKeyEvent<EvKeyPressJ<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'k')
|
||||
this->postKeyEvent<EvKeyPressK<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'l')
|
||||
this->postKeyEvent<EvKeyPressL<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'm')
|
||||
this->postKeyEvent<EvKeyPressM<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'n')
|
||||
this->postKeyEvent<EvKeyPressN<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'o')
|
||||
this->postKeyEvent<EvKeyPressO<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'p')
|
||||
this->postKeyEvent<EvKeyPressP<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'q')
|
||||
this->postKeyEvent<EvKeyPressQ<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'r')
|
||||
this->postKeyEvent<EvKeyPressR<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 's')
|
||||
this->postKeyEvent<EvKeyPressS<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 't')
|
||||
this->postKeyEvent<EvKeyPressT<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'u')
|
||||
this->postKeyEvent<EvKeyPressU<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'v')
|
||||
this->postKeyEvent<EvKeyPressV<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'w')
|
||||
this->postKeyEvent<EvKeyPressW<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'x')
|
||||
this->postKeyEvent<EvKeyPressX<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'y')
|
||||
this->postKeyEvent<EvKeyPressY<CpKeyboardListener1, TOrthogonal>>();
|
||||
else if (character == 'z')
|
||||
this->postKeyEvent<EvKeyPressZ<CpKeyboardListener1, TOrthogonal>>();
|
||||
|
||||
OnKeyPress_(character);
|
||||
};
|
||||
}
|
||||
|
||||
// This signal is created to be used in client behaviors
|
||||
smacc2::SmaccSignal<void(char keypress)> OnKeyPress_;
|
||||
|
||||
// This is the signal subscription method for client behaviors and other components
|
||||
template <typename T>
|
||||
void OnKeyPress(void (T::*callback)(char keypress), T * object)
|
||||
{
|
||||
this->getStateMachine()->createSignalConnection(OnKeyPress_, callback, object);
|
||||
}
|
||||
|
||||
void onKeyboardMessage(const std_msgs::msg::UInt16 & unicode_keychar)
|
||||
{
|
||||
postEventKeyPress(unicode_keychar);
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename TEv>
|
||||
void postKeyEvent()
|
||||
{
|
||||
RCLCPP_WARN(
|
||||
getLogger(), "CpKeyboardListener1 ev: %s",
|
||||
smacc2::demangleSymbol(typeid(TEv).name()).c_str());
|
||||
this->postEvent<TEv>();
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void(std_msgs::msg::UInt16)> postEventKeyPress;
|
||||
};
|
||||
} // namespace cl_keyboard::components
|
||||
@@ -1,18 +0,0 @@
|
||||
<?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>cl_keyboard</name>
|
||||
<version>2.3.19</version>
|
||||
<description>The cl_keyboard package</description>
|
||||
<maintainer email="pablo@ibrobotics.com">Pablo Inigo Blasco</maintainer>
|
||||
<license>Apache-2.0</license>
|
||||
|
||||
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||
|
||||
<depend>smacc2</depend>
|
||||
<depend>std_msgs</depend>
|
||||
|
||||
<export>
|
||||
<build_type>ament_cmake</build_type>
|
||||
</export>
|
||||
</package>
|
||||
@@ -1,85 +0,0 @@
|
||||
#!/bin/env python3
|
||||
|
||||
# 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.
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# *
|
||||
# * Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
# *
|
||||
# ******************************************************************************************************************/
|
||||
|
||||
import sys
|
||||
import select
|
||||
import termios
|
||||
import tty
|
||||
|
||||
import rclpy
|
||||
from rclpy.node import Node
|
||||
|
||||
from std_msgs.msg import UInt16
|
||||
|
||||
settings = termios.tcgetattr(sys.stdin)
|
||||
|
||||
|
||||
def getKey():
|
||||
global settings
|
||||
tty.setraw(sys.stdin.fileno())
|
||||
select.select([sys.stdin], [], [], 0)
|
||||
key = sys.stdin.read(1)
|
||||
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
|
||||
return key
|
||||
|
||||
|
||||
class KeyboardPublisher(Node):
|
||||
def __init__(self):
|
||||
super().__init__("keyboard_node")
|
||||
self.pub = self.create_publisher(UInt16, "keyboard_unicode", 1)
|
||||
timer_period = 0.20 # seconds
|
||||
self.timer = self.create_timer(timer_period, self.timer_update)
|
||||
self.i = 0
|
||||
|
||||
def timer_update(self):
|
||||
try:
|
||||
key = getKey()
|
||||
# rospy.loginfo(type(key))
|
||||
msg = UInt16()
|
||||
msg.data = ord(key)
|
||||
|
||||
self.get_logger().info(f"key: {msg.data}")
|
||||
self.pub.publish(msg)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
finally:
|
||||
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
|
||||
|
||||
|
||||
def main(args=None):
|
||||
rclpy.init(args=args)
|
||||
|
||||
node = KeyboardPublisher()
|
||||
|
||||
rclpy.spin(node)
|
||||
|
||||
# Destroy the node explicitly
|
||||
# (optional - otherwise it will be done automatically
|
||||
# when the garbage collector destroys the node object)
|
||||
node.destroy_node()
|
||||
rclpy.shutdown()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,29 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_keyboard/cl_keyboard.hpp>
|
||||
|
||||
namespace cl_keyboard
|
||||
{
|
||||
// Declare the Client's default constructor.
|
||||
ClKeyboard::ClKeyboard() {}
|
||||
// Declare the Client's default destructor.
|
||||
ClKeyboard::~ClKeyboard() {}
|
||||
} // namespace cl_keyboard
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,122 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(cl_nav2z)
|
||||
|
||||
# Default to C++17
|
||||
if(NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(-Wall -Wextra -Wpedantic)
|
||||
endif()
|
||||
|
||||
# find dependencies
|
||||
find_package(ament_cmake REQUIRED)
|
||||
find_package(smacc2 REQUIRED)
|
||||
find_package(std_srvs REQUIRED)
|
||||
find_package(std_msgs REQUIRED)
|
||||
find_package(nav2_msgs REQUIRED)
|
||||
find_package(tf2 REQUIRED)
|
||||
find_package(tf2_ros REQUIRED)
|
||||
find_package(angles REQUIRED)
|
||||
find_package(yaml_cpp_vendor REQUIRED)
|
||||
find_package(tf2_geometry_msgs REQUIRED)
|
||||
find_package(pluginlib REQUIRED)
|
||||
find_package(bond REQUIRED)
|
||||
find_package(slam_toolbox REQUIRED)
|
||||
find_package(ament_index_cpp REQUIRED)
|
||||
find_package(rclcpp_action REQUIRED)
|
||||
find_package(nav2_util)
|
||||
|
||||
|
||||
set(dependencies
|
||||
smacc2
|
||||
std_srvs
|
||||
std_msgs
|
||||
nav2_msgs
|
||||
tf2
|
||||
tf2_ros
|
||||
angles
|
||||
yaml_cpp_vendor
|
||||
tf2_geometry_msgs
|
||||
bond
|
||||
slam_toolbox
|
||||
ament_index_cpp
|
||||
rclcpp_action
|
||||
nav2_util
|
||||
)
|
||||
|
||||
include_directories(include)
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED
|
||||
src/${PROJECT_NAME}/cl_nav2z.cpp
|
||||
src/${PROJECT_NAME}/common.cpp
|
||||
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_nav2z_client_behavior_base.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_absolute_rotate.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_rotate_look_at.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_navigate_backward.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_navigate_forward.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_abort_navigation.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_navigate_global_position.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_navigate_next_waypoint.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_navigate_next_waypoint_until_reached.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_navigate_named_waypoint.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_rotate.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_undo_path_backwards.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_wait_pose.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_wait_nav2_nodes.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_pause_slam.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_resume_slam.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_wait_transform.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_seek_waypoint.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_spiral_motion.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_track_path_odometry.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_track_path_slam.cpp
|
||||
|
||||
# COMPONENTS
|
||||
src/${PROJECT_NAME}/components/costmap_switch/cp_costmap_switch.cpp
|
||||
#src/${PROJECT_NAME}/components/odom_tracker/cp_odom_tracker_node.cpp
|
||||
|
||||
src/${PROJECT_NAME}/components/odom_tracker/cp_odom_tracker.cpp
|
||||
src/${PROJECT_NAME}/components/planner_switcher/cp_planner_switcher.cpp
|
||||
src/${PROJECT_NAME}/components/goal_checker_switcher/cp_goal_checker_switcher.cpp
|
||||
src/${PROJECT_NAME}/components/pose/cp_pose.cpp
|
||||
src/${PROJECT_NAME}/components/waypoints_navigator/cp_waypoints_event_dispatcher.cpp
|
||||
src/${PROJECT_NAME}/components/waypoints_navigator/cp_waypoints_navigator.cpp
|
||||
src/${PROJECT_NAME}/components/waypoints_navigator/cp_waypoints_visualizer.cpp
|
||||
src/${PROJECT_NAME}/components/amcl/cp_amcl.cpp
|
||||
src/${PROJECT_NAME}/components/slam_toolbox/cp_slam_toolbox.cpp
|
||||
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_active_stop.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_load_waypoints_file.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_navigate_next_waypoint_free.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_position_control_free_space.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_pure_spinning.cpp
|
||||
src/${PROJECT_NAME}/client_behaviors/cb_save_slam_map.cpp
|
||||
)
|
||||
|
||||
ament_target_dependencies(${PROJECT_NAME}
|
||||
${dependencies})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME})
|
||||
|
||||
ament_export_include_directories(include)
|
||||
ament_export_libraries(${PROJECT_NAME})
|
||||
ament_export_dependencies(${dependencies})
|
||||
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
ARCHIVE DESTINATION lib
|
||||
LIBRARY DESTINATION lib
|
||||
RUNTIME DESTINATION bin
|
||||
)
|
||||
|
||||
install(DIRECTORY include/
|
||||
DESTINATION include/
|
||||
)
|
||||
|
||||
install(FILES scripts/lidar_completion.py
|
||||
DESTINATION lib/${PROJECT_NAME}/
|
||||
)
|
||||
|
||||
ament_package()
|
||||
@@ -1,82 +0,0 @@
|
||||
// Copyright 2024 Robosoft 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/components/nav2_action_interface/cp_nav2_action_interface.hpp>
|
||||
#include <nav2_msgs/action/navigate_to_pose.hpp>
|
||||
#include <smacc2/client_core_components/cp_action_client.hpp>
|
||||
#include <smacc2/smacc.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
|
||||
// Pure component-based ClNav2Z - No legacy support
|
||||
// Follows cl_keyboard pattern: orchestrator only, behaviors use requiresComponent()
|
||||
class ClNav2Z : public smacc2::ISmaccClient
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
ClNav2Z(std::string actionServerName = "/navigate_to_pose") : actionServerName_(actionServerName)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~ClNav2Z() = default;
|
||||
|
||||
// Component composition during orthogonal initialization
|
||||
template <typename TOrthogonal, typename TClient>
|
||||
void onComponentInitialization()
|
||||
{
|
||||
// Create core action client component
|
||||
auto actionClient = this->createComponent<
|
||||
smacc2::client_core_components::CpActionClient<nav2_msgs::action::NavigateToPose>,
|
||||
TOrthogonal, ClNav2Z>();
|
||||
actionClient->actionServerName = actionServerName_;
|
||||
|
||||
// Create nav2-specific interface component (requires actionClient)
|
||||
this->createComponent<components::CpNav2ActionInterface, TOrthogonal, ClNav2Z>();
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
this->getLogger(), "[ClNav2Z] Components created for action server: " << actionServerName_);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string actionServerName_;
|
||||
|
||||
// ✅ PURE ORCHESTRATOR PATTERN - ALL LEGACY METHODS REMOVED:
|
||||
//
|
||||
// ❌ REMOVED: sendGoal() methods - use CpNav2ActionInterface::sendGoal()
|
||||
// ❌ REMOVED: signal connection proxy methods - use CpNav2ActionInterface::onNavigationSucceeded()
|
||||
// ❌ REMOVED: signal getter methods - signals owned by components
|
||||
// ❌ REMOVED: component accessor methods - use requiresComponent()
|
||||
// ❌ REMOVED: convenience wrapper methods - use component APIs directly
|
||||
// ❌ REMOVED: type aliases - use component types directly
|
||||
//
|
||||
// ✅ NEW BEHAVIOR PATTERN:
|
||||
// class CbNavigateForward : public CbNav2ZClientBehaviorBase {
|
||||
// void onEntry() override {
|
||||
// CpNav2ActionInterface* navInterface;
|
||||
// this->requiresComponent(navInterface);
|
||||
// navInterface->onNavigationSucceeded(&CbNavigateForward::onSuccess, this);
|
||||
// Goal goal = createForwardGoal();
|
||||
// navInterface->sendGoal(goal);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// ✅ SMACC2 SIGNAL COMPLIANCE: All signal connections use createSignalConnection()
|
||||
// ✅ FRAMEWORK CONSISTENCY: Matches cl_keyboard pure component pattern
|
||||
// ✅ CLEAN SEPARATION: Client orchestrates, components implement, behaviors consume
|
||||
};
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright 2024 Robosoft 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.
|
||||
|
||||
#pragma once
|
||||
#include <nav2_msgs/action/navigate_to_pose.hpp>
|
||||
#include <smacc2/client_bases/smacc_action_client_base.hpp>
|
||||
#include <smacc2/smacc.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
// Declare Client class, inherit from SmaccActionClientBase template with default action argument.
|
||||
class ClNav2Z
|
||||
: public smacc2::client_bases::SmaccActionClientBase<nav2_msgs::action::NavigateToPose>
|
||||
{
|
||||
public:
|
||||
// Bring the SmaccActionClientBase types into the current scope.
|
||||
using smacc2::client_bases::SmaccActionClientBase<nav2_msgs::action::NavigateToPose>::GoalHandle;
|
||||
using smacc2::client_bases::SmaccActionClientBase<
|
||||
nav2_msgs::action::NavigateToPose>::ResultCallback;
|
||||
|
||||
// Define "SmaccNavigateResultSignal" as a SmaccSignal that points to the WrappedResult type of SmaccActionClientBase.
|
||||
typedef smacc2::SmaccSignal<void(const WrappedResult &)> SmaccNavigateResultSignal;
|
||||
|
||||
// Declare Client class constructor with string set to the right ROS action.
|
||||
ClNav2Z(std::string navigateToPoseAction = "/navigate_to_pose");
|
||||
|
||||
// Declare Client class destructor.
|
||||
virtual ~ClNav2Z();
|
||||
};
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,45 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
// rotation behavior
|
||||
#include <cl_nav2z/client_behaviors/cb_absolute_rotate.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_rotate.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_rotate_look_at.hpp>
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_backwards.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_forward.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_global_position.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_retry_behavior.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_undo_path_backwards.hpp>
|
||||
|
||||
// nav2 synchronization behaviors
|
||||
#include <cl_nav2z/client_behaviors/cb_wait_nav2_nodes.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_wait_pose.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_wait_transform.hpp>
|
||||
|
||||
// others
|
||||
#include <cl_nav2z/client_behaviors/cb_abort_navigation.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_stop_navigation.hpp>
|
||||
|
||||
// waypoints behaviors
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_named_waypoint.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_next_waypoint.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_next_waypoint_until_reached.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_seek_waypoint.hpp>
|
||||
|
||||
// slam behaviors
|
||||
#include <cl_nav2z/client_behaviors/cb_pause_slam.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_resume_slam.hpp>
|
||||
@@ -1,49 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <tf2_ros/buffer.h>
|
||||
|
||||
#include <cl_nav2z/components/nav2_action_interface/cp_nav2_action_interface.hpp>
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
#include "cb_navigate_global_position.hpp"
|
||||
#include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbAbortNavigation : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
public:
|
||||
CbAbortNavigation();
|
||||
|
||||
template <typename TOrthogonal, typename TSourceObject>
|
||||
void onStateOrthogonalAllocation()
|
||||
{
|
||||
this->requiresComponent(nav2ActionInterface_);
|
||||
smacc2::SmaccAsyncClientBehavior::onStateOrthogonalAllocation<TOrthogonal, TSourceObject>();
|
||||
}
|
||||
|
||||
void onEntry() override;
|
||||
void onExit() override;
|
||||
|
||||
private:
|
||||
components::CpNav2ActionInterface * nav2ActionInterface_ = nullptr;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,51 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <tf2_ros/buffer.h>
|
||||
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
#include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbAbsoluteRotate : public CbNav2ZClientBehaviorBase
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<tf2_ros::Buffer> listener;
|
||||
|
||||
float absoluteGoalAngleDegree;
|
||||
std::optional<float> yawGoalTolerance;
|
||||
std::optional<float> maxVelTheta; // if not defined, default parameter server
|
||||
std::optional<SpinningPlanner> spinningPlanner;
|
||||
|
||||
CbAbsoluteRotate();
|
||||
CbAbsoluteRotate(float absoluteGoalAngleDegree, float yawGoalTolerance = -1);
|
||||
|
||||
void onEntry() override;
|
||||
void onExit() override;
|
||||
|
||||
private:
|
||||
void updateTemporalBehaviorParameters(bool undo);
|
||||
float oldYawTolerance;
|
||||
float oldMaxVelTheta;
|
||||
float oldMinVelTheta;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,40 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <geometry_msgs/msg/twist.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
struct CbActiveStop : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
private:
|
||||
rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr cmd_vel_pub_;
|
||||
|
||||
public:
|
||||
CbActiveStop();
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,46 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator_base.hpp>
|
||||
#include <smacc2/smacc_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
struct CbLoadWaypointsFile : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
public:
|
||||
CbLoadWaypointsFile(std::string filepath);
|
||||
|
||||
CbLoadWaypointsFile(std::string parameter_name, std::string packagenamespace);
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
|
||||
std::optional<std::string> filepath_;
|
||||
|
||||
std::optional<std::string> parameterName_;
|
||||
std::optional<std::string> packageNamespace_;
|
||||
|
||||
cl_nav2z::CpWaypointNavigatorBase * waypointsNavigator_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,148 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/components/nav2_action_interface/cp_nav2_action_interface.hpp>
|
||||
#include <cl_nav2z/components/planner_switcher/cp_planner_switcher.hpp>
|
||||
#include <smacc2/client_core_components/cp_action_client.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbNav2ZClientBehaviorBase : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
public:
|
||||
virtual ~CbNav2ZClientBehaviorBase();
|
||||
|
||||
template <typename TOrthogonal, typename TSourceObject>
|
||||
void onStateOrthogonalAllocation()
|
||||
{
|
||||
// NEW: Pure component-based approach - no client dependencies
|
||||
this->requiresComponent(nav2ActionInterface_);
|
||||
this->requiresComponent(actionClient_);
|
||||
|
||||
smacc2::SmaccAsyncClientBehavior::onStateOrthogonalAllocation<TOrthogonal, TSourceObject>();
|
||||
}
|
||||
|
||||
// LEGACY COMPATIBILITY: For third-party code that still calls the old method
|
||||
template <typename TOrthogonal, typename TSourceObject>
|
||||
[[deprecated(
|
||||
"Use onStateOrthogonalAllocation instead. This method exists only for third-party "
|
||||
"compatibility.")]] void
|
||||
onOrthogonalAllocation()
|
||||
{
|
||||
onStateOrthogonalAllocation<TOrthogonal, TSourceObject>();
|
||||
}
|
||||
|
||||
protected:
|
||||
// NEW: Component-based API - uses components directly
|
||||
void sendGoal(nav2_msgs::action::NavigateToPose::Goal & goal)
|
||||
{
|
||||
if (nav2ActionInterface_)
|
||||
{
|
||||
nav2ActionInterface_->sendGoal(goal);
|
||||
}
|
||||
}
|
||||
|
||||
void cancelGoal()
|
||||
{
|
||||
if (nav2ActionInterface_)
|
||||
{
|
||||
nav2ActionInterface_->cancelNavigation();
|
||||
}
|
||||
}
|
||||
|
||||
// Component-based signal connections
|
||||
template <typename T>
|
||||
boost::signals2::connection onNavigationSucceeded(
|
||||
void (T::*callback)(const components::CpNav2ActionInterface::WrappedResult &), T * object)
|
||||
{
|
||||
if (nav2ActionInterface_)
|
||||
{
|
||||
return nav2ActionInterface_->onNavigationSucceeded(callback, object);
|
||||
}
|
||||
return boost::signals2::connection();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
boost::signals2::connection onNavigationAborted(
|
||||
void (T::*callback)(const components::CpNav2ActionInterface::WrappedResult &), T * object)
|
||||
{
|
||||
if (nav2ActionInterface_)
|
||||
{
|
||||
return nav2ActionInterface_->onNavigationAborted(callback, object);
|
||||
}
|
||||
return boost::signals2::connection();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
boost::signals2::connection onNavigationCancelled(
|
||||
void (T::*callback)(const components::CpNav2ActionInterface::WrappedResult &), T * object)
|
||||
{
|
||||
if (nav2ActionInterface_)
|
||||
{
|
||||
return nav2ActionInterface_->onNavigationCancelled(callback, object);
|
||||
}
|
||||
return boost::signals2::connection();
|
||||
}
|
||||
|
||||
// Helper method to get the client for accessing other components
|
||||
template <typename ComponentType>
|
||||
ComponentType * getComponent()
|
||||
{
|
||||
ClNav2Z * client = nullptr;
|
||||
this->requiresClient(client);
|
||||
if (client)
|
||||
{
|
||||
return client->getComponent<ComponentType>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// NEW: Component references instead of client reference
|
||||
components::CpNav2ActionInterface * nav2ActionInterface_ = nullptr;
|
||||
smacc2::client_core_components::CpActionClient<nav2_msgs::action::NavigateToPose> *
|
||||
actionClient_ = nullptr;
|
||||
|
||||
// Common legacy member for result tracking
|
||||
rclcpp_action::ResultCode navigationResult_;
|
||||
|
||||
// REMOVED: All legacy client-based members
|
||||
// ❌ cl_nav2z::ClNav2Z * nav2zClient_
|
||||
// ❌ cl_nav2z::ClNav2Z::SmaccNavigateResultSignal::SharedPtr navigationCallback_
|
||||
// ❌ rclcpp_action::ResultCode navigationResult_
|
||||
// ❌ goalHandleFuture_
|
||||
|
||||
// Virtual methods for derived classes - now use component types
|
||||
virtual void onNavigationResult(const components::CpNav2ActionInterface::WrappedResult &) {}
|
||||
virtual void onNavigationActionSuccess(const components::CpNav2ActionInterface::WrappedResult &)
|
||||
{
|
||||
}
|
||||
virtual void onNavigationActionAbort(const components::CpNav2ActionInterface::WrappedResult &) {}
|
||||
};
|
||||
|
||||
enum class SpinningPlanner
|
||||
{
|
||||
Default,
|
||||
PureSpinning,
|
||||
Forward
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,50 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator.hpp>
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
// It sends the mobile base some distance backwards
|
||||
class CbNavigateBackwards : public CbNav2ZClientBehaviorBase
|
||||
{
|
||||
public:
|
||||
float backwardDistance;
|
||||
|
||||
// just a stub to show how to use parameterless constructor
|
||||
std::optional<float> backwardSpeed;
|
||||
|
||||
std::optional<std::string> goalChecker_;
|
||||
|
||||
cl_nav2z::odom_tracker::CpOdomTracker * odomTracker_;
|
||||
|
||||
CbNavigateBackwards(float backwardDistanceMeters);
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,79 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <tf2/utils.h>
|
||||
#include <tf2_ros/buffer.h>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <geometry_msgs/msg/pose_stamped.hpp>
|
||||
#include <optional>
|
||||
#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
|
||||
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
struct CbNavigateForwardOptions
|
||||
{
|
||||
// just a stub to show how to use parameterless constructor
|
||||
std::optional<float> forwardSpeed;
|
||||
|
||||
// this may be useful in the case you want to do a straight line with some known direction
|
||||
// and the robot may not have that specific initial orientation at that moment.
|
||||
// If it is not set, the orientation of the straight line is the orientation of the initial (current) state.
|
||||
std::optional<geometry_msgs::msg::Quaternion> forceInitialOrientation;
|
||||
|
||||
// the name of the goal checker selected in the navigation2 stack
|
||||
std::optional<std::string> goalChecker_;
|
||||
};
|
||||
|
||||
// Performs a relative motion forwards
|
||||
class CbNavigateForward : public CbNav2ZClientBehaviorBase
|
||||
{
|
||||
public:
|
||||
CbNavigateForwardOptions options;
|
||||
|
||||
CbNavigateForward();
|
||||
|
||||
CbNavigateForward(float forwardDistance);
|
||||
|
||||
// alternative forward motion using an absolute goal position instead a relative linear distance.
|
||||
// It is specially to retry a previous relative incorrect motions based on distance.
|
||||
// The developer user is in charge of setting a valid goal position that is located forward
|
||||
// from the current position and orientation.
|
||||
CbNavigateForward(geometry_msgs::msg::PoseStamped goalPosition);
|
||||
|
||||
virtual ~CbNavigateForward();
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
|
||||
void setForwardDistance(float distance_meters);
|
||||
|
||||
protected:
|
||||
// required component
|
||||
odom_tracker::CpOdomTracker * odomTracker_;
|
||||
|
||||
std::optional<geometry_msgs::msg::PoseStamped> goalPose_;
|
||||
|
||||
std::optional<float> forwardDistance_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,69 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <geometry_msgs/msg/point.hpp>
|
||||
#include <geometry_msgs/msg/pose.hpp>
|
||||
#include <nav2_msgs/action/navigate_to_pose.hpp>
|
||||
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
struct CbNavigateGlobalPositionOptions
|
||||
{
|
||||
// std::optional<float> yawTolerance;
|
||||
// std::optional<float> yawToleranceX;
|
||||
// std::optional<float> yawToleranceY;
|
||||
|
||||
std::optional<std::string> goalChecker_;
|
||||
|
||||
std::optional<std::string> controllerName_;
|
||||
};
|
||||
|
||||
class CbNavigateGlobalPosition : public CbNav2ZClientBehaviorBase
|
||||
{
|
||||
public:
|
||||
float goalYaw;
|
||||
|
||||
CbNavigateGlobalPositionOptions options;
|
||||
geometry_msgs::msg::Point goalPosition;
|
||||
|
||||
CbNavigateGlobalPosition();
|
||||
|
||||
CbNavigateGlobalPosition(
|
||||
float x, float y, float yaw /*radians*/,
|
||||
std::optional<CbNavigateGlobalPositionOptions> options = std::nullopt);
|
||||
|
||||
void setGoal(const geometry_msgs::msg::Pose & pose);
|
||||
|
||||
virtual void onEntry() override;
|
||||
|
||||
// This is the substate destructor. This code will be executed when the
|
||||
// workflow exits from this substate (that is according to statechart the moment when this object is destroyed)
|
||||
void onExit() override;
|
||||
|
||||
// auxiliary function that defines the motion that is requested to the navigation2 action server
|
||||
void execute();
|
||||
|
||||
private:
|
||||
void readStartPoseFromParameterServer(nav2_msgs::action::NavigateToPose::Goal & goal);
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,45 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator.hpp>
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
#include "cb_navigate_next_waypoint.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbNavigateNamedWaypoint : public CbNavigateNextWaypoint
|
||||
{
|
||||
public:
|
||||
CbNavigateNamedWaypoint(
|
||||
std::string waypointname, std::optional<NavigateNextWaypointOptions> options = std::nullopt);
|
||||
|
||||
virtual ~CbNavigateNamedWaypoint();
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
|
||||
CpWaypointNavigator * waypointsNavigator_;
|
||||
|
||||
std::string waypointname_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,45 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator.hpp>
|
||||
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbNavigateNextWaypoint : public CbNav2ZClientBehaviorBase
|
||||
{
|
||||
public:
|
||||
CbNavigateNextWaypoint(std::optional<NavigateNextWaypointOptions> options = std::nullopt);
|
||||
|
||||
virtual ~CbNavigateNextWaypoint();
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
|
||||
protected:
|
||||
CpWaypointNavigator * waypointsNavigator_;
|
||||
|
||||
NavigateNextWaypointOptions options_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,44 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
#include <cl_nav2z/client_behaviors/cb_position_control_free_space.hpp>
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator_base.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
|
||||
class CbNavigateNextWaypointFree : public cl_nav2z::CbPositionControlFreeSpace
|
||||
{
|
||||
public:
|
||||
CbNavigateNextWaypointFree();
|
||||
|
||||
virtual ~CbNavigateNextWaypointFree();
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onSucessCallback();
|
||||
|
||||
void onExit() override;
|
||||
|
||||
protected:
|
||||
cl_nav2z::CpWaypointNavigatorBase * waypointsNavigator_;
|
||||
};
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,100 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/components/nav2_action_interface/cp_nav2_action_interface.hpp>
|
||||
#include "cb_navigate_next_waypoint.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
template <typename AsyncCB, typename Orthogonal>
|
||||
struct EvGoalWaypointReached : sc::event<EvGoalWaypointReached<AsyncCB, Orthogonal>>
|
||||
{
|
||||
};
|
||||
|
||||
class CbNavigateNextWaypointUntilReached : public CbNavigateNextWaypoint
|
||||
{
|
||||
public:
|
||||
CbNavigateNextWaypointUntilReached(
|
||||
std::string goalWaypointName,
|
||||
std::optional<NavigateNextWaypointOptions> options = std::nullopt);
|
||||
|
||||
virtual ~CbNavigateNextWaypointUntilReached();
|
||||
|
||||
template <typename TOrthogonal, typename TSourceObject>
|
||||
void onStateOrthogonalAllocation()
|
||||
{
|
||||
CbNavigateNextWaypoint::onStateOrthogonalAllocation<TOrthogonal, TSourceObject>();
|
||||
|
||||
postEvGoalWaypointReached_ = [this]()
|
||||
{ this->postEvent<EvGoalWaypointReached<TSourceObject, TOrthogonal>>(); };
|
||||
}
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
|
||||
void onNavigationActionSuccess(
|
||||
const components::CpNav2ActionInterface::WrappedResult & r) override
|
||||
{
|
||||
// if (!isOwnActionResponse(r))
|
||||
// {
|
||||
// RCLCPP_WARN(
|
||||
// getLogger(), "[%s] Propagating success event skipped. Action response is not ours.",
|
||||
// getName().c_str());
|
||||
// return;
|
||||
// }
|
||||
|
||||
navigationResult_ = r.code;
|
||||
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[%s] Propagating success event from action server", getName().c_str());
|
||||
|
||||
this->requiresComponent(waypointsNavigator_);
|
||||
|
||||
auto current_waypoint_name = waypointsNavigator_->getCurrentWaypointName();
|
||||
|
||||
if (current_waypoint_name == this->goalWaypointName_)
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(),
|
||||
"[CbNavigateNextWaypointUntilReached] GoalReached current iteration waypoint i: %ld with "
|
||||
"name '%s'",
|
||||
waypointsNavigator_->getCurrentWaypointIndex(), current_waypoint_name->c_str());
|
||||
|
||||
this->postEvGoalWaypointReached_();
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(),
|
||||
"[CbNavigateNextWaypointUntilReached] goal:'%s' current:'%s'. keep navigating.",
|
||||
goalWaypointName_.c_str(), current_waypoint_name->c_str());
|
||||
}
|
||||
|
||||
this->postSuccessEvent();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string goalWaypointName_;
|
||||
|
||||
std::function<void()> postEvGoalWaypointReached_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,37 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/components/slam_toolbox/cp_slam_toolbox.hpp>
|
||||
#include <slam_toolbox/srv/pause.hpp>
|
||||
#include <smacc2/client_behaviors/cb_call_service.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbPauseSlam : public smacc2::client_behaviors::CbServiceCall<slam_toolbox::srv::Pause>
|
||||
{
|
||||
public:
|
||||
CbPauseSlam(std::string serviceName = "/slam_toolbox/pause_new_measurements");
|
||||
void onEntry() override;
|
||||
|
||||
protected:
|
||||
CpSlamToolbox * slam_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,64 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
#include <geometry_msgs/msg/twist.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
struct CbPositionControlFreeSpace : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
private:
|
||||
double targetYaw_;
|
||||
bool goalReached_;
|
||||
double k_betta_;
|
||||
double max_angular_yaw_speed_;
|
||||
|
||||
double prev_error_linear_ = 0.0;
|
||||
double prev_error_angular_ = 0.0;
|
||||
double integral_linear_ = 0.0;
|
||||
double integral_angular_ = 0.0;
|
||||
|
||||
// Limit the maximum linear velocity and angular velocity to avoid sudden
|
||||
// movements
|
||||
double max_linear_velocity = 1.0; // Adjust this value according to your needs
|
||||
double max_angular_velocity = 1.0; // Adjust this value according to your needs
|
||||
|
||||
rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr cmd_vel_pub_;
|
||||
|
||||
public:
|
||||
double yaw_goal_tolerance_rads_ = 0.1;
|
||||
|
||||
double threshold_distance_ = 3.0;
|
||||
|
||||
geometry_msgs::msg::Pose target_pose_;
|
||||
|
||||
CbPositionControlFreeSpace();
|
||||
|
||||
void updateParameters();
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,48 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <geometry_msgs/msg/twist.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
struct CbPureSpinning : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
private:
|
||||
double targetYaw__rads;
|
||||
bool goalReached_;
|
||||
double k_betta_;
|
||||
double max_angular_yaw_speed_;
|
||||
|
||||
rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr cmd_vel_pub_;
|
||||
|
||||
public:
|
||||
double yaw_goal_tolerance_rads_;
|
||||
|
||||
CbPureSpinning(double targetYaw_rads, double max_angular_yaw_speed = 0.5);
|
||||
void updateParameters();
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,37 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <slam_toolbox/srv/pause.hpp>
|
||||
#include "cl_nav2z/components/slam_toolbox/cp_slam_toolbox.hpp"
|
||||
#include "smacc2/client_behaviors/cb_call_service.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbResumeSlam : public smacc2::client_behaviors::CbServiceCall<slam_toolbox::srv::Pause>
|
||||
{
|
||||
public:
|
||||
CbResumeSlam(std::string serviceName = "/slam_toolbox/pause_new_measurements");
|
||||
void onEntry() override;
|
||||
|
||||
protected:
|
||||
CpSlamToolbox * slam_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,51 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <optional>
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
using odom_tracker::CpOdomTracker;
|
||||
|
||||
template <typename TCbRelativeMotion>
|
||||
class CbRetry : public TCbRelativeMotion
|
||||
{
|
||||
public:
|
||||
CbRetry() {}
|
||||
void onEntry() override
|
||||
{
|
||||
odomTracker_ = this->nav2zClient_->template getComponent<CpOdomTracker>();
|
||||
auto goal = odomTracker_->getCurrentMotionGoal();
|
||||
|
||||
if (goal)
|
||||
{
|
||||
this->goalPose_ = *goal;
|
||||
}
|
||||
|
||||
TCbRelativeMotion::onEntry();
|
||||
}
|
||||
|
||||
private:
|
||||
CpOdomTracker * odomTracker_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,47 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <tf2_ros/buffer.h>
|
||||
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbRotate : public CbNav2ZClientBehaviorBase
|
||||
{
|
||||
public:
|
||||
float rotateDegree;
|
||||
|
||||
std::optional<std::string> goalChecker_;
|
||||
|
||||
std::optional<cl_nav2z::SpinningPlanner> spinningPlanner;
|
||||
|
||||
CbRotate(float rotate_degree);
|
||||
|
||||
CbRotate(float rotate_degree, cl_nav2z::SpinningPlanner spinning_planner);
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
private:
|
||||
//TODO: replace this with the Pose Component in the same way it is done in the CbAbsoluteRotateBehavior
|
||||
std::shared_ptr<tf2_ros::Buffer> listener;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,43 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <tf2_ros/buffer.h>
|
||||
|
||||
#include <geometry_msgs/msg/pose_stamped.hpp>
|
||||
#include "cb_absolute_rotate.hpp"
|
||||
#include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbRotateLookAt : public CbAbsoluteRotate
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<tf2_ros::Buffer> listener;
|
||||
|
||||
std::optional<geometry_msgs::msg::PoseStamped> lookAtPose_;
|
||||
|
||||
CbRotateLookAt();
|
||||
CbRotateLookAt(const geometry_msgs::msg::PoseStamped & lookAtPose);
|
||||
|
||||
void onEntry() override;
|
||||
// void onExit() override;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,46 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <nav2_msgs/srv/save_map.hpp>
|
||||
#include <slam_toolbox/srv/save_map.hpp>
|
||||
#include <smacc2/client_behaviors/cb_call_service.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
template <typename TService>
|
||||
using CbServiceCall = smacc2::client_behaviors::CbServiceCall<TService>;
|
||||
|
||||
struct CbSaveSlamMap : public CbServiceCall<nav2_msgs::srv::SaveMap>
|
||||
{
|
||||
public:
|
||||
CbSaveSlamMap();
|
||||
// void onEntry() override {}
|
||||
|
||||
void onExit() override;
|
||||
|
||||
std::shared_ptr<nav2_msgs::srv::SaveMap::Request> getRequest(
|
||||
/*slam_toolbox::srv::SaveMap_Request_<std::allocator<void> >::_name_type saved_map_name*/);
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,48 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator.hpp>
|
||||
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbSeekWaypoint : public smacc2::SmaccClientBehavior
|
||||
{
|
||||
public:
|
||||
CbSeekWaypoint(std::string skip_until_name);
|
||||
|
||||
virtual ~CbSeekWaypoint();
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
|
||||
CpWaypointNavigator * waypointsNavigator_;
|
||||
|
||||
NavigateNextWaypointOptions options_;
|
||||
|
||||
private:
|
||||
std::optional<int> count_;
|
||||
std::optional<std::string> seekWaypointName_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,61 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
|
||||
// client behaviors typically accept parameters to be customized in the state it is being used
|
||||
// we follow this pattern, with a basic structure with optional fields, that make thee initialization of the behavior more readable in the
|
||||
// state initialization. It also avoid an explosion of constructors for each variation of the parameters.
|
||||
struct CbSpiralMotionOptions
|
||||
{
|
||||
std::optional<float> linearVelocity = 0.0f;
|
||||
std::optional<float> maxLinearVelocity = 0.5f;
|
||||
std::optional<float> initialAngularVelocity = 1.5f;
|
||||
std::optional<rclcpp::Duration> spiralMotionDuration = rclcpp::Duration::from_seconds(40);
|
||||
std::optional<float> finalRadius = 20.0f; //meters
|
||||
};
|
||||
|
||||
/* a basic client behavior has a simple onEntry and onExit functions. When we enter into a stae we call onEntry.
|
||||
This client behavior is asynchronous so that onEntry returns immediately, it opens a thread to run the behavior*/
|
||||
struct CbSpiralMotion : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
public:
|
||||
//
|
||||
// constructor, we accept an empty usag of the behavior, but also any other combination of parameters
|
||||
CbSpiralMotion(std::optional<CbSpiralMotionOptions> options = std::nullopt);
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
|
||||
private:
|
||||
// this client behavior has its own temporal publisher to control the robot
|
||||
rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr cmdVelPub_;
|
||||
|
||||
// we store the options that customize the behavior
|
||||
CbSpiralMotionOptions options_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,38 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <tf2_ros/buffer.h>
|
||||
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
#include "cb_navigate_global_position.hpp"
|
||||
#include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbStopNavigation : public CbNavigateGlobalPosition
|
||||
{
|
||||
public:
|
||||
CbStopNavigation();
|
||||
|
||||
void onEntry() override;
|
||||
void onExit() override;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,38 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
struct CbTrackPathOdometry : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
private:
|
||||
public:
|
||||
CbTrackPathOdometry();
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,38 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
struct CbTrackPathSLAM : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
private:
|
||||
public:
|
||||
CbTrackPathSLAM();
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,56 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <tf2_ros/buffer.h>
|
||||
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include "cb_nav2z_client_behavior_base.hpp"
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
using ::cl_nav2z::odom_tracker::CpOdomTracker;
|
||||
|
||||
struct CbUndoPathBackwardsOptions
|
||||
{
|
||||
// the name of the goal checker selected in the navigation2 stack
|
||||
std::optional<std::string> goalCheckerId_;
|
||||
|
||||
// the name of the goal checker selected in the navigation2 stack
|
||||
std::optional<std::string> undoControllerName_;
|
||||
};
|
||||
|
||||
class CbUndoPathBackwards : public CbNav2ZClientBehaviorBase
|
||||
{
|
||||
public:
|
||||
CbUndoPathBackwards(std::optional<CbUndoPathBackwardsOptions> options = std::nullopt);
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
void onExit() override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<tf2_ros::Buffer> listener;
|
||||
|
||||
CpOdomTracker * odomTracker;
|
||||
|
||||
std::optional<CbUndoPathBackwardsOptions> options_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,67 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <tf2_ros/buffer.h>
|
||||
|
||||
#include <bond/msg/status.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
enum class Nav2Nodes
|
||||
{
|
||||
PlannerServer,
|
||||
ControllerServer,
|
||||
RecoveriesServer,
|
||||
BtNavigator,
|
||||
MapServer,
|
||||
None
|
||||
};
|
||||
|
||||
std::string toString(Nav2Nodes value);
|
||||
|
||||
Nav2Nodes fromString(std::string str);
|
||||
|
||||
class CbWaitNav2Nodes : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
public:
|
||||
CbWaitNav2Nodes(
|
||||
std::string topicname,
|
||||
std::vector<Nav2Nodes> waitNodes = {
|
||||
Nav2Nodes::PlannerServer, Nav2Nodes::ControllerServer, Nav2Nodes::BtNavigator});
|
||||
|
||||
CbWaitNav2Nodes(
|
||||
std::vector<Nav2Nodes> waitNodes = {
|
||||
Nav2Nodes::PlannerServer, Nav2Nodes::ControllerServer, Nav2Nodes::BtNavigator});
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
private:
|
||||
void onMessageReceived(const bond::msg::Status & msg);
|
||||
|
||||
std::string topicname_;
|
||||
|
||||
rclcpp::Subscription<bond::msg::Status>::SharedPtr sub_;
|
||||
std::map<Nav2Nodes, bool> receivedAliveMsg_;
|
||||
|
||||
std::vector<Nav2Nodes> waitNodes_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,59 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
// waits a robot pose message. Usually used for the startup synchronization.
|
||||
enum class WaitPoseStandardReferenceFrame
|
||||
{
|
||||
Map,
|
||||
Odometry
|
||||
};
|
||||
|
||||
// Waits a new pose using the Pose Component
|
||||
// the specific pose to wait is configured in that component
|
||||
class CbWaitPose : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
public:
|
||||
// waits a new pose update of the Pose Component
|
||||
CbWaitPose();
|
||||
|
||||
// waits a new pose update of the Pose Component in some reference frame (if there is no connection it will wait)
|
||||
CbWaitPose(WaitPoseStandardReferenceFrame frame);
|
||||
|
||||
virtual ~CbWaitPose();
|
||||
|
||||
template <typename TOrthogonal, typename TSourceObject>
|
||||
void onStateOrthogonalAllocation()
|
||||
{
|
||||
this->requiresClient(nav2zClient_);
|
||||
smacc2::SmaccAsyncClientBehavior::onStateOrthogonalAllocation<TOrthogonal, TSourceObject>();
|
||||
}
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
protected:
|
||||
cl_nav2z::ClNav2Z * nav2zClient_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,60 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
|
||||
|
||||
#include <tf2/transform_datatypes.h>
|
||||
#include <tf2/utils.h>
|
||||
#include <tf2_ros/buffer.h>
|
||||
#include <tf2_ros/transform_listener.h>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CbWaitTransform : public smacc2::SmaccAsyncClientBehavior
|
||||
{
|
||||
public:
|
||||
CbWaitTransform(std::string targetFrame, std::string referenceFrame, rclcpp::Duration timeout);
|
||||
|
||||
virtual ~CbWaitTransform();
|
||||
|
||||
template <typename TOrthogonal, typename TSourceObject>
|
||||
void onStateOrthogonalAllocation()
|
||||
{
|
||||
smacc2::SmaccAsyncClientBehavior::onStateOrthogonalAllocation<TOrthogonal, TSourceObject>();
|
||||
}
|
||||
|
||||
void onEntry() override;
|
||||
|
||||
protected:
|
||||
// shared static listener
|
||||
std::shared_ptr<tf2_ros::Buffer> tfBuffer_;
|
||||
std::shared_ptr<tf2_ros::TransformListener> tfListener_;
|
||||
|
||||
std::string targetFrame_;
|
||||
std::string referenceFrame_;
|
||||
rclcpp::Duration timeout_;
|
||||
|
||||
std::optional<tf2::Stamped<tf2::Transform>> result_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,34 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <tf2/transform_datatypes.h>
|
||||
#include <builtin_interfaces/msg/time.hpp>
|
||||
#include <geometry_msgs/msg/point.hpp>
|
||||
#include <geometry_msgs/msg/pose.hpp>
|
||||
#include <geometry_msgs/msg/pose_stamped.hpp>
|
||||
#include <geometry_msgs/msg/quaternion.hpp>
|
||||
#include <geometry_msgs/msg/quaternion_stamped.hpp>
|
||||
#include <nav2_msgs/action/navigate_to_pose.hpp>
|
||||
#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
|
||||
|
||||
std::ostream & operator<<(std::ostream & out, const geometry_msgs::msg::Quaternion & msg);
|
||||
std::ostream & operator<<(std::ostream & out, const geometry_msgs::msg::Pose & msg);
|
||||
std::ostream & operator<<(std::ostream & out, const geometry_msgs::msg::Point & msg);
|
||||
std::ostream & operator<<(std::ostream & out, const geometry_msgs::msg::PoseStamped & msg);
|
||||
std::ostream & operator<<(std::ostream & out, const nav2_msgs::action::NavigateToPose::Goal & msg);
|
||||
std::ostream & operator<<(std::ostream & out, const builtin_interfaces::msg::Time & msg);
|
||||
@@ -1,43 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <geometry_msgs/msg/pose_with_covariance_stamped.hpp>
|
||||
#include <smacc2/smacc.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CpAmcl : public smacc2::ISmaccComponent
|
||||
{
|
||||
public:
|
||||
CpAmcl();
|
||||
virtual ~CpAmcl();
|
||||
|
||||
std::string getName() const override;
|
||||
|
||||
void onInitialize() override;
|
||||
|
||||
void setInitialPose(const geometry_msgs::msg::PoseWithCovarianceStamped & initialpose);
|
||||
|
||||
private:
|
||||
rclcpp::Publisher<geometry_msgs::msg::PoseWithCovarianceStamped>::SharedPtr initalPosePub_;
|
||||
};
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,92 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <rclcpp/rclcpp.hpp>
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <smacc2/component.hpp>
|
||||
|
||||
// #include <dynamic_reconfigure/DoubleParameter.h>
|
||||
// #include <dynamic_reconfigure/Reconfigure.h>
|
||||
// #include <dynamic_reconfigure/Config.h>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class CpCostmapProxy;
|
||||
|
||||
class CpCostmapSwitch : public smacc2::ISmaccComponent
|
||||
{
|
||||
public:
|
||||
enum class StandardLayers
|
||||
{
|
||||
GLOBAL_OBSTACLES_LAYER = 0,
|
||||
LOCAL_OBSTACLES_LAYER = 1,
|
||||
GLOBAL_INFLATED_LAYER = 2,
|
||||
LOCAL_INFLATED_LAYER = 3
|
||||
};
|
||||
|
||||
static std::array<std::string, 4> layerNames;
|
||||
|
||||
CpCostmapSwitch();
|
||||
|
||||
void onInitialize() override;
|
||||
|
||||
static std::string getStandardCostmapName(StandardLayers layertype);
|
||||
|
||||
bool exists(std::string layerName);
|
||||
|
||||
void enable(std::string layerName);
|
||||
|
||||
void enable(StandardLayers layerType);
|
||||
|
||||
void disable(std::string layerName);
|
||||
|
||||
void disable(StandardLayers layerType);
|
||||
|
||||
void registerProxyFromDynamicReconfigureServer(
|
||||
std::string costmapName, std::string enablePropertyName = "enabled");
|
||||
|
||||
private:
|
||||
std::map<std::string, std::shared_ptr<CpCostmapProxy>> costmapProxies;
|
||||
cl_nav2z::ClNav2Z * nav2zClient_;
|
||||
};
|
||||
//-------------------------------------------------------------------------
|
||||
class CpCostmapProxy
|
||||
{
|
||||
public:
|
||||
CpCostmapProxy(
|
||||
std::string costmap_name, std::string enablePropertyName, rclcpp::Node::SharedPtr nh);
|
||||
|
||||
void setCostmapEnabled(bool value);
|
||||
|
||||
private:
|
||||
std::string costmapName_;
|
||||
rclcpp::Node::SharedPtr nh_;
|
||||
|
||||
inline rclcpp::Node::SharedPtr getNode() { return nh_; }
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,47 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <rclcpp/rclcpp.hpp>
|
||||
#include <smacc2/component.hpp>
|
||||
#include <std_msgs/msg/string.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
// this class is used to switch the current goal checker of the remote navigation2 stack controller
|
||||
class CpGoalCheckerSwitcher : public smacc2::ISmaccComponent
|
||||
{
|
||||
public:
|
||||
CpGoalCheckerSwitcher(
|
||||
std::string goal_checker_selector_topic = "goal_checker_selector",
|
||||
std::string default_goal_checker_name = "goal_checker");
|
||||
void onInitialize() override;
|
||||
virtual ~CpGoalCheckerSwitcher();
|
||||
void setDefaultGoalChecker();
|
||||
void setGoalCheckerId(std::string goal_checker_id);
|
||||
|
||||
private:
|
||||
std::string goal_checker_selector_topic_;
|
||||
std::string default_goal_checker_name_;
|
||||
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr goal_checker_selector_pub_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,262 +0,0 @@
|
||||
// Copyright 2024 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <geometry_msgs/msg/pose_stamped.hpp>
|
||||
#include <nav2_msgs/action/navigate_to_pose.hpp>
|
||||
#include <smacc2/client_core_components/cp_action_client.hpp>
|
||||
#include <smacc2/component.hpp>
|
||||
#include <smacc2/smacc_signal.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <future>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
namespace components
|
||||
{
|
||||
|
||||
class CpNav2ActionInterface : public smacc2::ISmaccComponent
|
||||
{
|
||||
public:
|
||||
// Type aliases for convenience
|
||||
using ActionType = nav2_msgs::action::NavigateToPose;
|
||||
using Goal = ActionType::Goal;
|
||||
using Result = ActionType::Result;
|
||||
using Feedback = ActionType::Feedback;
|
||||
using GoalHandle = rclcpp_action::ClientGoalHandle<ActionType>;
|
||||
using WrappedResult = typename GoalHandle::WrappedResult;
|
||||
using ActionClient = smacc2::client_core_components::CpActionClient<ActionType>;
|
||||
|
||||
// Nav2-specific signals for external subscribers
|
||||
smacc2::SmaccSignal<void(const WrappedResult &)> onNavigationSucceeded_;
|
||||
smacc2::SmaccSignal<void(const WrappedResult &)> onNavigationAborted_;
|
||||
smacc2::SmaccSignal<void(const WrappedResult &)> onNavigationCancelled_;
|
||||
smacc2::SmaccSignal<void(const Feedback &)> onNavigationFeedback_;
|
||||
|
||||
// Nav2-specific event posting functions (set during orthogonal allocation)
|
||||
std::function<void(const WrappedResult &)> postNavigationSuccessEvent;
|
||||
std::function<void(const WrappedResult &)> postNavigationAbortedEvent;
|
||||
std::function<void(const WrappedResult &)> postNavigationCancelledEvent;
|
||||
std::function<void(const Feedback &)> postNavigationFeedbackEvent;
|
||||
|
||||
CpNav2ActionInterface() = default;
|
||||
virtual ~CpNav2ActionInterface() = default;
|
||||
|
||||
// Public API for behaviors and other components
|
||||
std::shared_future<typename GoalHandle::SharedPtr> sendNavigationGoal(
|
||||
const geometry_msgs::msg::PoseStamped & target)
|
||||
{
|
||||
if (!actionClient_)
|
||||
{
|
||||
RCLCPP_ERROR(getLogger(), "[CpNav2ActionInterface] Action client not available!");
|
||||
throw std::runtime_error("Action client not initialized");
|
||||
}
|
||||
|
||||
auto goal = createNavigationGoal(target);
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[CpNav2ActionInterface] Sending navigation goal to: "
|
||||
<< "x=" << target.pose.position.x << ", y=" << target.pose.position.y
|
||||
<< ", frame=" << target.header.frame_id);
|
||||
|
||||
return actionClient_->sendGoal(goal);
|
||||
}
|
||||
|
||||
std::shared_future<typename GoalHandle::SharedPtr> sendGoal(Goal & goal)
|
||||
{
|
||||
if (!actionClient_)
|
||||
{
|
||||
RCLCPP_ERROR(getLogger(), "[CpNav2ActionInterface] Action client not available!");
|
||||
throw std::runtime_error("Action client not initialized");
|
||||
}
|
||||
|
||||
return actionClient_->sendGoal(goal);
|
||||
}
|
||||
|
||||
bool cancelNavigation()
|
||||
{
|
||||
if (!actionClient_)
|
||||
{
|
||||
RCLCPP_WARN(getLogger(), "[CpNav2ActionInterface] Action client not available for cancel!");
|
||||
return false;
|
||||
}
|
||||
|
||||
RCLCPP_INFO(getLogger(), "[CpNav2ActionInterface] Cancelling navigation goal");
|
||||
return actionClient_->cancelGoal();
|
||||
}
|
||||
|
||||
bool isNavigationServerReady() const { return actionClient_ && actionClient_->isServerReady(); }
|
||||
|
||||
void waitForNavigationServer()
|
||||
{
|
||||
if (actionClient_)
|
||||
{
|
||||
actionClient_->waitForServer();
|
||||
}
|
||||
}
|
||||
|
||||
// Component lifecycle
|
||||
template <typename TOrthogonal, typename TSourceObject>
|
||||
void onComponentInitialization()
|
||||
{
|
||||
// Require the underlying action client component
|
||||
this->requiresComponent(actionClient_);
|
||||
|
||||
// Set up nav2-specific event posting functions
|
||||
postNavigationSuccessEvent = [this](const WrappedResult & result)
|
||||
{
|
||||
auto * ev = new smacc2::default_events::EvActionSucceeded<TSourceObject, TOrthogonal>();
|
||||
this->postEvent(ev);
|
||||
};
|
||||
|
||||
postNavigationAbortedEvent = [this](const WrappedResult & result)
|
||||
{
|
||||
auto * ev = new smacc2::default_events::EvActionAborted<TSourceObject, TOrthogonal>();
|
||||
this->postEvent(ev);
|
||||
};
|
||||
|
||||
postNavigationCancelledEvent = [this](const WrappedResult & result)
|
||||
{
|
||||
auto * ev = new smacc2::default_events::EvActionCancelled<TSourceObject, TOrthogonal>();
|
||||
this->postEvent(ev);
|
||||
};
|
||||
|
||||
postNavigationFeedbackEvent = [this](const Feedback & feedback)
|
||||
{
|
||||
auto * ev = new smacc2::default_events::EvActionFeedback<Feedback, TOrthogonal>();
|
||||
ev->feedbackMessage = feedback;
|
||||
this->postEvent(ev);
|
||||
};
|
||||
|
||||
RCLCPP_INFO(getLogger(), "[CpNav2ActionInterface] Component initialized");
|
||||
}
|
||||
|
||||
void onInitialize() override
|
||||
{
|
||||
// Wire up signal connections from action client to nav2-specific signals
|
||||
if (actionClient_)
|
||||
{
|
||||
// Connect action client signals to our nav2-specific signals and event posting using method pointers
|
||||
actionClient_->onSucceeded(&CpNav2ActionInterface::onNavigationSuccess, this);
|
||||
actionClient_->onAborted(&CpNav2ActionInterface::onNavigationAborted, this);
|
||||
actionClient_->onCancelled(&CpNav2ActionInterface::onNavigationCancelled, this);
|
||||
actionClient_->onFeedback(&CpNav2ActionInterface::onNavigationFeedback, this);
|
||||
|
||||
RCLCPP_INFO(getLogger(), "[CpNav2ActionInterface] Signal connections established");
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_ERROR(
|
||||
getLogger(), "[CpNav2ActionInterface] Action client not found during initialization!");
|
||||
}
|
||||
}
|
||||
|
||||
// Signal connection methods for external subscribers
|
||||
template <typename T>
|
||||
boost::signals2::connection onNavigationSucceeded(
|
||||
void (T::*callback)(const WrappedResult &), T * object)
|
||||
{
|
||||
return this->getStateMachine()->createSignalConnection(
|
||||
onNavigationSucceeded_, callback, object);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
boost::signals2::connection onNavigationAborted(
|
||||
void (T::*callback)(const WrappedResult &), T * object)
|
||||
{
|
||||
return this->getStateMachine()->createSignalConnection(onNavigationAborted_, callback, object);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
boost::signals2::connection onNavigationCancelled(
|
||||
void (T::*callback)(const WrappedResult &), T * object)
|
||||
{
|
||||
return this->getStateMachine()->createSignalConnection(
|
||||
onNavigationCancelled_, callback, object);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
boost::signals2::connection onNavigationFeedback(
|
||||
void (T::*callback)(const Feedback &), T * object)
|
||||
{
|
||||
return this->getStateMachine()->createSignalConnection(onNavigationFeedback_, callback, object);
|
||||
}
|
||||
|
||||
// Access to underlying action client for advanced usage
|
||||
ActionClient * getActionClient() const { return actionClient_; }
|
||||
|
||||
private:
|
||||
ActionClient * actionClient_ = nullptr;
|
||||
|
||||
// Event translation callbacks
|
||||
void onNavigationSuccess(const WrappedResult & result)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CpNav2ActionInterface] Navigation succeeded");
|
||||
onNavigationSucceeded_(result);
|
||||
if (postNavigationSuccessEvent)
|
||||
{
|
||||
postNavigationSuccessEvent(result);
|
||||
}
|
||||
}
|
||||
|
||||
void onNavigationAborted(const WrappedResult & result)
|
||||
{
|
||||
RCLCPP_WARN(getLogger(), "[CpNav2ActionInterface] Navigation aborted");
|
||||
onNavigationAborted_(result);
|
||||
if (postNavigationAbortedEvent)
|
||||
{
|
||||
postNavigationAbortedEvent(result);
|
||||
}
|
||||
}
|
||||
|
||||
void onNavigationCancelled(const WrappedResult & result)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CpNav2ActionInterface] Navigation cancelled");
|
||||
onNavigationCancelled_(result);
|
||||
if (postNavigationCancelledEvent)
|
||||
{
|
||||
postNavigationCancelledEvent(result);
|
||||
}
|
||||
}
|
||||
|
||||
void onNavigationFeedback(const Feedback & feedback)
|
||||
{
|
||||
RCLCPP_DEBUG(getLogger(), "[CpNav2ActionInterface] Navigation feedback received");
|
||||
onNavigationFeedback_(feedback);
|
||||
if (postNavigationFeedbackEvent)
|
||||
{
|
||||
postNavigationFeedbackEvent(feedback);
|
||||
}
|
||||
}
|
||||
|
||||
// Nav2-specific goal construction
|
||||
Goal createNavigationGoal(const geometry_msgs::msg::PoseStamped & target)
|
||||
{
|
||||
Goal goal;
|
||||
goal.pose = target;
|
||||
|
||||
// Set default behavior_tree if not specified
|
||||
if (goal.behavior_tree.empty())
|
||||
{
|
||||
goal.behavior_tree = ""; // Let Nav2 use default behavior tree
|
||||
}
|
||||
|
||||
return goal;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace components
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,218 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <tf2/transform_datatypes.h>
|
||||
#include <smacc2/common.hpp>
|
||||
#include <smacc2/component.hpp>
|
||||
|
||||
#include <rclcpp/rclcpp.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include <geometry_msgs/msg/point.hpp>
|
||||
#include <geometry_msgs/msg/pose.hpp>
|
||||
#include <nav2_msgs/action/navigate_to_pose.hpp>
|
||||
#include <nav_msgs/msg/odometry.hpp>
|
||||
#include <nav_msgs/msg/path.hpp>
|
||||
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
#include <std_msgs/msg/header.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
namespace odom_tracker
|
||||
{
|
||||
enum class WorkingMode : uint8_t
|
||||
{
|
||||
RECORD_PATH = 0,
|
||||
CLEAR_PATH = 1,
|
||||
IDLE = 2
|
||||
};
|
||||
|
||||
enum class OdomTrackerStrategy
|
||||
{
|
||||
ODOMETRY_SUBSCRIBER,
|
||||
POSE_COMPONENT
|
||||
};
|
||||
|
||||
/// This object tracks and saves the trajectories performed by the vehicle
|
||||
/// so that they can be used later to execute operations such as "undo motions"
|
||||
class CpOdomTracker : public smacc2::ISmaccComponent
|
||||
{
|
||||
public:
|
||||
// by default, the component start in record_path mode and publishing the
|
||||
// current path
|
||||
CpOdomTracker(
|
||||
std::string odomtopicName = "/odom", std::string odomFrame = "odom",
|
||||
OdomTrackerStrategy strategy = OdomTrackerStrategy::ODOMETRY_SUBSCRIBER);
|
||||
|
||||
// threadsafe
|
||||
/// odom callback: Updates the path - this must be called periodically for each odometry message.
|
||||
// The odom parameters is the main input of this tracker
|
||||
virtual void processNewPose(const geometry_msgs::msg::PoseStamped & odom);
|
||||
|
||||
virtual void odomMessageCallback(const nav_msgs::msg::Odometry::SharedPtr odom);
|
||||
|
||||
virtual void update();
|
||||
|
||||
// ------ CONTROL COMMANDS ---------------------
|
||||
// threadsafe
|
||||
void setWorkingMode(WorkingMode workingMode);
|
||||
|
||||
// threadsafe
|
||||
void setPublishMessages(bool value);
|
||||
|
||||
// threadsafe
|
||||
void pushPath();
|
||||
|
||||
// threadsafe
|
||||
void pushPath(std::string pathname);
|
||||
|
||||
// threadsafe
|
||||
void popPath(int pathCount = 1, bool keepPreviousPath = false);
|
||||
|
||||
// threadsafe
|
||||
void clearPath();
|
||||
|
||||
// threadsafe
|
||||
void setStartPoint(const geometry_msgs::msg::PoseStamped & pose);
|
||||
|
||||
// threadsafe
|
||||
void setStartPoint(const geometry_msgs::msg::Pose & pose);
|
||||
|
||||
// threadsafe - use only for recording mode, it is reset always a new path is pushed, popped or cleared
|
||||
void setCurrentMotionGoal(const geometry_msgs::msg::PoseStamped & pose);
|
||||
|
||||
void setCurrentPathName(const std::string & currentPathName);
|
||||
|
||||
// threadsafe
|
||||
std::optional<geometry_msgs::msg::PoseStamped> getCurrentMotionGoal();
|
||||
|
||||
// threadsafe
|
||||
nav_msgs::msg::Path getPath();
|
||||
|
||||
void logStateString(bool debug = true);
|
||||
|
||||
// parameters update callback
|
||||
void updateParameters();
|
||||
|
||||
inline void setOdomFrame(std::string odomFrame)
|
||||
{
|
||||
odomFrame_ = odomFrame;
|
||||
getNode()->set_parameter(rclcpp::Parameter("odom_frame", odomFrame));
|
||||
}
|
||||
|
||||
protected:
|
||||
void onInitialize() override;
|
||||
|
||||
void updateConfiguration();
|
||||
|
||||
virtual void rtPublishPaths(rclcpp::Time timestamp);
|
||||
|
||||
// this is called when a new odom message is received in record path mode
|
||||
virtual bool updateRecordPath(const geometry_msgs::msg::PoseStamped & odom);
|
||||
|
||||
// this is called when a new odom message is received in clear path mode
|
||||
virtual bool updateClearPath(const geometry_msgs::msg::PoseStamped & odom);
|
||||
|
||||
void updateAggregatedStackPath();
|
||||
|
||||
// -------------- OUTPUTS ---------------------
|
||||
rclcpp::Publisher<nav_msgs::msg::Path>::SharedPtr robotBasePathPub_;
|
||||
rclcpp::Publisher<nav_msgs::msg::Path>::SharedPtr robotBasePathStackedPub_;
|
||||
|
||||
// --------------- INPUTS ------------------------
|
||||
// optional, this class can be used directly calling the odomProcessing method
|
||||
// without any subscriber
|
||||
rclcpp::Subscription<nav_msgs::msg::Odometry>::SharedPtr odomSub_;
|
||||
|
||||
cl_nav2z::Pose * robotPose_;
|
||||
rclcpp::TimerBase::SharedPtr robotPoseTimer_;
|
||||
|
||||
// -------------- PARAMETERS ----------------------
|
||||
/// How much distance there is between two points of the path
|
||||
double recordPointDistanceThreshold_;
|
||||
|
||||
/// Meters
|
||||
double recordAngularDistanceThreshold_;
|
||||
|
||||
/// rads
|
||||
double clearPointDistanceThreshold_;
|
||||
|
||||
/// rads
|
||||
double clearAngularDistanceThreshold_;
|
||||
|
||||
std::string odomFrame_;
|
||||
|
||||
std::string odomTopicName_;
|
||||
|
||||
// --------------- STATE ---------------
|
||||
// default true
|
||||
bool publishMessages;
|
||||
|
||||
/// Processed path for the mouth of the reel
|
||||
nav_msgs::msg::Path baseTrajectory_;
|
||||
|
||||
WorkingMode workingMode_;
|
||||
|
||||
std::vector<nav_msgs::msg::Path> pathStack_;
|
||||
|
||||
struct PathInfo
|
||||
{
|
||||
std::string name;
|
||||
std::optional<geometry_msgs::msg::PoseStamped> goalPose;
|
||||
};
|
||||
|
||||
std::vector<PathInfo> pathInfos_;
|
||||
|
||||
nav_msgs::msg::Path aggregatedStackPathMsg_;
|
||||
|
||||
OdomTrackerStrategy strategy_;
|
||||
|
||||
std::optional<geometry_msgs::msg::PoseStamped> currentMotionGoal_;
|
||||
std::string currentPathName_;
|
||||
|
||||
rcl_interfaces::msg::SetParametersResult parametersCallback(
|
||||
const std::vector<rclcpp::Parameter> & parameters);
|
||||
|
||||
rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr param_callback_handle_;
|
||||
|
||||
std::mutex m_mutex_;
|
||||
};
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* p2pDistance()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
inline double p2pDistance(
|
||||
const geometry_msgs::msg::Point & p1, const geometry_msgs::msg::Point & p2)
|
||||
{
|
||||
double dx = (p1.x - p2.x);
|
||||
double dy = (p1.y - p2.y);
|
||||
double dz = (p2.z - p2.z);
|
||||
double dist = sqrt(dx * dx + dy * dy + dz * dz);
|
||||
return dist;
|
||||
}
|
||||
} // namespace odom_tracker
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,70 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <rclcpp/rclcpp.hpp>
|
||||
#include <smacc2/client_bases/smacc_action_client.hpp>
|
||||
#include <smacc2/component.hpp>
|
||||
#include <std_msgs/msg/string.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
// this component is used to switch the current planner and controller interacting
|
||||
// with the remote navigation2 stack nodes (bt_navigator, planner_server, controller_server)
|
||||
class CpPlannerSwitcher : public smacc2::ISmaccComponent
|
||||
{
|
||||
public:
|
||||
CpPlannerSwitcher();
|
||||
|
||||
void onInitialize() override;
|
||||
|
||||
void setDesiredGlobalPlanner(std::string);
|
||||
|
||||
void setDesiredController(std::string);
|
||||
|
||||
void commitPublish();
|
||||
|
||||
// STANDARD PLANNERS
|
||||
|
||||
void setBackwardPlanner(bool commit = true);
|
||||
|
||||
void setUndoPathBackwardPlanner(bool commit = true);
|
||||
|
||||
void setForwardPlanner(bool commit = true);
|
||||
|
||||
void setPureSpinningPlanner(bool commit = true);
|
||||
|
||||
// sets ROS defaults local and global planners
|
||||
void setDefaultPlanners(bool commit = true);
|
||||
|
||||
private:
|
||||
std::string desired_planner_;
|
||||
|
||||
std::string desired_controller_;
|
||||
|
||||
bool set_planners_mode_flag_;
|
||||
|
||||
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr planner_selector_pub_;
|
||||
|
||||
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr controller_selector_pub_;
|
||||
|
||||
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr goal_checker_selector_pub_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,106 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*-2020
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <geometry_msgs/msg/pose_stamped.h>
|
||||
#include <tf2/transform_datatypes.h>
|
||||
#include <tf2/utils.h>
|
||||
#include <tf2_ros/buffer.h>
|
||||
#include <tf2_ros/transform_listener.h>
|
||||
#include <geometry_msgs/msg/quaternion_stamped.hpp>
|
||||
#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
|
||||
|
||||
#include <smacc2/component.hpp>
|
||||
#include <smacc2/smacc_updatable.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
enum class StandardReferenceFrames
|
||||
{
|
||||
Map,
|
||||
Odometry
|
||||
};
|
||||
|
||||
class Pose : public smacc2::ISmaccComponent, public smacc2::ISmaccUpdatable
|
||||
{
|
||||
public:
|
||||
Pose(std::string poseFrameName = "base_link", std::string referenceFrame = "odom");
|
||||
|
||||
Pose(StandardReferenceFrames referenceFrame);
|
||||
|
||||
void onInitialize() override;
|
||||
|
||||
void update() override;
|
||||
|
||||
// synchronously waits a transform in the current thread
|
||||
void waitTransformUpdate(rclcpp::Rate r = rclcpp::Rate(20));
|
||||
|
||||
inline geometry_msgs::msg::Pose toPoseMsg()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_mutex_);
|
||||
return this->pose_.pose;
|
||||
}
|
||||
|
||||
inline geometry_msgs::msg::PoseStamped toPoseStampedMsg()
|
||||
{
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[Pose] ToPoseMsg ");
|
||||
std::lock_guard<std::mutex> guard(m_mutex_);
|
||||
return this->pose_;
|
||||
}
|
||||
|
||||
// get yaw in radians
|
||||
float getYaw();
|
||||
|
||||
float getX();
|
||||
float getY();
|
||||
float getZ();
|
||||
|
||||
inline void setReferenceFrame(std::string referenceFrame) { referenceFrame_ = referenceFrame; }
|
||||
|
||||
inline const std::string & getReferenceFrame() const { return referenceFrame_; }
|
||||
|
||||
inline const std::string & getFrameId() const { return poseFrameName_; }
|
||||
|
||||
bool isInitialized;
|
||||
|
||||
std::optional<rclcpp::Time> frozenReferenceFrameTime;
|
||||
void freezeReferenceFrame()
|
||||
{
|
||||
frozenReferenceFrameTime = getNode()->now() - rclcpp::Duration::from_seconds(1);
|
||||
}
|
||||
|
||||
void unfreezeReferenceFrame() { frozenReferenceFrameTime = std::nullopt; }
|
||||
|
||||
private:
|
||||
geometry_msgs::msg::PoseStamped pose_;
|
||||
|
||||
static std::shared_ptr<tf2_ros::Buffer> tfBuffer_;
|
||||
static std::shared_ptr<tf2_ros::TransformListener> tfListener_;
|
||||
|
||||
static std::mutex listenerMutex_;
|
||||
|
||||
std::string poseFrameName_;
|
||||
std::string referenceFrame_;
|
||||
|
||||
std::mutex m_mutex_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,50 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <rclcpp/rclcpp.hpp>
|
||||
#include <smacc2/client_bases/smacc_action_client.hpp>
|
||||
#include <smacc2/component.hpp>
|
||||
#include <std_msgs/msg/string.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
// stores the state of the last modification of the slam node
|
||||
// (blind - open loop solution because the node does not provide that information)
|
||||
class CpSlamToolbox : public smacc2::ISmaccComponent
|
||||
{
|
||||
public:
|
||||
CpSlamToolbox();
|
||||
virtual ~CpSlamToolbox();
|
||||
|
||||
enum class SlamToolboxState
|
||||
{
|
||||
Resumed,
|
||||
Paused
|
||||
};
|
||||
|
||||
inline SlamToolboxState getState() { return state_; }
|
||||
|
||||
void toggleState();
|
||||
|
||||
private:
|
||||
SlamToolboxState state_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,85 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/components/nav2_action_interface/cp_nav2_action_interface.hpp>
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_event_dispatcher.hpp>
|
||||
#include <smacc2/smacc.hpp>
|
||||
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator_base.hpp>
|
||||
#include <geometry_msgs/msg/pose.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class ClNav2Z;
|
||||
|
||||
struct EvWaypointFinal : sc::event<EvWaypointFinal>
|
||||
{
|
||||
};
|
||||
|
||||
struct NavigateNextWaypointOptions
|
||||
{
|
||||
std::optional<std::string> controllerName_;
|
||||
std::optional<std::string> goalCheckerName_;
|
||||
};
|
||||
|
||||
// This component contains a list of waypoints. These waypoints can
|
||||
// be iterated in the different states using CbNextWaiPoint
|
||||
// waypoint index is only incremented if the current waypoint is successfully reached
|
||||
class CpWaypointNavigator : public CpWaypointNavigatorBase
|
||||
{
|
||||
public:
|
||||
ClNav2Z * client_;
|
||||
components::CpNav2ActionInterface * nav2ActionInterface_ = nullptr;
|
||||
|
||||
CpWaypointNavigator();
|
||||
|
||||
void onInitialize() override;
|
||||
|
||||
template <typename TOrthogonal, typename TSourceObject>
|
||||
void onStateOrthogonalAllocation()
|
||||
{
|
||||
waypointsEventDispatcher.initialize<TSourceObject, TOrthogonal>(client_);
|
||||
this->requiresComponent(nav2ActionInterface_);
|
||||
}
|
||||
|
||||
std::optional<std::shared_future<
|
||||
std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> > > >
|
||||
sendNextGoal(std::optional<NavigateNextWaypointOptions> options = std::nullopt);
|
||||
|
||||
void stopWaitingResult();
|
||||
|
||||
smacc2::SmaccSignal<void()> onNavigationRequestSucceded;
|
||||
smacc2::SmaccSignal<void()> onNavigationRequestAborted;
|
||||
smacc2::SmaccSignal<void()> onNavigationRequestCancelled;
|
||||
|
||||
private:
|
||||
void onNavigationResult(const components::CpNav2ActionInterface::WrappedResult & r);
|
||||
|
||||
void onGoalReached(const components::CpNav2ActionInterface::WrappedResult & res);
|
||||
void onGoalCancelled(const components::CpNav2ActionInterface::WrappedResult & /*res*/);
|
||||
void onGoalAborted(const components::CpNav2ActionInterface::WrappedResult & /*res*/);
|
||||
|
||||
boost::signals2::connection succeddedNav2ZClientConnection_;
|
||||
boost::signals2::connection abortedNav2ZClientConnection_;
|
||||
boost::signals2::connection cancelledNav2ZClientConnection_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,116 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_event_dispatcher.hpp>
|
||||
#include <smacc2/smacc.hpp>
|
||||
|
||||
#include <geometry_msgs/msg/pose.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
struct Pose2D
|
||||
{
|
||||
Pose2D(double x, double y, double yaw)
|
||||
{
|
||||
this->x_ = x;
|
||||
this->y_ = y;
|
||||
this->yaw_ = yaw;
|
||||
}
|
||||
|
||||
double x_;
|
||||
double y_;
|
||||
double yaw_;
|
||||
};
|
||||
|
||||
// This component contains a list of waypoints. These waypoints can
|
||||
// be iterated in the different states using CbNextWaiPoint
|
||||
// waypoint index is only incremented if the current waypoint is successfully reached
|
||||
class CpWaypointNavigatorBase : public smacc2::ISmaccComponent
|
||||
{
|
||||
public:
|
||||
WaypointEventDispatcher waypointsEventDispatcher;
|
||||
|
||||
CpWaypointNavigatorBase();
|
||||
|
||||
virtual ~CpWaypointNavigatorBase();
|
||||
|
||||
void onInitialize() override;
|
||||
|
||||
// DEPRECATED: For third-party compatibility only. Third-party developers should migrate to onStateOrthogonalAllocation
|
||||
// This method exists to support existing third-party classes that inherit from this base class
|
||||
// and call CpWaypointNavigatorBase::onOrthogonalAllocation<TOrthogonal, TSourceObject>()
|
||||
template <typename TOrthogonal, typename TSourceObject>
|
||||
[[deprecated(
|
||||
"Use onStateOrthogonalAllocation instead. This method exists only for third-party "
|
||||
"compatibility.")]] void
|
||||
onOrthogonalAllocation()
|
||||
{
|
||||
// Call the new method to maintain functionality for third-party inheritors
|
||||
onStateOrthogonalAllocation<TOrthogonal, TSourceObject>();
|
||||
}
|
||||
|
||||
template <typename TOrthogonal, typename TSourceObject>
|
||||
void onStateOrthogonalAllocation()
|
||||
{
|
||||
ClNav2Z * client = dynamic_cast<ClNav2Z *>(owner_);
|
||||
waypointsEventDispatcher.initialize<TSourceObject, TOrthogonal>(client);
|
||||
}
|
||||
|
||||
void loadWayPointsFromFile(std::string filepath);
|
||||
|
||||
void loadWayPointsFromFile2(std::string filepath);
|
||||
|
||||
void setWaypoints(const std::vector<geometry_msgs::msg::Pose> & waypoints);
|
||||
|
||||
void setWaypoints(const std::vector<Pose2D> & waypoints);
|
||||
|
||||
const std::vector<geometry_msgs::msg::Pose> & getWaypoints() const;
|
||||
const std::vector<std::string> & getWaypointNames() const;
|
||||
std::optional<geometry_msgs::msg::Pose> getNamedPose(std::string name) const;
|
||||
geometry_msgs::msg::Pose getPose(int index) const;
|
||||
geometry_msgs::msg::Pose getCurrentPose() const;
|
||||
|
||||
long getCurrentWaypointIndex() const;
|
||||
std::optional<std::string> getCurrentWaypointName() const;
|
||||
|
||||
long currentWaypoint_;
|
||||
|
||||
void rewind(int count);
|
||||
|
||||
void forward(int count);
|
||||
void seekName(std::string name);
|
||||
|
||||
void loadWaypointsFromYamlParameter(
|
||||
std::string parameter_name, std::string yaml_file_package_name);
|
||||
|
||||
void notifyGoalReached();
|
||||
|
||||
protected:
|
||||
void insertWaypoint(int index, geometry_msgs::msg::Pose & newpose);
|
||||
|
||||
void removeWaypoint(int index);
|
||||
|
||||
std::vector<geometry_msgs::msg::Pose> waypoints_;
|
||||
|
||||
std::vector<std::string> waypointsNames_;
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,58 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator.hpp>
|
||||
|
||||
#include <smacc2/smacc.hpp>
|
||||
|
||||
#include <geometry_msgs/msg/pose.hpp>
|
||||
#include <visualization_msgs/msg/marker_array.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
class ClNav2Z;
|
||||
|
||||
class CpWaypointsVisualizer : public smacc2::ISmaccComponent, public smacc2::ISmaccUpdatable
|
||||
{
|
||||
public:
|
||||
cl_nav2z::CpWaypointNavigator * waypointsNavigator_;
|
||||
|
||||
CpWaypointsVisualizer(rclcpp::Duration duration);
|
||||
|
||||
void onInitialize() override;
|
||||
|
||||
protected:
|
||||
virtual void update() override;
|
||||
|
||||
private:
|
||||
std::mutex m_mutex_;
|
||||
|
||||
rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr markersPub_;
|
||||
visualization_msgs::msg::MarkerArray markers_;
|
||||
visualization_msgs::msg::MarkerArray markerLabels_;
|
||||
|
||||
void createMarker(const geometry_msgs::msg::Pose & waypoint, visualization_msgs::msg::Marker & m);
|
||||
void createMarkerLabel(
|
||||
const geometry_msgs::msg::Pose & waypoint, std::string label,
|
||||
visualization_msgs::msg::Marker & m);
|
||||
};
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,37 +0,0 @@
|
||||
<?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>cl_nav2z</name>
|
||||
<version>2.3.19</version>
|
||||
<description>The cl_nav2z package implements SMACC Action Client Plugin for the ROS Navigation State - move_base node. Developed by Reel Robotics.</description>
|
||||
|
||||
<author email="pablo@ibrobotics.com">Pablo Inigo Blasco</author>
|
||||
<maintainer email="pablo@ibrobotics.com">Pablo Inigo Blasco</maintainer>
|
||||
|
||||
<license>BSDv3</license>
|
||||
|
||||
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||
|
||||
<depend>smacc2</depend>
|
||||
<depend>slam_toolbox</depend>
|
||||
|
||||
<depend>angles</depend>
|
||||
<depend>yaml_cpp_vendor</depend>
|
||||
<depend>nav2_msgs</depend>
|
||||
<depend>pluginlib</depend>
|
||||
<depend>rclcpp_action</depend>
|
||||
|
||||
<depend>nav2_util</depend>
|
||||
|
||||
<depend>std_msgs</depend>
|
||||
<depend>std_srvs</depend>
|
||||
<depend>tf2_ros</depend>
|
||||
<depend>tf2_geometry_msgs</depend>
|
||||
<depend>bond</depend>
|
||||
|
||||
<depend>ament_index_cpp</depend>
|
||||
|
||||
<export>
|
||||
<build_type>ament_cmake</build_type>
|
||||
</export>
|
||||
</package>
|
||||
@@ -1,105 +0,0 @@
|
||||
# Copyright 2024 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.
|
||||
|
||||
#!/usr/bin/env python3
|
||||
import rclpy
|
||||
from rclpy.node import Node
|
||||
from sensor_msgs.msg import LaserScan
|
||||
from rclpy.qos import QoSProfile, ReliabilityPolicy, HistoryPolicy
|
||||
import logging
|
||||
import copy
|
||||
|
||||
|
||||
class LidarProcessor(Node):
|
||||
def __init__(self):
|
||||
super().__init__("lidar_processor")
|
||||
|
||||
qos_prof_1 = QoSProfile(
|
||||
reliability=ReliabilityPolicy.BEST_EFFORT, history=HistoryPolicy.KEEP_LAST, depth=10
|
||||
)
|
||||
|
||||
self.subscription = self.create_subscription(
|
||||
LaserScan, "/scan_input", self.lidar_callback, qos_profile=qos_prof_1
|
||||
)
|
||||
|
||||
qos_prof_2 = QoSProfile(
|
||||
reliability=ReliabilityPolicy.RELIABLE, history=HistoryPolicy.KEEP_LAST, depth=10
|
||||
)
|
||||
|
||||
self.msg_buffer = []
|
||||
self.publisher = self.create_publisher(LaserScan, "/scan_output", qos_profile=qos_prof_2)
|
||||
|
||||
self.logger = self.get_logger()
|
||||
self.logger.set_level(logging.INFO)
|
||||
|
||||
def lidar_callback(self, msg):
|
||||
# self.logger.info("Received message")
|
||||
self.msg_buffer.append(msg)
|
||||
if len(self.msg_buffer) > 5:
|
||||
# self.logger.info("Merging messages")
|
||||
merged_msg = self.merge_lidar_msgs()
|
||||
# self.msg_buffer.pop(0)
|
||||
self.msg_buffer = []
|
||||
self.publisher.publish(merged_msg)
|
||||
|
||||
def merge_lidar_msgs(self):
|
||||
merged_ranges = [0.0] * len(self.msg_buffer[0].ranges) * len(self.msg_buffer)
|
||||
# cont_inf = 0
|
||||
cont_tot = 0
|
||||
for i in range(len(self.msg_buffer)):
|
||||
for j in range(len(self.msg_buffer[i].ranges)):
|
||||
# if self.msg_buffer[i].ranges[j] != float("inf"):
|
||||
merged_ranges[cont_tot] = self.msg_buffer[i].ranges[j]
|
||||
cont_tot += 1
|
||||
# else:
|
||||
# cont_inf += 1
|
||||
|
||||
# self.logger.info(f"Number of infinite values from total: {cont_inf}/{cont_tot}")
|
||||
|
||||
merged_msg = LaserScan()
|
||||
# merged_msg = copy.deepcopy(self.msg_buffer[-1])
|
||||
merged_msg.header = self.msg_buffer[-1].header
|
||||
|
||||
merged_msg.time_increment = self.msg_buffer[0].time_increment
|
||||
|
||||
merged_msg.angle_increment = self.msg_buffer[0].angle_increment
|
||||
merged_msg.angle_min = self.msg_buffer[0].angle_min
|
||||
merged_msg.angle_max = (
|
||||
self.msg_buffer[0].angle_min + (len(merged_ranges) - 1) * merged_msg.angle_increment
|
||||
)
|
||||
|
||||
# print(f"first angle_min: {self.msg_buffer[0].angle_min}")
|
||||
# print(f"angle_min: {merged_msg.angle_min}")
|
||||
# print(f"angle_max: {merged_msg.angle_max}")
|
||||
|
||||
# merged_msg.angle_min = self.msg_buffer[0].angle_min - self.msg_buffer[0].angle_increment*len(self.msg_buffer)
|
||||
# merged_msg.angle_max = merged_msg.angle_min + (len(merged_ranges)-1)*merged_msg.angle_increment
|
||||
|
||||
merged_msg.range_min = min(msg.range_min for msg in self.msg_buffer)
|
||||
merged_msg.range_max = max(msg.range_max for msg in self.msg_buffer)
|
||||
merged_msg.ranges = merged_ranges
|
||||
|
||||
return merged_msg
|
||||
|
||||
|
||||
def main(args=None):
|
||||
rclpy.init(args=args)
|
||||
lidar_processor = LidarProcessor()
|
||||
rclpy.spin(lidar_processor)
|
||||
lidar_processor.destroy_node()
|
||||
rclpy.shutdown()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright 2024 Robosoft 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.
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <pluginlib/class_list_macros.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
|
||||
// No implementation needed for the refactored client - all functionality
|
||||
// is provided through components and the header-only interface
|
||||
|
||||
} // namespace cl_nav2z
|
||||
|
||||
// Export the ClNav2Z class as type smacc2::ISmaccClient as an implementation of the ISmaccClient interface.
|
||||
PLUGINLIB_EXPORT_CLASS(cl_nav2z::ClNav2Z, smacc2::ISmaccClient)
|
||||
@@ -1,44 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_abort_navigation.hpp>
|
||||
#include <cl_nav2z/common.hpp>
|
||||
#include <cl_nav2z/components/goal_checker_switcher/cp_goal_checker_switcher.hpp>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
#include <rclcpp/parameter_client.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbAbortNavigation::CbAbortNavigation() {}
|
||||
|
||||
void CbAbortNavigation::onEntry()
|
||||
{
|
||||
// this->sendGoal(goal);
|
||||
|
||||
this->nav2ActionInterface_->cancelNavigation();
|
||||
this->postSuccessEvent();
|
||||
}
|
||||
|
||||
void CbAbortNavigation::onExit() {}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,270 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_absolute_rotate.hpp>
|
||||
#include <cl_nav2z/common.hpp>
|
||||
#include <cl_nav2z/components/goal_checker_switcher/cp_goal_checker_switcher.hpp>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
#include <rclcpp/parameter_client.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbAbsoluteRotate::CbAbsoluteRotate() {}
|
||||
CbAbsoluteRotate::CbAbsoluteRotate(float absoluteGoalAngleDegree, float yaw_goal_tolerance)
|
||||
{
|
||||
this->absoluteGoalAngleDegree = absoluteGoalAngleDegree;
|
||||
|
||||
if (yaw_goal_tolerance >= 0)
|
||||
{
|
||||
this->yawGoalTolerance = yaw_goal_tolerance;
|
||||
}
|
||||
}
|
||||
|
||||
void CbAbsoluteRotate::onEntry()
|
||||
{
|
||||
listener = std::make_shared<tf2_ros::Buffer>(getNode()->get_clock());
|
||||
double goal_angle = this->absoluteGoalAngleDegree;
|
||||
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CbAbsoluteRotate] Absolute yaw Angle:" << goal_angle);
|
||||
|
||||
auto plannerSwitcher = this->getComponent<CpPlannerSwitcher>();
|
||||
// this should work better with a coroutine and await
|
||||
// this->plannerSwitcher_->setForwardPlanner();
|
||||
|
||||
if (spinningPlanner && *spinningPlanner == SpinningPlanner::PureSpinning)
|
||||
{
|
||||
plannerSwitcher->setPureSpinningPlanner();
|
||||
}
|
||||
else
|
||||
{
|
||||
plannerSwitcher->setDefaultPlanners();
|
||||
}
|
||||
|
||||
updateTemporalBehaviorParameters(false);
|
||||
|
||||
auto p = this->getComponent<cl_nav2z::Pose>();
|
||||
auto referenceFrame = p->getReferenceFrame();
|
||||
auto currentPoseMsg = p->toPoseMsg();
|
||||
|
||||
nav2_msgs::action::NavigateToPose::Goal goal;
|
||||
goal.pose.header.frame_id = referenceFrame;
|
||||
//goal.pose.header.stamp = getNode()->now();
|
||||
|
||||
auto targetAngle = goal_angle * M_PI / 180.0;
|
||||
goal.pose.pose.position = currentPoseMsg.position;
|
||||
tf2::Quaternion q;
|
||||
q.setRPY(0, 0, targetAngle);
|
||||
goal.pose.pose.orientation = tf2::toMsg(q);
|
||||
|
||||
auto odomTracker_ = this->getComponent<odom_tracker::CpOdomTracker>();
|
||||
if (odomTracker_ != nullptr)
|
||||
{
|
||||
auto pathname = this->getCurrentState()->getName() + " - " + getName();
|
||||
odomTracker_->pushPath(pathname);
|
||||
odomTracker_->setStartPoint(p->toPoseStampedMsg());
|
||||
odomTracker_->setCurrentMotionGoal(goal.pose);
|
||||
odomTracker_->setWorkingMode(odom_tracker::WorkingMode::RECORD_PATH);
|
||||
}
|
||||
|
||||
auto goalCheckerSwitcher = this->getComponent<CpGoalCheckerSwitcher>();
|
||||
goalCheckerSwitcher->setGoalCheckerId("absolute_rotate_goal_checker");
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(),
|
||||
"[" << getName() << "] current pose yaw: " << tf2::getYaw(currentPoseMsg.orientation));
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(),
|
||||
"[" << getName() << "] goal pose yaw: " << tf2::getYaw(goal.pose.pose.orientation));
|
||||
this->sendGoal(goal);
|
||||
}
|
||||
|
||||
void CbAbsoluteRotate::updateTemporalBehaviorParameters(bool undo)
|
||||
{
|
||||
auto log = this->getLogger();
|
||||
|
||||
std::string nodename = "/controller_server";
|
||||
|
||||
auto parameters_client =
|
||||
std::make_shared<rclcpp::AsyncParametersClient>(this->getNode(), nodename);
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
log, "[" << getName() << "] using a parameter client to update some controller parameters: "
|
||||
<< nodename << ". Waiting service.");
|
||||
parameters_client->wait_for_service();
|
||||
|
||||
RCLCPP_INFO_STREAM(log, "[" << getName() << "] Service found: " << nodename << ".");
|
||||
|
||||
std::string localPlannerName;
|
||||
std::vector<rclcpp::Parameter> parameters;
|
||||
|
||||
// dynamic_reconfigure::DoubleParameter yaw_goal_tolerance;
|
||||
rclcpp::Parameter yaw_goal_tolerance("goal_checker.yaw_goal_tolerance");
|
||||
|
||||
rclcpp::Parameter max_vel_theta, min_vel_theta;
|
||||
|
||||
bool isRosBasePlanner = !spinningPlanner || *spinningPlanner == SpinningPlanner::Default;
|
||||
bool isPureSpinningPlanner = spinningPlanner && *spinningPlanner == SpinningPlanner::PureSpinning;
|
||||
|
||||
// SELECTING CONTROLLER AND PARAMETERS NAME
|
||||
if (isPureSpinningPlanner)
|
||||
{
|
||||
localPlannerName = "PureSpinningLocalPlanner";
|
||||
max_vel_theta = rclcpp::Parameter(localPlannerName + ".max_angular_z_speed");
|
||||
min_vel_theta = rclcpp::Parameter(localPlannerName + ".min_vel_theta");
|
||||
}
|
||||
else if (isRosBasePlanner)
|
||||
{
|
||||
localPlannerName = "FollowPath";
|
||||
max_vel_theta = rclcpp::Parameter(localPlannerName + ".max_vel_theta");
|
||||
min_vel_theta = rclcpp::Parameter(localPlannerName + ".min_vel_theta");
|
||||
}
|
||||
|
||||
if (!undo)
|
||||
{
|
||||
if (yawGoalTolerance)
|
||||
{
|
||||
// save old yaw tolerance
|
||||
auto fut = parameters_client->get_parameters(
|
||||
{localPlannerName + ".yaw_goal_tolerance"},
|
||||
[&](auto futureParameters)
|
||||
{
|
||||
auto params = futureParameters.get();
|
||||
oldYawTolerance = params[0].as_double();
|
||||
});
|
||||
|
||||
// make synchronous
|
||||
fut.get();
|
||||
|
||||
yaw_goal_tolerance = rclcpp::Parameter("goal_checker.yaw_goal_tolerance", *yawGoalTolerance);
|
||||
parameters.push_back(yaw_goal_tolerance);
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[" << getName()
|
||||
<< "] updating yaw tolerance local planner to: " << *yawGoalTolerance
|
||||
<< ", from previous value: " << this->oldYawTolerance);
|
||||
}
|
||||
|
||||
if (maxVelTheta)
|
||||
{
|
||||
if (isRosBasePlanner)
|
||||
{
|
||||
// nh.getParam(nodename + "/" + localPlannerName+"/min_vel_theta", oldMinVelTheta);
|
||||
// getCurrentState()->getParam(nodename + "/" + localPlannerName + "/max_vel_theta", oldMaxVelTheta);
|
||||
|
||||
// save old yaw tolerance
|
||||
auto fut = parameters_client->get_parameters(
|
||||
{localPlannerName + ".max_vel_theta"},
|
||||
[&](auto futureParameters)
|
||||
{
|
||||
auto params = futureParameters.get();
|
||||
oldMaxVelTheta = params[0].as_double();
|
||||
});
|
||||
|
||||
// make synchronous
|
||||
fut.get();
|
||||
}
|
||||
|
||||
max_vel_theta = rclcpp::Parameter(localPlannerName + ".max_vel_theta", *maxVelTheta);
|
||||
min_vel_theta = rclcpp::Parameter(localPlannerName + ".min_vel_theta", -*maxVelTheta);
|
||||
parameters.push_back(max_vel_theta);
|
||||
parameters.push_back(min_vel_theta);
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
log, "[" << getName() << "] updating max vel theta local planner to: " << *maxVelTheta
|
||||
<< ", from previous value: " << this->oldMaxVelTheta);
|
||||
RCLCPP_INFO_STREAM(
|
||||
log, "[" << getName() << "] updating min vel theta local planner to: " << -*maxVelTheta
|
||||
<< ", from previous value: " << this->oldMinVelTheta);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (yawGoalTolerance)
|
||||
{
|
||||
yaw_goal_tolerance = rclcpp::Parameter("goal_checker.yaw_goal_tolerance", oldYawTolerance);
|
||||
RCLCPP_INFO_STREAM(
|
||||
log, "[" << getName() << "] restoring yaw tolerance local planner from: "
|
||||
<< *yawGoalTolerance << " , to previous value: " << this->oldYawTolerance);
|
||||
}
|
||||
|
||||
if (maxVelTheta)
|
||||
{
|
||||
if (isRosBasePlanner)
|
||||
{
|
||||
max_vel_theta = rclcpp::Parameter(localPlannerName + ".max_vel_theta", oldMaxVelTheta);
|
||||
min_vel_theta = rclcpp::Parameter(localPlannerName + ".max_vel_theta", oldMinVelTheta);
|
||||
}
|
||||
|
||||
parameters.push_back(max_vel_theta);
|
||||
parameters.push_back(min_vel_theta);
|
||||
RCLCPP_INFO_STREAM(
|
||||
log, "[" << getName() << "] restoring max vel theta local planner from: " << *maxVelTheta
|
||||
<< ", to previous value: " << this->oldMaxVelTheta);
|
||||
RCLCPP_INFO_STREAM(
|
||||
log, "[" << getName() << "] restoring min vel theta local planner from: " << -(*maxVelTheta)
|
||||
<< ", to previous value: " << this->oldMinVelTheta);
|
||||
}
|
||||
}
|
||||
|
||||
if (parameters.size())
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Executing asynchronous request. Parameters to update: " << std::endl;
|
||||
for (auto & p : parameters)
|
||||
{
|
||||
ss << p.get_name() << " - " << p.value_to_string() << std::endl;
|
||||
}
|
||||
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CbAbsoluteRotate] " << ss.str());
|
||||
|
||||
auto futureResults = parameters_client->set_parameters(parameters);
|
||||
|
||||
int i = 0;
|
||||
for (auto & res : futureResults.get())
|
||||
{
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[" << getName() << "] parameter result: " << parameters[i].get_name() << "="
|
||||
<< parameters[i].as_string() << ". Result: " << res.successful);
|
||||
i++;
|
||||
}
|
||||
|
||||
RCLCPP_INFO_STREAM(log, "[" << getName() << "] parameters updated");
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO_STREAM(log, "[" << getName() << "] skipping parameters update");
|
||||
}
|
||||
}
|
||||
|
||||
void CbAbsoluteRotate::onExit()
|
||||
{
|
||||
if (spinningPlanner && *spinningPlanner == SpinningPlanner::PureSpinning)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
this->updateTemporalBehaviorParameters(true);
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,53 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <angles/angles.h>
|
||||
#include <geometry_msgs/msg/twist.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_active_stop.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbActiveStop::CbActiveStop() {}
|
||||
|
||||
void CbActiveStop::onEntry()
|
||||
{
|
||||
auto nh = this->getNode();
|
||||
cmd_vel_pub_ = nh->create_publisher<geometry_msgs::msg::Twist>("/cmd_vel", rclcpp::QoS(1));
|
||||
|
||||
rclcpp::Rate loop_rate(5);
|
||||
geometry_msgs::msg::Twist cmd_vel_msg;
|
||||
while (!this->isShutdownRequested())
|
||||
{
|
||||
cmd_vel_msg.linear.x = 0;
|
||||
cmd_vel_msg.angular.z = 0;
|
||||
|
||||
cmd_vel_pub_->publish(cmd_vel_msg);
|
||||
loop_rate.sleep();
|
||||
}
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] Finished behavior execution");
|
||||
|
||||
this->postSuccessEvent();
|
||||
}
|
||||
|
||||
void CbActiveStop::onExit() {}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,57 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_load_waypoints_file.hpp>
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator_base.hpp>
|
||||
#include <smacc2/smacc_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
|
||||
CbLoadWaypointsFile::CbLoadWaypointsFile(std::string filepath) : filepath_(filepath) {}
|
||||
|
||||
CbLoadWaypointsFile::CbLoadWaypointsFile(std::string parameter_name, std::string packagenamespace)
|
||||
: parameterName_(parameter_name), packageNamespace_(packagenamespace)
|
||||
{
|
||||
}
|
||||
|
||||
void CbLoadWaypointsFile::onEntry()
|
||||
{
|
||||
requiresComponent(waypointsNavigator_); // this is a component from the
|
||||
// nav2z_client library
|
||||
|
||||
if (filepath_)
|
||||
{
|
||||
this->waypointsNavigator_->loadWayPointsFromFile(filepath_.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "Loading waypoints from parameter %s", parameterName_.value().c_str());
|
||||
this->waypointsNavigator_->loadWaypointsFromYamlParameter(
|
||||
parameterName_.value(), packageNamespace_.value());
|
||||
}
|
||||
|
||||
// change this to skip some points of the yaml file, default = 0
|
||||
waypointsNavigator_->currentWaypoint_ = 0;
|
||||
this->postSuccessEvent();
|
||||
}
|
||||
|
||||
void CbLoadWaypointsFile::onExit() {}
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,34 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#include <cl_nav2z/client_behaviors/cb_nav2z_client_behavior_base.hpp>
|
||||
#include <cl_nav2z/common.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbNav2ZClientBehaviorBase::~CbNav2ZClientBehaviorBase() {}
|
||||
|
||||
// REMOVED: All legacy implementation - behaviors now use component APIs directly
|
||||
// The base class provides component access but no complex logic
|
||||
// Individual behaviors should use:
|
||||
// nav2ActionInterface_->sendGoal(goal)
|
||||
// nav2ActionInterface_->onNavigationSucceeded(&Behavior::onSuccess, this)
|
||||
// etc.
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,100 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <tf2/utils.h>
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_backwards.hpp>
|
||||
#include <cl_nav2z/common.hpp>
|
||||
#include <cl_nav2z/components/goal_checker_switcher/cp_goal_checker_switcher.hpp>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
#include <geometry_msgs/msg/quaternion_stamped.hpp>
|
||||
#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
using namespace ::cl_nav2z::odom_tracker;
|
||||
|
||||
CbNavigateBackwards::CbNavigateBackwards(float backwardDistance)
|
||||
{
|
||||
if (backwardDistance < 0)
|
||||
{
|
||||
RCLCPP_ERROR(getLogger(), "[CbNavigateBackwards] distance must be greater or equal than 0");
|
||||
this->backwardDistance = 0;
|
||||
}
|
||||
this->backwardDistance = backwardDistance;
|
||||
}
|
||||
|
||||
void CbNavigateBackwards::onEntry()
|
||||
{
|
||||
// straight motion distance
|
||||
double dist = backwardDistance;
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[CbNavigateBackwards] Straight backwards motion distance: " << dist);
|
||||
|
||||
auto p = this->getComponent<cl_nav2z::Pose>();
|
||||
auto referenceFrame = p->getReferenceFrame();
|
||||
auto currentPoseMsg = p->toPoseMsg();
|
||||
tf2::Transform currentPose;
|
||||
tf2::fromMsg(currentPoseMsg, currentPose);
|
||||
|
||||
tf2::Transform backwardDeltaTransform;
|
||||
backwardDeltaTransform.setIdentity();
|
||||
backwardDeltaTransform.setOrigin(tf2::Vector3(-dist, 0, 0));
|
||||
|
||||
tf2::Transform targetPose = currentPose * backwardDeltaTransform;
|
||||
|
||||
nav2_msgs::action::NavigateToPose::Goal goal;
|
||||
goal.pose.header.frame_id = referenceFrame;
|
||||
//goal.pose.header.stamp = getNode()->now();
|
||||
tf2::toMsg(targetPose, goal.pose.pose);
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CbNavigateBackwards] TARGET POSE BACKWARDS: " << goal.pose);
|
||||
|
||||
geometry_msgs::msg::PoseStamped currentStampedPoseMsg;
|
||||
currentStampedPoseMsg.header.frame_id = referenceFrame;
|
||||
currentStampedPoseMsg.header.stamp = getNode()->now();
|
||||
tf2::toMsg(currentPose, currentStampedPoseMsg.pose);
|
||||
|
||||
odomTracker_ = this->getComponent<CpOdomTracker>();
|
||||
if (odomTracker_ != nullptr)
|
||||
{
|
||||
this->odomTracker_->clearPath();
|
||||
this->odomTracker_->setStartPoint(currentStampedPoseMsg);
|
||||
this->odomTracker_->setWorkingMode(WorkingMode::RECORD_PATH);
|
||||
}
|
||||
|
||||
auto plannerSwitcher = this->getComponent<CpPlannerSwitcher>();
|
||||
plannerSwitcher->setBackwardPlanner();
|
||||
|
||||
auto goalCheckerSwitcher = this->getComponent<CpGoalCheckerSwitcher>();
|
||||
goalCheckerSwitcher->setGoalCheckerId("backward_goal_checker");
|
||||
|
||||
this->sendGoal(goal);
|
||||
}
|
||||
|
||||
void CbNavigateBackwards::onExit()
|
||||
{
|
||||
if (odomTracker_)
|
||||
{
|
||||
this->odomTracker_->setWorkingMode(WorkingMode::IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,158 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/common.hpp>
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_forward.hpp>
|
||||
#include <cl_nav2z/components/goal_checker_switcher/cp_goal_checker_switcher.hpp>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
using ::cl_nav2z::odom_tracker::CpOdomTracker;
|
||||
using ::cl_nav2z::odom_tracker::WorkingMode;
|
||||
|
||||
using ::cl_nav2z::Pose;
|
||||
|
||||
CbNavigateForward::CbNavigateForward(float distance_meters) : forwardDistance_(distance_meters) {}
|
||||
CbNavigateForward::CbNavigateForward() {}
|
||||
|
||||
CbNavigateForward::CbNavigateForward(geometry_msgs::msg::PoseStamped goal) : goalPose_(goal) {}
|
||||
|
||||
CbNavigateForward::~CbNavigateForward() {}
|
||||
|
||||
void CbNavigateForward::setForwardDistance(float distance_meters)
|
||||
{
|
||||
if (distance_meters < 0)
|
||||
{
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[" << getName() << "] negative forward distance: " << distance_meters
|
||||
<< ". Resetting to 0.");
|
||||
distance_meters = 0;
|
||||
}
|
||||
forwardDistance_ = distance_meters;
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[" << getName() << "] setting fw motion distance: " << *forwardDistance_);
|
||||
}
|
||||
|
||||
void CbNavigateForward::onEntry()
|
||||
{
|
||||
if (forwardDistance_)
|
||||
{
|
||||
setForwardDistance(*forwardDistance_);
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[" << getName() << "] Straight motion distance: " << *forwardDistance_);
|
||||
}
|
||||
|
||||
// get current pose
|
||||
auto p = this->getComponent<Pose>();
|
||||
auto referenceFrame = p->getReferenceFrame();
|
||||
auto currentPoseMsg = p->toPoseMsg();
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[" << getName() << "]"
|
||||
<< "current pose: " << currentPoseMsg);
|
||||
|
||||
// force global orientation if it is requested
|
||||
if (options.forceInitialOrientation)
|
||||
{
|
||||
currentPoseMsg.orientation = *(options.forceInitialOrientation);
|
||||
RCLCPP_WARN_STREAM(
|
||||
getLogger(),
|
||||
"[" << getName() << "]"
|
||||
<< "Forcing initial straight motion orientation: " << currentPoseMsg.orientation);
|
||||
}
|
||||
|
||||
tf2::Transform currentPose;
|
||||
tf2::fromMsg(currentPoseMsg, currentPose);
|
||||
|
||||
tf2::Transform targetPose;
|
||||
if (goalPose_)
|
||||
{
|
||||
tf2::fromMsg(goalPose_->pose, targetPose);
|
||||
}
|
||||
else if (forwardDistance_)
|
||||
{
|
||||
// compute forward goal pose
|
||||
tf2::Transform forwardDeltaTransform;
|
||||
forwardDeltaTransform.setIdentity();
|
||||
forwardDeltaTransform.setOrigin(tf2::Vector3(*forwardDistance_, 0, 0));
|
||||
|
||||
targetPose = currentPose * forwardDeltaTransform;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_WARN_STREAM(
|
||||
getLogger(),
|
||||
"[" << getName() << "]"
|
||||
<< "No goal Pose or Distance is specified. Aborting. No action request is sent."
|
||||
<< currentPoseMsg.orientation);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// action goal
|
||||
nav2_msgs::action::NavigateToPose::Goal goal;
|
||||
goal.pose.header.frame_id = referenceFrame;
|
||||
//goal.pose.header.stamp = getNode()->now();
|
||||
tf2::toMsg(targetPose, goal.pose.pose);
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[" << getName() << "]"
|
||||
<< " TARGET POSE FORWARD: " << goal.pose.pose);
|
||||
|
||||
// current pose
|
||||
geometry_msgs::msg::PoseStamped currentStampedPoseMsg;
|
||||
currentStampedPoseMsg.header.frame_id = referenceFrame;
|
||||
currentStampedPoseMsg.header.stamp =
|
||||
getNode()->now(); // probably it is better avoid setting that goal timestamp
|
||||
|
||||
tf2::toMsg(currentPose, currentStampedPoseMsg.pose);
|
||||
|
||||
odomTracker_ = this->getComponent<CpOdomTracker>();
|
||||
if (odomTracker_ != nullptr)
|
||||
{
|
||||
auto pathname = this->getCurrentState()->getName() + " - " + getName();
|
||||
odomTracker_->pushPath(pathname);
|
||||
odomTracker_->setStartPoint(currentStampedPoseMsg);
|
||||
odomTracker_->setCurrentMotionGoal(goal.pose);
|
||||
odomTracker_->setWorkingMode(WorkingMode::RECORD_PATH);
|
||||
}
|
||||
|
||||
auto plannerSwitcher = this->getComponent<CpPlannerSwitcher>();
|
||||
plannerSwitcher->setForwardPlanner();
|
||||
|
||||
auto goalCheckerSwitcher = this->getComponent<CpGoalCheckerSwitcher>();
|
||||
goalCheckerSwitcher->setGoalCheckerId("forward_goal_checker");
|
||||
|
||||
this->sendGoal(goal);
|
||||
}
|
||||
|
||||
void CbNavigateForward::onExit()
|
||||
{
|
||||
if (odomTracker_)
|
||||
{
|
||||
this->odomTracker_->setWorkingMode(WorkingMode::IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,109 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#include <cl_nav2z/common.hpp>
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_global_position.hpp>
|
||||
#include <cl_nav2z/components/goal_checker_switcher/cp_goal_checker_switcher.hpp>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <cl_nav2z/components/planner_switcher/cp_planner_switcher.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
using namespace ::cl_nav2z::odom_tracker;
|
||||
|
||||
CbNavigateGlobalPosition::CbNavigateGlobalPosition() {}
|
||||
|
||||
CbNavigateGlobalPosition::CbNavigateGlobalPosition(
|
||||
float x, float y, float yaw, std::optional<CbNavigateGlobalPositionOptions> options)
|
||||
{
|
||||
auto p = geometry_msgs::msg::Point();
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
goalPosition = p;
|
||||
goalYaw = yaw;
|
||||
|
||||
if (options) this->options = *options;
|
||||
}
|
||||
|
||||
void CbNavigateGlobalPosition::setGoal(const geometry_msgs::msg::Pose & pose)
|
||||
{
|
||||
goalPosition = pose.position;
|
||||
goalYaw = tf2::getYaw(pose.orientation);
|
||||
}
|
||||
|
||||
void CbNavigateGlobalPosition::onEntry()
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "Entering Navigate Global position");
|
||||
RCLCPP_INFO(getLogger(), "Component requirements completed");
|
||||
|
||||
auto pose = this->getComponent<cl_nav2z::Pose>()->toPoseMsg();
|
||||
auto * odomTracker = this->getComponent<CpOdomTracker>();
|
||||
|
||||
auto plannerSwitcher = this->getComponent<CpPlannerSwitcher>();
|
||||
|
||||
plannerSwitcher->setDefaultPlanners(false);
|
||||
|
||||
if (options.controllerName_)
|
||||
{
|
||||
plannerSwitcher->setDesiredController(*(options.controllerName_));
|
||||
}
|
||||
|
||||
plannerSwitcher->commitPublish();
|
||||
|
||||
auto goalCheckerSwitcher = this->getComponent<CpGoalCheckerSwitcher>();
|
||||
goalCheckerSwitcher->setGoalCheckerId("goal_checker");
|
||||
|
||||
auto pathname = this->getCurrentState()->getName() + " - " + getName();
|
||||
odomTracker->pushPath(pathname);
|
||||
odomTracker->setStartPoint(pose);
|
||||
odomTracker->setWorkingMode(WorkingMode::RECORD_PATH);
|
||||
|
||||
execute();
|
||||
}
|
||||
|
||||
// auxiliary function that defines the motion that is requested to the nav2 action server
|
||||
void CbNavigateGlobalPosition::execute()
|
||||
{
|
||||
auto p = this->getComponent<cl_nav2z::Pose>();
|
||||
auto referenceFrame = p->getReferenceFrame();
|
||||
// auto currentPoseMsg = p->toPoseMsg();
|
||||
|
||||
RCLCPP_INFO(getLogger(), "Sending Goal to MoveBase");
|
||||
nav2_msgs::action::NavigateToPose::Goal goal;
|
||||
goal.pose.header.frame_id = referenceFrame;
|
||||
//goal.pose.header.stamp = getNode()->now();
|
||||
|
||||
goal.pose.pose.position = goalPosition;
|
||||
tf2::Quaternion q;
|
||||
q.setRPY(0, 0, goalYaw);
|
||||
goal.pose.pose.orientation = tf2::toMsg(q);
|
||||
|
||||
this->sendGoal(goal);
|
||||
}
|
||||
|
||||
// This is the substate destructor. This code will be executed when the
|
||||
// workflow exits from this substate (that is according to statechart the moment when this object is destroyed)
|
||||
void CbNavigateGlobalPosition::onExit()
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "Exiting move goal Action Client");
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,59 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_named_waypoint.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbNavigateNamedWaypoint::CbNavigateNamedWaypoint(
|
||||
std::string waypointname, std::optional<NavigateNextWaypointOptions> options)
|
||||
: CbNavigateNextWaypoint(options)
|
||||
{
|
||||
waypointname_ = waypointname;
|
||||
}
|
||||
|
||||
CbNavigateNamedWaypoint::~CbNavigateNamedWaypoint() {}
|
||||
|
||||
void CbNavigateNamedWaypoint::onEntry()
|
||||
{
|
||||
// waypointsNavigator_ = this->getComponent<CpWaypointNavigator>();
|
||||
// waypointsNavigator_->sendNextGoal(options_);
|
||||
|
||||
// auto waypointname = waypointsNavigator_->getCurrentWaypointName();
|
||||
|
||||
// if(waypointname)
|
||||
// {
|
||||
// RCLCPP_INFO(
|
||||
// getLogger(), "[CbNavigateNamedWaypoint] current iteration waypoints i: %ld with name '%s'",
|
||||
// waypointsNavigator_->getCurrentWaypointIndex(), waypointname->c_str()); }
|
||||
// else
|
||||
// {
|
||||
// RCLCPP_INFO(
|
||||
// getLogger(), "[CbNavigateNamedWaypoint] current iteration waypoints i: %ld",
|
||||
// waypointsNavigator_->getCurrentWaypointIndex()); }
|
||||
|
||||
auto waypointsNavigator_ = this->getComponent<CpWaypointNavigator>();
|
||||
waypointsNavigator_->seekName(waypointname_);
|
||||
CbNavigateNextWaypoint::onEntry();
|
||||
}
|
||||
|
||||
void CbNavigateNamedWaypoint::onExit() { CbNavigateNextWaypoint::onExit(); }
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,56 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_next_waypoint.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbNavigateNextWaypoint::CbNavigateNextWaypoint(std::optional<NavigateNextWaypointOptions> options)
|
||||
{
|
||||
if (options) options_ = *options;
|
||||
}
|
||||
|
||||
CbNavigateNextWaypoint::~CbNavigateNextWaypoint() {}
|
||||
|
||||
void CbNavigateNextWaypoint::onEntry()
|
||||
{
|
||||
this->requiresComponent(waypointsNavigator_);
|
||||
|
||||
auto goalHandle = waypointsNavigator_->sendNextGoal(options_);
|
||||
|
||||
auto waypointname = waypointsNavigator_->getCurrentWaypointName();
|
||||
|
||||
if (waypointname)
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CbNavigateNextWaypoint] current iteration waypoints i: %ld with name '%s'",
|
||||
waypointsNavigator_->getCurrentWaypointIndex(), waypointname->c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CbNavigateNextWaypoint] current iteration waypoints i: %ld",
|
||||
waypointsNavigator_->getCurrentWaypointIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void CbNavigateNextWaypoint::onExit() { waypointsNavigator_->stopWaitingResult(); }
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,54 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_next_waypoint_free.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
|
||||
CbNavigateNextWaypointFree::CbNavigateNextWaypointFree() {}
|
||||
|
||||
CbNavigateNextWaypointFree::~CbNavigateNextWaypointFree() {}
|
||||
|
||||
void CbNavigateNextWaypointFree::onEntry()
|
||||
{
|
||||
requiresComponent(this->waypointsNavigator_);
|
||||
this->target_pose_ = this->waypointsNavigator_->getCurrentPose();
|
||||
|
||||
this->onSuccess(&CbNavigateNextWaypointFree::CbNavigateNextWaypointFree::onSucessCallback, this);
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[CbNavigateNextWaypoint] initial load file target pose: x: "
|
||||
<< this->target_pose_.position.x << ", y: " << this->target_pose_.position.y);
|
||||
CbPositionControlFreeSpace::onEntry();
|
||||
}
|
||||
|
||||
void CbNavigateNextWaypointFree::onSucessCallback()
|
||||
{
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CbNavigateNextWaypoint] Success on planning to next waypoint");
|
||||
this->waypointsNavigator_->notifyGoalReached();
|
||||
this->waypointsNavigator_->forward(1);
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[CbNavigateNextWaypoint] next position index: "
|
||||
<< this->waypointsNavigator_->getCurrentWaypointIndex() << "/"
|
||||
<< this->waypointsNavigator_->getWaypoints().size());
|
||||
}
|
||||
|
||||
void CbNavigateNextWaypointFree::onExit() {}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,37 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_navigate_next_waypoint_until_reached.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbNavigateNextWaypointUntilReached::CbNavigateNextWaypointUntilReached(
|
||||
std::string goalWaypointName, std::optional<NavigateNextWaypointOptions> options)
|
||||
: CbNavigateNextWaypoint(options), goalWaypointName_(goalWaypointName)
|
||||
{
|
||||
}
|
||||
|
||||
CbNavigateNextWaypointUntilReached::~CbNavigateNextWaypointUntilReached() {}
|
||||
|
||||
void CbNavigateNextWaypointUntilReached::onEntry() { CbNavigateNextWaypoint::onEntry(); }
|
||||
|
||||
void CbNavigateNextWaypointUntilReached::onExit() { CbNavigateNextWaypoint::onExit(); }
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,51 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#include <cl_nav2z/client_behaviors/cb_pause_slam.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbPauseSlam::CbPauseSlam(std::string serviceName)
|
||||
: smacc2::client_behaviors::CbServiceCall<slam_toolbox::srv::Pause>(serviceName.c_str())
|
||||
{
|
||||
}
|
||||
|
||||
void CbPauseSlam::onEntry()
|
||||
{
|
||||
this->requiresComponent(this->slam_);
|
||||
|
||||
auto currentState = slam_->getState();
|
||||
|
||||
if (currentState == CpSlamToolbox::SlamToolboxState::Resumed)
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CbPauseSlam] calling pause service to toggle from resumed to paused");
|
||||
this->request_ = std::make_shared<slam_toolbox::srv::Pause::Request>();
|
||||
CbServiceCall<slam_toolbox::srv::Pause>::onEntry();
|
||||
this->slam_->toggleState();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->request_ = nullptr;
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CbPauseSlam] calling skipped. The current slam state is already paused.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,199 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <angles/angles.h>
|
||||
#include <geometry_msgs/msg/twist.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_position_control_free_space.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbPositionControlFreeSpace::CbPositionControlFreeSpace()
|
||||
: targetYaw_(0), k_betta_(1.0), max_angular_yaw_speed_(1.0)
|
||||
{
|
||||
}
|
||||
|
||||
void CbPositionControlFreeSpace::updateParameters() {}
|
||||
|
||||
void CbPositionControlFreeSpace::onEntry()
|
||||
{
|
||||
auto nh = this->getNode();
|
||||
cmd_vel_pub_ = nh->create_publisher<geometry_msgs::msg::Twist>("/cmd_vel", rclcpp::QoS(1));
|
||||
|
||||
cl_nav2z::Pose * pose;
|
||||
|
||||
this->requiresComponent(pose);
|
||||
|
||||
geometry_msgs::msg::Twist cmd_vel;
|
||||
goalReached_ = false;
|
||||
|
||||
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;
|
||||
double ki_linear = 0.0;
|
||||
double kd_linear = 0.1;
|
||||
|
||||
double kp_angular = 0.5;
|
||||
double ki_angular = 0.0;
|
||||
double kd_angular = 0.1;
|
||||
|
||||
while (rclcpp::ok() && !goalReached_)
|
||||
{
|
||||
RCLCPP_INFO_STREAM_THROTTLE(
|
||||
getLogger(), *getNode()->get_clock(), 200,
|
||||
"CbPositionControlFreeSpace, current pose: " << currentPose.position.x << ", "
|
||||
<< currentPose.position.y << ", "
|
||||
<< tf2::getYaw(currentPose.orientation));
|
||||
|
||||
RCLCPP_INFO_STREAM_THROTTLE(
|
||||
getLogger(), *getNode()->get_clock(), 200,
|
||||
"CbPositionControlFreeSpace, target pose: " << target_pose_.position.x << ", "
|
||||
<< target_pose_.position.y << ", "
|
||||
<< tf2::getYaw(target_pose_.orientation));
|
||||
|
||||
tf2::Quaternion q;
|
||||
currentPose = pose->toPoseMsg();
|
||||
|
||||
// Here we implement the control logic to calculate the velocity command
|
||||
// based on the received position of the vehicle and the target pose.
|
||||
|
||||
// Calculate the errors in x and y
|
||||
double error_x = target_pose_.position.x - currentPose.position.x;
|
||||
double error_y = target_pose_.position.y - currentPose.position.y;
|
||||
|
||||
// Calculate the distance to the target pose
|
||||
double distance_to_target = std::sqrt(error_x * error_x + error_y * error_y);
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[" << getName() << "] distance to target: " << distance_to_target
|
||||
<< " ( th: " << threshold_distance_ << ")");
|
||||
|
||||
// Check if the robot has reached the target pose
|
||||
if (distance_to_target < threshold_distance_)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "Goal reached!");
|
||||
// Stop the robot by setting the velocity commands to zero
|
||||
geometry_msgs::msg::Twist cmd_vel_msg;
|
||||
cmd_vel_msg.linear.x = 0.0;
|
||||
cmd_vel_msg.angular.z = 0.0;
|
||||
cmd_vel_pub_->publish(cmd_vel_msg);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the desired orientation angle
|
||||
double desired_yaw = std::atan2(error_y, error_x);
|
||||
|
||||
// Calculate the difference between the desired orientation and the
|
||||
// current orientation
|
||||
double yaw_error = desired_yaw - (tf2::getYaw(currentPose.orientation) + M_PI);
|
||||
|
||||
// Ensure the yaw error is within the range [-pi, pi]
|
||||
while (yaw_error > M_PI) yaw_error -= 2 * M_PI;
|
||||
while (yaw_error < -M_PI) yaw_error += 2 * M_PI;
|
||||
|
||||
// Calculate the control signals (velocity commands) using PID controllers
|
||||
double cmd_linear_x = kp_linear * distance_to_target + ki_linear * integral_linear_ +
|
||||
kd_linear * (distance_to_target - prev_error_linear_);
|
||||
double cmd_angular_z = kp_angular * yaw_error + ki_angular * integral_angular_ +
|
||||
kd_angular * (yaw_error - prev_error_angular_);
|
||||
|
||||
if (cmd_linear_x > max_linear_velocity)
|
||||
cmd_linear_x = max_linear_velocity;
|
||||
else if (cmd_linear_x < -max_linear_velocity)
|
||||
cmd_linear_x = -max_linear_velocity;
|
||||
|
||||
if (cmd_angular_z > max_angular_velocity)
|
||||
cmd_angular_z = max_angular_velocity;
|
||||
else if (cmd_angular_z < -max_angular_velocity)
|
||||
cmd_angular_z = -max_angular_velocity;
|
||||
|
||||
// Construct and publish the velocity command message
|
||||
geometry_msgs::msg::Twist cmd_vel_msg;
|
||||
|
||||
cmd_vel_msg.linear.x = cmd_linear_x;
|
||||
cmd_vel_msg.angular.z = cmd_angular_z;
|
||||
|
||||
cmd_vel_pub_->publish(cmd_vel_msg);
|
||||
|
||||
// Update errors and integrals for the next control cycle
|
||||
prev_error_linear_ = distance_to_target;
|
||||
prev_error_angular_ = yaw_error;
|
||||
integral_linear_ += distance_to_target;
|
||||
integral_angular_ += yaw_error;
|
||||
|
||||
// tf2::fromMsg(currentPose.orientation, q);
|
||||
// auto currentYaw = tf2::getYaw(currentPose.orientation);
|
||||
// auto deltaAngle = angles::shortest_angular_distance(prevyaw,
|
||||
// currentYaw); countAngle += deltaAngle;
|
||||
|
||||
// prevyaw = currentYaw;
|
||||
// double angular_error = targetYaw_ - countAngle;
|
||||
|
||||
// auto omega = angular_error * k_betta_;
|
||||
// cmd_vel.linear.x = 0;
|
||||
// cmd_vel.linear.y = 0;
|
||||
// cmd_vel.linear.z = 0;
|
||||
// cmd_vel.angular.z =
|
||||
// std::min(std::max(omega, -fabs(max_angular_yaw_speed_)),
|
||||
// fabs(max_angular_yaw_speed_));
|
||||
|
||||
// RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] delta angle: "
|
||||
// << deltaAngle); RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "]
|
||||
// cummulated angle: " << countAngle); RCLCPP_INFO_STREAM(getLogger(), "["
|
||||
// << getName() << "] k_betta_: " << k_betta_);
|
||||
|
||||
// RCLCPP_INFO_STREAM(
|
||||
// getLogger(), "[" << getName() << "] angular error: " << angular_error
|
||||
// << "("
|
||||
// << yaw_goal_tolerance_rads_ << ")");
|
||||
// RCLCPP_INFO_STREAM(
|
||||
// getLogger(), "[" << getName() << "] command angular speed: " <<
|
||||
// cmd_vel.angular.z);
|
||||
|
||||
// if (fabs(angular_error) < yaw_goal_tolerance_rads_)
|
||||
// {
|
||||
// RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] GOAL REACHED.
|
||||
// Sending stop command."); goalReached_ = true; cmd_vel.linear.x = 0;
|
||||
// cmd_vel.angular.z = 0;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// this->cmd_vel_pub_->publish(cmd_vel);
|
||||
|
||||
loop_rate.sleep();
|
||||
}
|
||||
}
|
||||
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] Finished behavior execution");
|
||||
|
||||
this->postSuccessEvent();
|
||||
}
|
||||
|
||||
void CbPositionControlFreeSpace::onExit() {}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,102 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <angles/angles.h>
|
||||
#include <cl_nav2z/client_behaviors/cb_pure_spinning.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
#include <geometry_msgs/msg/twist.hpp>
|
||||
#include <sensor_msgs/msg/laser_scan.hpp>
|
||||
namespace cl_nav2z
|
||||
{
|
||||
|
||||
CbPureSpinning::CbPureSpinning(double targetYaw_rads, double max_angular_yaw_speed)
|
||||
: targetYaw__rads(targetYaw_rads),
|
||||
k_betta_(1.0),
|
||||
max_angular_yaw_speed_(max_angular_yaw_speed),
|
||||
yaw_goal_tolerance_rads_(0.1)
|
||||
{
|
||||
}
|
||||
|
||||
void CbPureSpinning::updateParameters() {}
|
||||
|
||||
void CbPureSpinning::onEntry()
|
||||
{
|
||||
auto nh = this->getNode();
|
||||
cmd_vel_pub_ = nh->create_publisher<geometry_msgs::msg::Twist>("/cmd_vel", rclcpp::QoS(1));
|
||||
|
||||
cl_nav2z::Pose * pose;
|
||||
this->requiresComponent(pose);
|
||||
|
||||
geometry_msgs::msg::Twist cmd_vel;
|
||||
goalReached_ = false;
|
||||
|
||||
geometry_msgs::msg::Pose currentPose = pose->toPoseMsg();
|
||||
|
||||
rclcpp::Rate loop_rate(10);
|
||||
double countAngle = 0;
|
||||
auto prevyaw = tf2::getYaw(currentPose.orientation);
|
||||
while (rclcpp::ok() && !goalReached_)
|
||||
{
|
||||
tf2::Quaternion q;
|
||||
currentPose = pose->toPoseMsg();
|
||||
tf2::fromMsg(currentPose.orientation, q);
|
||||
auto currentYaw = tf2::getYaw(currentPose.orientation);
|
||||
auto deltaAngle = angles::shortest_angular_distance(prevyaw, currentYaw);
|
||||
countAngle += deltaAngle;
|
||||
|
||||
prevyaw = currentYaw;
|
||||
double angular_error = targetYaw__rads - countAngle;
|
||||
|
||||
auto omega = angular_error * k_betta_;
|
||||
cmd_vel.linear.x = 0;
|
||||
cmd_vel.linear.y = 0;
|
||||
cmd_vel.linear.z = 0;
|
||||
cmd_vel.angular.z =
|
||||
std::min(std::max(omega, -fabs(max_angular_yaw_speed_)), fabs(max_angular_yaw_speed_));
|
||||
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] delta angle: " << deltaAngle);
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] cummulated angle: " << countAngle);
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] k_betta_: " << k_betta_);
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[" << getName() << "] angular error: " << angular_error << "("
|
||||
<< yaw_goal_tolerance_rads_ << ")");
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[" << getName() << "] command angular speed: " << cmd_vel.angular.z);
|
||||
|
||||
if (fabs(angular_error) < yaw_goal_tolerance_rads_)
|
||||
{
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] GOAL REACHED. Sending stop command.");
|
||||
goalReached_ = true;
|
||||
cmd_vel.linear.x = 0;
|
||||
cmd_vel.angular.z = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
this->cmd_vel_pub_->publish(cmd_vel);
|
||||
|
||||
loop_rate.sleep();
|
||||
}
|
||||
|
||||
this->postSuccessEvent();
|
||||
}
|
||||
|
||||
void CbPureSpinning::onExit() {}
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,51 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#include <cl_nav2z/client_behaviors/cb_resume_slam.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbResumeSlam::CbResumeSlam(std::string serviceName)
|
||||
: smacc2::client_behaviors::CbServiceCall<slam_toolbox::srv::Pause>(serviceName.c_str())
|
||||
{
|
||||
}
|
||||
|
||||
void CbResumeSlam::onEntry()
|
||||
{
|
||||
this->requiresComponent(this->slam_);
|
||||
|
||||
auto currentState = slam_->getState();
|
||||
|
||||
if (currentState == CpSlamToolbox::SlamToolboxState::Paused)
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CbResumeSlam] calling pause service to toggle from paused to resumed");
|
||||
this->request_ = std::make_shared<slam_toolbox::srv::Pause::Request>();
|
||||
smacc2::client_behaviors::CbServiceCall<slam_toolbox::srv::Pause>::onEntry();
|
||||
this->slam_->toggleState();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->request_ = nullptr;
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CbResumeSlam] calling skipped. The current slam state is already resumed.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,86 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#include <geometry_msgs/msg/quaternion_stamped.hpp>
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_rotate.hpp>
|
||||
#include <cl_nav2z/common.hpp>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbRotate::CbRotate(float rotate_degree) : rotateDegree(rotate_degree) {}
|
||||
|
||||
CbRotate::CbRotate(float rotate_degree, SpinningPlanner spinning_planner)
|
||||
: rotateDegree(rotate_degree), spinningPlanner(spinning_planner)
|
||||
{
|
||||
}
|
||||
|
||||
void CbRotate::onEntry()
|
||||
{
|
||||
double angle_increment_degree = rotateDegree;
|
||||
|
||||
auto plannerSwitcher = this->getComponent<CpPlannerSwitcher>();
|
||||
|
||||
if (spinningPlanner && *spinningPlanner == SpinningPlanner::PureSpinning)
|
||||
{
|
||||
plannerSwitcher->setPureSpinningPlanner();
|
||||
}
|
||||
else
|
||||
{
|
||||
plannerSwitcher->setDefaultPlanners();
|
||||
}
|
||||
|
||||
auto p = this->getComponent<cl_nav2z::Pose>();
|
||||
auto referenceFrame = p->getReferenceFrame();
|
||||
auto currentPoseMsg = p->toPoseMsg();
|
||||
|
||||
tf2::Transform currentPose;
|
||||
tf2::fromMsg(currentPoseMsg, currentPose);
|
||||
|
||||
auto odomTracker = this->getComponent<odom_tracker::CpOdomTracker>();
|
||||
nav2_msgs::action::NavigateToPose::Goal goal;
|
||||
goal.pose.header.frame_id = referenceFrame;
|
||||
//goal.pose.header.stamp = getNode()->now();
|
||||
|
||||
auto currentAngle = tf2::getYaw(currentPoseMsg.orientation);
|
||||
auto targetAngle = currentAngle + angle_increment_degree * M_PI / 180.0;
|
||||
goal.pose.pose.position = currentPoseMsg.position;
|
||||
tf2::Quaternion q;
|
||||
q.setRPY(0, 0, targetAngle);
|
||||
goal.pose.pose.orientation = tf2::toMsg(q);
|
||||
|
||||
geometry_msgs::msg::PoseStamped stampedCurrentPoseMsg;
|
||||
stampedCurrentPoseMsg.header.frame_id = referenceFrame;
|
||||
stampedCurrentPoseMsg.header.stamp = getNode()->now();
|
||||
stampedCurrentPoseMsg.pose = currentPoseMsg;
|
||||
|
||||
auto pathname = this->getCurrentState()->getName() + " - " + getName();
|
||||
odomTracker->pushPath(pathname);
|
||||
|
||||
odomTracker->setStartPoint(stampedCurrentPoseMsg);
|
||||
odomTracker->setWorkingMode(odom_tracker::WorkingMode::RECORD_PATH);
|
||||
|
||||
RCLCPP_INFO_STREAM(getLogger(), "current pose: " << currentPoseMsg);
|
||||
RCLCPP_INFO_STREAM(getLogger(), "goal pose: " << goal.pose.pose);
|
||||
this->sendGoal(goal);
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,58 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_rotate_look_at.hpp>
|
||||
#include <cl_nav2z/common.hpp>
|
||||
#include <cl_nav2z/components/goal_checker_switcher/cp_goal_checker_switcher.hpp>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
#include <rclcpp/parameter_client.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbRotateLookAt::CbRotateLookAt() {}
|
||||
|
||||
CbRotateLookAt::CbRotateLookAt(const geometry_msgs::msg::PoseStamped & lookAtPose)
|
||||
: lookAtPose_(lookAtPose)
|
||||
{
|
||||
}
|
||||
|
||||
void CbRotateLookAt::onEntry()
|
||||
{
|
||||
cl_nav2z::Pose * pose;
|
||||
this->requiresComponent(pose);
|
||||
|
||||
pose->waitTransformUpdate(rclcpp::Rate(20));
|
||||
auto position = pose->toPoseMsg().position;
|
||||
|
||||
if (lookAtPose_)
|
||||
{
|
||||
auto targetPosition = lookAtPose_->pose.position;
|
||||
double yaw_degrees =
|
||||
atan2(targetPosition.y - position.y, targetPosition.x - position.x) * 180.0 / M_PI;
|
||||
this->absoluteGoalAngleDegree = yaw_degrees;
|
||||
}
|
||||
|
||||
CbAbsoluteRotate::onEntry();
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,85 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <angles/angles.h>
|
||||
#include <chrono>
|
||||
#include <cl_nav2z/client_behaviors/cb_save_slam_map.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
#include <geometry_msgs/msg/twist.hpp>
|
||||
#include <memory>
|
||||
#include <nav2_msgs/srv/save_map.hpp>
|
||||
#include <slam_toolbox/srv/save_map.hpp>
|
||||
#include <smacc2/client_behaviors/cb_call_service.hpp>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
#include <std_msgs/msg/string.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CbSaveSlamMap::CbSaveSlamMap() : CbServiceCall("/map_saver/save_map", getRequest())
|
||||
{
|
||||
// : CbServiceCall("/slam_toolbox/save_map",
|
||||
// getRequest()) {
|
||||
|
||||
// map_name.data = "saved_map";
|
||||
// auto request = getRequest(map_name);
|
||||
// RCLCPP_INFO_STREAM(getLogger(), "Save Slam Map builded");
|
||||
}
|
||||
|
||||
// void onEntry() override {}
|
||||
|
||||
void CbSaveSlamMap::onExit() {}
|
||||
|
||||
std::shared_ptr<nav2_msgs::srv::SaveMap::Request> CbSaveSlamMap::getRequest(
|
||||
/*slam_toolbox::srv::SaveMap_Request_<std::allocator<void> >::_name_type saved_map_name*/)
|
||||
{
|
||||
nav2_msgs::srv::SaveMap_Request map_save;
|
||||
std_msgs::msg::String map_name;
|
||||
|
||||
// // map_name.data = "saved_map";
|
||||
// map_save.map_topic = "map";
|
||||
// map_save.map_url = "${workspacesFolder}/maps/saved_map";
|
||||
// map_save.image_format = "png";
|
||||
// map_save.occupied_thresh = 0.65;
|
||||
// map_save.free_thresh = 0.25;
|
||||
// map_save.map_mode = "trinary";
|
||||
|
||||
// // auto request = std::make_shared<slam_toolbox::srv::SaveMap::Request>();
|
||||
// // // request->name = saved_map_name;
|
||||
// // request->name = map_name;
|
||||
// // return request;
|
||||
// auto request = std::make_shared<nav2_msgs::srv::SaveMap::Request>(map_save);
|
||||
|
||||
auto request = std::make_shared<nav2_msgs::srv::SaveMap::Request>();
|
||||
request->map_topic = "map";
|
||||
request->map_url = "/tmp/saved_map";
|
||||
request->image_format = "png";
|
||||
request->occupied_thresh = 0.65;
|
||||
request->free_thresh = 0.25;
|
||||
request->map_mode = "trinary";
|
||||
|
||||
return request;
|
||||
}
|
||||
} // namespace cl_nav2z
|
||||
|
||||
// slam_toolbox::srv::SaveMap_Request_<std::allocator<void> >::_name_type
|
||||
|
||||
// std_msgs::msg::String_<std::allocator<void> >
|
||||
@@ -1,50 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_seek_waypoint.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbSeekWaypoint::CbSeekWaypoint(std::string seekWaypointName)
|
||||
: count_(std::nullopt), seekWaypointName_(seekWaypointName)
|
||||
{
|
||||
}
|
||||
|
||||
CbSeekWaypoint::~CbSeekWaypoint() {}
|
||||
|
||||
void CbSeekWaypoint::onEntry()
|
||||
{
|
||||
this->requiresComponent(waypointsNavigator_);
|
||||
|
||||
if (count_)
|
||||
{
|
||||
waypointsNavigator_->forward(*count_);
|
||||
count_ = std::nullopt;
|
||||
}
|
||||
else if (seekWaypointName_)
|
||||
{
|
||||
waypointsNavigator_->seekName(*seekWaypointName_);
|
||||
seekWaypointName_ = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void CbSeekWaypoint::onExit() {}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,136 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <angles/angles.h>
|
||||
#include <cl_nav2z/client_behaviors/cb_spiral_motion.hpp>
|
||||
#include <geometry_msgs/msg/twist.hpp>
|
||||
#include <optional>
|
||||
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
|
||||
CbSpiralMotion::CbSpiralMotion(std::optional<CbSpiralMotionOptions> options)
|
||||
{
|
||||
if (options)
|
||||
{
|
||||
options_ = *options;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we use default options
|
||||
options_ = CbSpiralMotionOptions();
|
||||
}
|
||||
}
|
||||
|
||||
void CbSpiralMotion::onEntry()
|
||||
{
|
||||
/*
|
||||
struct CbSpiralMotionOptions
|
||||
{
|
||||
std::optional<float> linearVelocity = 0.0f;
|
||||
std::optional<float> maxLinearVelocity = 1.0f;
|
||||
std::optional<float> initialAngularVelocity = 1.0f;
|
||||
std::optional<rclcpp::Duration> spiralMotionDuration = rclcpp::Duration::from_seconds(120);
|
||||
std::optional <float> finalRadius=10.0f;//meters
|
||||
};
|
||||
*/
|
||||
|
||||
auto linearVelocity = *(options_.linearVelocity);
|
||||
auto maxLinearVelocity = *(options_.maxLinearVelocity);
|
||||
auto initialAngularVelocity = *(options_.initialAngularVelocity);
|
||||
auto spiralMotionDuration = *(options_.spiralMotionDuration);
|
||||
auto finalRadius = *(options_.finalRadius);
|
||||
|
||||
float rate = 20.0f;
|
||||
rclcpp::Rate r(rate);
|
||||
cmdVelPub_ = getNode()->create_publisher<geometry_msgs::msg::Twist>("/cmd_vel", rclcpp::QoS(1));
|
||||
|
||||
rclcpp::Duration linearRamp = rclcpp::Duration::from_seconds(spiralMotionDuration.seconds());
|
||||
float linearAceleration = (maxLinearVelocity - linearVelocity) / linearRamp.seconds();
|
||||
float dt = 1.0f / rate;
|
||||
|
||||
// we know final radious and the constant linear velocity
|
||||
float finalAngularVelocity = maxLinearVelocity / finalRadius;
|
||||
|
||||
float angularAcceleration =
|
||||
(initialAngularVelocity - finalAngularVelocity) / spiralMotionDuration.seconds();
|
||||
|
||||
geometry_msgs::msg::Twist cmd_vel;
|
||||
|
||||
cmd_vel.linear.x = linearVelocity;
|
||||
cmd_vel.angular.z = initialAngularVelocity;
|
||||
auto start_time = getNode()->now();
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[CbSpiralMotion]: initialAngularVelocity: "
|
||||
<< initialAngularVelocity << ", finalAngularVelocity: " << finalAngularVelocity
|
||||
<< ", angularAcceleration: " << angularAcceleration);
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[CbSpiralMotion]: linearAceleration: "
|
||||
<< linearAceleration << ", maxLinearVelocity: " << maxLinearVelocity);
|
||||
|
||||
bool end_condition = false;
|
||||
|
||||
while (!end_condition)
|
||||
{
|
||||
auto current_time = getNode()->now() - start_time;
|
||||
|
||||
cmd_vel.linear.x += linearAceleration * dt;
|
||||
if (cmd_vel.linear.x > maxLinearVelocity)
|
||||
{
|
||||
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();
|
||||
cmd_vel.angular.z = initialAngularVelocity * (1.0f - ellapsedTimeFactor) +
|
||||
finalAngularVelocity * ellapsedTimeFactor;
|
||||
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CbSpiralMotion] cmd_vel.linear.x = %f, cmd_vel.angular.z = %f",
|
||||
cmd_vel.linear.x, cmd_vel.angular.z);
|
||||
|
||||
cmdVelPub_->publish(cmd_vel);
|
||||
r.sleep();
|
||||
|
||||
auto now = getNode()->now();
|
||||
|
||||
rclcpp::Duration ellapsed = now - start_time;
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[CbSpiralMotion] ellapsed time: " << ellapsed.seconds() << ", total duration: "
|
||||
<< spiralMotionDuration.seconds());
|
||||
if (ellapsed > spiralMotionDuration)
|
||||
{
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CbSpiralMotion] spiralMotionDuration reached");
|
||||
end_condition = true;
|
||||
}
|
||||
}
|
||||
|
||||
// asynchronous client behaviors usually post a success event when they are done
|
||||
// that is used in states to transition to the next state
|
||||
this->postSuccessEvent();
|
||||
}
|
||||
|
||||
void CbSpiralMotion::onExit() {}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,52 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/client_behaviors/cb_abort_navigation.hpp>
|
||||
#include <cl_nav2z/common.hpp>
|
||||
#include <cl_nav2z/components/goal_checker_switcher/cp_goal_checker_switcher.hpp>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
#include <rclcpp/parameter_client.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbStopNavigation::CbStopNavigation() {}
|
||||
|
||||
void CbStopNavigation::onEntry()
|
||||
{
|
||||
// this->sendGoal(goal);
|
||||
|
||||
// this->cancelGoal();
|
||||
|
||||
cl_nav2z::Pose * poseComponent;
|
||||
this->requiresComponent(poseComponent);
|
||||
|
||||
this->setGoal(poseComponent->toPoseMsg());
|
||||
|
||||
CbNavigateGlobalPosition::onEntry();
|
||||
|
||||
// this->sendGoal(goal);
|
||||
}
|
||||
|
||||
void CbStopNavigation::onExit() {}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,49 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_track_path_odometry.hpp>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbTrackPathOdometry::CbTrackPathOdometry() {}
|
||||
|
||||
void CbTrackPathOdometry::onEntry()
|
||||
{
|
||||
RCLCPP_INFO(this->getLogger(), "Pose tracker freeze reference frame");
|
||||
cl_nav2z::Pose * poseComponent;
|
||||
requiresComponent(poseComponent);
|
||||
poseComponent->freezeReferenceFrame();
|
||||
|
||||
// poseComponent->setReferenceFrame("odom");
|
||||
|
||||
RCLCPP_INFO(this->getLogger(), "Odom tracker clear path");
|
||||
cl_nav2z::odom_tracker::CpOdomTracker * odomTracker;
|
||||
this->requiresComponent(odomTracker);
|
||||
// odomTracker->setOdomFrame("odom");
|
||||
|
||||
odomTracker->clearPath();
|
||||
}
|
||||
|
||||
void CbTrackPathOdometry::onExit() {}
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,49 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_track_path_slam.hpp>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
|
||||
CbTrackPathSLAM::CbTrackPathSLAM() {}
|
||||
|
||||
void CbTrackPathSLAM::onEntry()
|
||||
{
|
||||
RCLCPP_INFO(this->getLogger(), "Pose tracker freeze reference frame");
|
||||
cl_nav2z::Pose * poseComponent;
|
||||
requiresComponent(poseComponent);
|
||||
poseComponent->unfreezeReferenceFrame();
|
||||
// poseComponent->setReferenceFrame("odom");
|
||||
|
||||
RCLCPP_INFO(this->getLogger(), "Odom tracker clear path");
|
||||
cl_nav2z::odom_tracker::CpOdomTracker * odomTracker;
|
||||
this->requiresComponent(odomTracker);
|
||||
// odomTracker->setOdomFrame("odom");
|
||||
|
||||
odomTracker->clearPath();
|
||||
}
|
||||
|
||||
void CbTrackPathSLAM::onExit() {}
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,131 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_undo_path_backwards.hpp>
|
||||
#include <cl_nav2z/common.hpp>
|
||||
#include <cl_nav2z/components/goal_checker_switcher/cp_goal_checker_switcher.hpp>
|
||||
#include <cl_nav2z/components/planner_switcher/cp_planner_switcher.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
using ::cl_nav2z::odom_tracker::CpOdomTracker;
|
||||
using ::cl_nav2z::odom_tracker::WorkingMode;
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CbUndoPathBackwards::CbUndoPathBackwards(std::optional<CbUndoPathBackwardsOptions> options)
|
||||
{
|
||||
options_ = options;
|
||||
}
|
||||
|
||||
void CbUndoPathBackwards::onEntry()
|
||||
{
|
||||
listener = std::make_shared<tf2_ros::Buffer>(this->getNode()->get_clock());
|
||||
odomTracker = this->getComponent<CpOdomTracker>();
|
||||
|
||||
odomTracker->logStateString(false);
|
||||
|
||||
auto plannerSwitcher = this->getComponent<CpPlannerSwitcher>();
|
||||
|
||||
nav_msgs::msg::Path forwardpath = odomTracker->getPath();
|
||||
// RCLCPP_INFO_STREAM(getLogger(),"[UndoPathBackward] Current path backwards: " << forwardpath);
|
||||
|
||||
odomTracker->setWorkingMode(WorkingMode::CLEAR_PATH);
|
||||
|
||||
nav2_msgs::action::NavigateToPose::Goal goal;
|
||||
|
||||
auto goalCheckerSwitcher = this->getComponent<CpGoalCheckerSwitcher>();
|
||||
|
||||
// this line is used to flush/reset backward planner in the case it were already there
|
||||
// plannerSwitcher->setDefaultPlanners();
|
||||
if (forwardpath.poses.size() > 0)
|
||||
{
|
||||
goal.pose = forwardpath.poses.front();
|
||||
//goal.pose.header.stamp = getNode()->now();
|
||||
goal.pose.header.stamp = rclcpp::Time(0);
|
||||
|
||||
if (options_ && options_->undoControllerName_)
|
||||
{
|
||||
plannerSwitcher->setUndoPathBackwardPlanner(false);
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(),
|
||||
"[" << getName() << "] Undoing path with controller: " << *options_->undoControllerName_);
|
||||
plannerSwitcher->setDesiredController(*options_->undoControllerName_);
|
||||
plannerSwitcher->commitPublish();
|
||||
}
|
||||
else
|
||||
{
|
||||
plannerSwitcher->setUndoPathBackwardPlanner();
|
||||
}
|
||||
|
||||
// WARNING: There might be some race condition with the remote undo global planner/controller were the global path was not
|
||||
// received yet, thee goal switcher
|
||||
// TODO: waiting notification from global planner that it is loaded
|
||||
|
||||
RCLCPP_ERROR_STREAM(
|
||||
getLogger(), "[" << getName()
|
||||
<< "] Waiting for 5 seconds to get planer/controller and wait goal checker "
|
||||
"ready");
|
||||
|
||||
// rclcpp::sleep_for(5s);
|
||||
RCLCPP_ERROR_STREAM(getLogger(), "[" << getName() << "] activating undo navigation planner");
|
||||
|
||||
if (options_ && options_->goalCheckerId_)
|
||||
{
|
||||
goalCheckerSwitcher->setGoalCheckerId(*options_->goalCheckerId_);
|
||||
}
|
||||
else
|
||||
{
|
||||
goalCheckerSwitcher->setGoalCheckerId("undo_path_backwards_goal_checker");
|
||||
}
|
||||
|
||||
this->sendGoal(goal);
|
||||
}
|
||||
}
|
||||
|
||||
void CbUndoPathBackwards::onExit()
|
||||
{
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] Exiting: undo navigation ");
|
||||
|
||||
if (this->navigationResult_ == rclcpp_action::ResultCode::SUCCEEDED)
|
||||
{
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), getName() << " - [CbUndoPathBackwards] Exiting: undo navigation successful, "
|
||||
"popping odom tracker path");
|
||||
odomTracker = this->getComponent<CpOdomTracker>();
|
||||
odomTracker->popPath();
|
||||
|
||||
odomTracker->logStateString(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), getName() << " - [CbUndoPathBackwards] Exiting: undo navigation abort, avoiding "
|
||||
"popping current path");
|
||||
|
||||
odomTracker = this->getComponent<CpOdomTracker>();
|
||||
odomTracker->logStateString(false);
|
||||
// navigation interrupted or aborted. The path may be not totally undone.
|
||||
// We keep the odom tracker in its current state, probably in the middle of the undoing process.
|
||||
// Could you try to repeat the behavior?
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,133 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_wait_nav2_nodes.hpp>
|
||||
#include <cl_nav2z/common.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbWaitNav2Nodes::CbWaitNav2Nodes(std::vector<Nav2Nodes> waitNodes)
|
||||
: CbWaitNav2Nodes("/bond", waitNodes)
|
||||
{
|
||||
}
|
||||
|
||||
CbWaitNav2Nodes::CbWaitNav2Nodes(std::string topic, std::vector<Nav2Nodes> waitNodes)
|
||||
: topicname_(topic), waitNodes_(waitNodes)
|
||||
{
|
||||
}
|
||||
|
||||
void CbWaitNav2Nodes::onMessageReceived(const bond::msg::Status & msg)
|
||||
{
|
||||
auto value = fromString(msg.id);
|
||||
bool updated = false;
|
||||
// RCLCPP_INFO(getLogger(), "[CbWaitNav2Nodes] received '%s'", msg.id.c_str());
|
||||
|
||||
if (receivedAliveMsg_.count(value) && !receivedAliveMsg_[value])
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CbWaitNav2Nodes] '%s' alive received", msg.id.c_str());
|
||||
receivedAliveMsg_[value] = true;
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (updated)
|
||||
{
|
||||
bool success = true;
|
||||
std::stringstream ss;
|
||||
for (auto & pair : receivedAliveMsg_)
|
||||
{
|
||||
if (!pair.second)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
ss << "- " << toString(pair.first) << ": " << (pair.second ? "ALIVE" : "WAITING")
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[CbWaitNav2Nodes] waiting nodes status:" << std::endl
|
||||
<< ss.str().c_str());
|
||||
|
||||
if (success)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CbWaitNav2Nodes] success event");
|
||||
this->postSuccessEvent();
|
||||
sub_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CbWaitNav2Nodes] still missing nodes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CbWaitNav2Nodes::onEntry()
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (auto v : waitNodes_)
|
||||
{
|
||||
receivedAliveMsg_[v] = false;
|
||||
ss << "[CbWaitNav2Nodes] - " << toString(v) << ": waiting" << std::endl;
|
||||
}
|
||||
RCLCPP_INFO(getLogger(), ss.str().c_str());
|
||||
|
||||
//rclcpp::SensorDataQoS qos;
|
||||
rclcpp::SubscriptionOptions sub_option;
|
||||
|
||||
sub_ = getNode()->create_subscription<bond::msg::Status>(
|
||||
topicname_, 20, std::bind(&CbWaitNav2Nodes::onMessageReceived, this, std::placeholders::_1),
|
||||
sub_option);
|
||||
}
|
||||
|
||||
std::string toString(Nav2Nodes value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case Nav2Nodes::PlannerServer:
|
||||
return "planner_server";
|
||||
case Nav2Nodes::ControllerServer:
|
||||
return "controller_server";
|
||||
case Nav2Nodes::RecoveriesServer:
|
||||
return "behavior_server";
|
||||
case Nav2Nodes::BtNavigator:
|
||||
return "bt_navigator";
|
||||
case Nav2Nodes::MapServer:
|
||||
return "map_server";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
Nav2Nodes fromString(std::string id)
|
||||
{
|
||||
if (id == "planner_server")
|
||||
return Nav2Nodes::PlannerServer;
|
||||
else if (id == "controller_server")
|
||||
return Nav2Nodes::ControllerServer;
|
||||
else if (id == "behavior_server")
|
||||
return Nav2Nodes::RecoveriesServer;
|
||||
else if (id == "bt_navigator")
|
||||
return Nav2Nodes::BtNavigator;
|
||||
else if (id == "map_server")
|
||||
return Nav2Nodes::MapServer;
|
||||
else
|
||||
return Nav2Nodes::None;
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,53 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/client_behaviors/cb_wait_pose.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
#include <cl_nav2z/common.hpp>
|
||||
#include <rclcpp/parameter_client.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbWaitPose::CbWaitPose() {}
|
||||
|
||||
CbWaitPose::~CbWaitPose() {}
|
||||
|
||||
void CbWaitPose::onEntry()
|
||||
{
|
||||
cl_nav2z::Pose * pose = nullptr;
|
||||
this->requiresComponent(pose);
|
||||
try
|
||||
{
|
||||
pose->waitTransformUpdate(rclcpp::Rate(20));
|
||||
auto posemsg = pose->toPoseMsg();
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CbWaitPose] pose arrived: " << std::endl << posemsg);
|
||||
}
|
||||
catch (std::exception & ex)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CbWaitPose] error getting the robot pose");
|
||||
this->postFailureEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
RCLCPP_INFO(getLogger(), "[CbWaitPose] pose received");
|
||||
this->postSuccessEvent();
|
||||
}
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,63 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#include <cl_nav2z/client_behaviors/cb_wait_transform.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CbWaitTransform::CbWaitTransform(
|
||||
std::string targetFrame, std::string referenceFrame, rclcpp::Duration timeout)
|
||||
: targetFrame_(targetFrame), referenceFrame_(referenceFrame), timeout_(timeout)
|
||||
{
|
||||
}
|
||||
|
||||
CbWaitTransform::~CbWaitTransform() {}
|
||||
|
||||
void CbWaitTransform::onEntry()
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CbWaitTransform] ref %s -> target %s", referenceFrame_.c_str(),
|
||||
targetFrame_.c_str());
|
||||
|
||||
tfBuffer_ = std::make_shared<tf2_ros::Buffer>(getNode()->get_clock());
|
||||
tfListener_ = std::make_shared<tf2_ros::TransformListener>(*tfBuffer_);
|
||||
|
||||
tf2::Stamped<tf2::Transform> transform;
|
||||
try
|
||||
{
|
||||
auto transformstamped =
|
||||
tfBuffer_->lookupTransform(targetFrame_, referenceFrame_, getNode()->now(), timeout_);
|
||||
tf2::fromMsg(transformstamped, transform);
|
||||
|
||||
result_ = transform;
|
||||
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CbWaitTransform] Success wait transform ref %s -> target %s",
|
||||
referenceFrame_.c_str(), targetFrame_.c_str());
|
||||
this->postSuccessEvent();
|
||||
}
|
||||
catch (tf2::TransformException & ex)
|
||||
{
|
||||
RCLCPP_ERROR_STREAM(
|
||||
getLogger(), "[CbWaitTransform] Failure waiting transform ( ref "
|
||||
<< targetFrame_ << "/ target " << referenceFrame_ << " - " << ex.what());
|
||||
this->postFailureEvent();
|
||||
}
|
||||
}
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,64 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/common.hpp>
|
||||
|
||||
#include <tf2/utils.h>
|
||||
#include <rclcpp/rclcpp.hpp>
|
||||
#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
|
||||
|
||||
std::ostream & operator<<(std::ostream & out, const geometry_msgs::msg::Quaternion & msg)
|
||||
{
|
||||
out << " Orientation [" << msg.x << " , " << msg.y << " , " << msg.z << ", " << msg.w
|
||||
<< "] , yaw: " << tf2::getYaw(msg);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & out, const geometry_msgs::msg::Point & msg)
|
||||
{
|
||||
out << "[" << msg.x << " , " << msg.y << " , " << msg.z << "]";
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & out, const geometry_msgs::msg::Pose & msg)
|
||||
{
|
||||
out << " p " << msg.position;
|
||||
out << " q [" << msg.orientation.x << " , " << msg.orientation.y << " , " << msg.orientation.z
|
||||
<< ", " << msg.orientation.w << "]";
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & out, const geometry_msgs::msg::PoseStamped & msg)
|
||||
{
|
||||
out << msg.pose;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & out, const nav2_msgs::action::NavigateToPose::Goal & msg)
|
||||
{
|
||||
out << msg.pose;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & out, const builtin_interfaces::msg::Time & msg)
|
||||
{
|
||||
out << "seconds: " << rclcpp::Time(msg).seconds();
|
||||
return out;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#include <cl_nav2z/components/amcl/cp_amcl.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CpAmcl::CpAmcl() {}
|
||||
|
||||
CpAmcl::~CpAmcl() {}
|
||||
|
||||
std::string CpAmcl::getName() const { return "AMCL"; }
|
||||
|
||||
void CpAmcl::onInitialize()
|
||||
{
|
||||
initalPosePub_ = getNode()->create_publisher<geometry_msgs::msg::PoseWithCovarianceStamped>(
|
||||
"initialpose", rclcpp::QoS(10));
|
||||
}
|
||||
|
||||
void CpAmcl::setInitialPose(const geometry_msgs::msg::PoseWithCovarianceStamped & initialpose)
|
||||
{
|
||||
initalPosePub_->publish(initialpose);
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,162 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#include <cl_nav2z/components/costmap_switch/cp_costmap_switch.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
std::array<std::string, 4> CpCostmapSwitch::layerNames = {
|
||||
"global_costmap/obstacles_layer",
|
||||
"local_costmap/obstacles_layer"
|
||||
"global_costmap/inflater_layer",
|
||||
"local_costmap/inflater_layer"};
|
||||
|
||||
void CpCostmapSwitch::registerProxyFromDynamicReconfigureServer(
|
||||
std::string costmapName, std::string enablePropertyName)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CpCostmapSwitch] registering costmap type: %s", costmapName.c_str());
|
||||
auto proxy = std::make_shared<CpCostmapProxy>(
|
||||
this->nav2zClient_->getName() + "/" + costmapName, enablePropertyName, getNode());
|
||||
costmapProxies[costmapName] = proxy;
|
||||
}
|
||||
|
||||
CpCostmapSwitch::CpCostmapSwitch() {}
|
||||
|
||||
void CpCostmapSwitch::onInitialize()
|
||||
{
|
||||
this->nav2zClient_ = dynamic_cast<cl_nav2z::ClNav2Z *>(owner_);
|
||||
|
||||
if (this->nav2zClient_ == nullptr)
|
||||
{
|
||||
RCLCPP_ERROR(getLogger(), "the owner of the CpCostmapSwitch must be a ClNav2Z");
|
||||
}
|
||||
|
||||
registerProxyFromDynamicReconfigureServer(
|
||||
getStandardCostmapName(StandardLayers::GLOBAL_OBSTACLES_LAYER));
|
||||
registerProxyFromDynamicReconfigureServer(
|
||||
getStandardCostmapName(StandardLayers::LOCAL_OBSTACLES_LAYER));
|
||||
registerProxyFromDynamicReconfigureServer(
|
||||
getStandardCostmapName(StandardLayers::GLOBAL_INFLATED_LAYER));
|
||||
registerProxyFromDynamicReconfigureServer(
|
||||
getStandardCostmapName(StandardLayers::LOCAL_INFLATED_LAYER));
|
||||
}
|
||||
|
||||
std::string CpCostmapSwitch::getStandardCostmapName(StandardLayers layertype)
|
||||
{
|
||||
return CpCostmapSwitch::layerNames[(int)layertype];
|
||||
}
|
||||
|
||||
bool CpCostmapSwitch::exists(std::string layerName)
|
||||
{
|
||||
if (!this->costmapProxies.count(layerName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CpCostmapSwitch::enable(std::string layerName)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CpCostmapSwitch] enabling %s", layerName.c_str());
|
||||
|
||||
if (!exists(layerName))
|
||||
{
|
||||
RCLCPP_ERROR(getLogger(), "[CpCostmapSwitch] costmap %s does not exist", layerName.c_str());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpCostmapSwitch] costmap %s found. Calling dynamic reconfigure server.",
|
||||
layerName.c_str());
|
||||
costmapProxies[layerName]->setCostmapEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void CpCostmapSwitch::enable(StandardLayers layerType)
|
||||
{
|
||||
this->enable(getStandardCostmapName(layerType));
|
||||
}
|
||||
|
||||
void CpCostmapSwitch::disable(std::string layerName)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CpCostmapSwitch] disabling %s", layerName.c_str());
|
||||
|
||||
if (!exists(layerName))
|
||||
{
|
||||
RCLCPP_ERROR(getLogger(), "[CpCostmapSwitch] costmap %s does not exist", layerName.c_str());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpCostmapSwitch] costmap %s found. Calling dynamic reconfigure server.",
|
||||
layerName.c_str());
|
||||
costmapProxies[layerName]->setCostmapEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CpCostmapSwitch::disable(StandardLayers layerType)
|
||||
{
|
||||
this->disable(getStandardCostmapName(layerType));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
CpCostmapProxy::CpCostmapProxy(
|
||||
std::string /*costmap_name*/, std::string /*enablePropertyName*/, rclcpp::Node::SharedPtr nh)
|
||||
: nh_(nh)
|
||||
{
|
||||
// this->costmapName_ = costmap_name + "/set_parameters";
|
||||
// dynamic_reconfigure::BoolParameter enableField;
|
||||
// enableField.name = "enabled";
|
||||
// enableField.value = true;
|
||||
|
||||
// enableReq.bools.push_back(enableField);
|
||||
|
||||
// enableField.value = false;
|
||||
// disableReq.bools.push_back(enableField);
|
||||
RCLCPP_ERROR(nh->get_logger(), "costmap switch not implemented %s", costmapName_.c_str());
|
||||
}
|
||||
|
||||
void CpCostmapProxy::setCostmapEnabled(bool /*value*/)
|
||||
{
|
||||
// dynamic_reconfigure::ReconfigureRequest srv_req;
|
||||
// dynamic_reconfigure::ReconfigureResponse srv_resp;
|
||||
|
||||
// if (value)
|
||||
// srv_req.config = enableReq;
|
||||
// else
|
||||
// srv_req.config = disableReq;
|
||||
|
||||
// if (ros::service::exists(costmapName_, true))
|
||||
// {
|
||||
// RCLCPP_INFO(getLogger(),"sending dynamic reconfigure request: %s", costmapName_.c_str());
|
||||
// ros::service::call(costmapName_, srv_req, srv_resp);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// RCLCPP_WARN(getLogger(),"could not call dynamic reconfigure server. It does not exist: %s", costmapName_.c_str());
|
||||
// }
|
||||
|
||||
RCLCPP_ERROR(nh_->get_logger(), "costmap switch not implemented %s", costmapName_.c_str());
|
||||
}
|
||||
|
||||
// void CpCostmapProxy::dynreconfCallback(const dynamic_reconfigure::Config::ConstPtr &configuration_update)
|
||||
// {
|
||||
// // auto gp = std::find_if(configuration_update->strs.begin(), configuration_update->strs.begin(),
|
||||
// // [&](const dynamic_reconfigure::StrParameter &p) { return p.name == "base_global_planner" && p.value == desired_global_planner_; });
|
||||
// }
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,75 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#include <cl_nav2z/components/goal_checker_switcher/cp_goal_checker_switcher.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CpGoalCheckerSwitcher::CpGoalCheckerSwitcher(
|
||||
std::string goal_checker_selector_topic, std::string default_goal_checker_name)
|
||||
: goal_checker_selector_topic_(goal_checker_selector_topic),
|
||||
default_goal_checker_name_(default_goal_checker_name)
|
||||
{
|
||||
}
|
||||
|
||||
CpGoalCheckerSwitcher::~CpGoalCheckerSwitcher() {}
|
||||
|
||||
void CpGoalCheckerSwitcher::onInitialize()
|
||||
{
|
||||
rclcpp::QoS qos(rclcpp::KeepLast(1));
|
||||
qos.transient_local().reliable();
|
||||
|
||||
this->goal_checker_selector_pub_ =
|
||||
getNode()->create_publisher<std_msgs::msg::String>(goal_checker_selector_topic_, qos);
|
||||
}
|
||||
|
||||
void CpGoalCheckerSwitcher::setDefaultGoalChecker()
|
||||
{
|
||||
setGoalCheckerId(default_goal_checker_name_); // default id in navigation2 stack
|
||||
}
|
||||
|
||||
void CpGoalCheckerSwitcher::setGoalCheckerId(std::string goalcheckerid)
|
||||
{
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[CpGoalCheckerSwitcher] Setting goal checker: " << goalcheckerid);
|
||||
|
||||
// controller_server_node_->wait_for_service();
|
||||
// std::vector<rclcpp::Parameter> params{ rclcpp::Parameter("current_goal_checker", goalcheckerid) };
|
||||
// auto futureResults = controller_server_node_->set_parameters(params);
|
||||
|
||||
std_msgs::msg::String msg;
|
||||
msg.data = goalcheckerid;
|
||||
this->goal_checker_selector_pub_->publish(msg);
|
||||
|
||||
// int i = 0;
|
||||
// for (auto& res : futureResults.get())
|
||||
// {
|
||||
// RCLCPP_INFO_STREAM(getLogger(), "[CpGoalCheckerSwitcher] parameter result: "
|
||||
// << params[i].get_name() << "=" << params[i].as_string()
|
||||
// << ". Result: " << res.successful);
|
||||
// i++;
|
||||
|
||||
// if (!res.successful)
|
||||
// RCLCPP_ERROR_STREAM(this->getLogger(), "[CpGoalCheckerSwitcher] goal checker could not properly
|
||||
// switch "
|
||||
// "the goal checker of the controller_server");
|
||||
// }
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,658 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#include <cl_nav2z/common.hpp>
|
||||
|
||||
#include <angles/angles.h>
|
||||
#include <tf2/utils.h>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <smacc2/component.hpp>
|
||||
#include <smacc2/impl/smacc_component_impl.hpp>
|
||||
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
namespace odom_tracker
|
||||
{
|
||||
CpOdomTracker::CpOdomTracker(
|
||||
std::string odomTopicName, std::string odomFrame, OdomTrackerStrategy strategy)
|
||||
: strategy_(strategy)
|
||||
{
|
||||
workingMode_ = WorkingMode::RECORD_PATH;
|
||||
publishMessages = true;
|
||||
odomFrame_ = odomFrame;
|
||||
odomTopicName_ = odomTopicName;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void parameterDeclareAndtryGetOrSet(
|
||||
rclcpp::Node::SharedPtr & node, std::string param_name, T & value)
|
||||
{
|
||||
if (!node->get_parameter(param_name, value))
|
||||
{
|
||||
RCLCPP_INFO_STREAM(
|
||||
node->get_logger(), "[CpOdomTracker] autoset " << param_name << ": " << value);
|
||||
node->declare_parameter(param_name, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO_STREAM(node->get_logger(), "[CpOdomTracker] " << param_name << ": " << value);
|
||||
}
|
||||
}
|
||||
|
||||
void CpOdomTracker::onInitialize()
|
||||
{
|
||||
// default values
|
||||
recordPointDistanceThreshold_ = 0.005; // 5 mm
|
||||
recordAngularDistanceThreshold_ = 0.1; // radians
|
||||
clearPointDistanceThreshold_ = 0.05; // 5 cm
|
||||
clearAngularDistanceThreshold_ = 0.1; // radi
|
||||
|
||||
auto nh = getNode();
|
||||
RCLCPP_WARN(getLogger(), "[CpOdomTracker] Initializing Odometry Tracker");
|
||||
|
||||
parameterDeclareAndtryGetOrSet(nh, "odom_frame", this->odomFrame_);
|
||||
parameterDeclareAndtryGetOrSet(
|
||||
nh, "record_point_distance_threshold", recordPointDistanceThreshold_);
|
||||
parameterDeclareAndtryGetOrSet(
|
||||
nh, "record_angular_distance_threshold", recordAngularDistanceThreshold_);
|
||||
parameterDeclareAndtryGetOrSet(
|
||||
nh, "clear_point_distance_threshold", clearPointDistanceThreshold_);
|
||||
parameterDeclareAndtryGetOrSet(
|
||||
nh, "clear_angular_distance_threshold", clearAngularDistanceThreshold_);
|
||||
|
||||
param_callback_handle_ = getNode()->add_on_set_parameters_callback(
|
||||
std::bind(&CpOdomTracker::parametersCallback, this, std::placeholders::_1));
|
||||
|
||||
robotBasePathPub_ =
|
||||
nh->create_publisher<nav_msgs::msg::Path>("odom_tracker_path", rclcpp::QoS(1));
|
||||
|
||||
robotBasePathStackedPub_ =
|
||||
nh->create_publisher<nav_msgs::msg::Path>("odom_tracker_stacked_path", rclcpp::QoS(1));
|
||||
|
||||
if (this->strategy_ == OdomTrackerStrategy::ODOMETRY_SUBSCRIBER)
|
||||
{
|
||||
RCLCPP_INFO_STREAM(
|
||||
nh->get_logger(), "[CpOdomTracker] subscribing to odom topic: " << odomTopicName_);
|
||||
|
||||
rclcpp::SensorDataQoS qos;
|
||||
odomSub_ = nh->create_subscription<nav_msgs::msg::Odometry>(
|
||||
odomTopicName_, qos,
|
||||
std::bind(&CpOdomTracker::odomMessageCallback, this, std::placeholders::_1));
|
||||
}
|
||||
else if (this->strategy_ == OdomTrackerStrategy::POSE_COMPONENT)
|
||||
{
|
||||
this->requiresComponent(robotPose_);
|
||||
robotPoseTimer_ = nh->create_wall_timer(
|
||||
std::chrono::milliseconds(100), std::bind(&CpOdomTracker::update, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_ERROR_STREAM(
|
||||
nh->get_logger(), "[CpOdomTracker] unknown strategy: " << (int)this->strategy_);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* parametersCallback()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
rcl_interfaces::msg::SetParametersResult CpOdomTracker::parametersCallback(
|
||||
const std::vector<rclcpp::Parameter> & parameters)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
RCLCPP_INFO(getLogger(), "odom_tracker m_mutex acquire");
|
||||
|
||||
for (const auto & param : parameters)
|
||||
{
|
||||
if (param.get_name() == "record_point_distance_threshold")
|
||||
{
|
||||
recordPointDistanceThreshold_ = param.as_double();
|
||||
}
|
||||
else if (param.get_name() == "record_angular_distance_threshold")
|
||||
{
|
||||
recordAngularDistanceThreshold_ = param.as_double();
|
||||
}
|
||||
else if (param.get_name() == "clear_point_distance_threshold")
|
||||
{
|
||||
clearPointDistanceThreshold_ = param.as_double();
|
||||
}
|
||||
else if (param.get_name() == "clear_angular_distance_threshold")
|
||||
{
|
||||
clearAngularDistanceThreshold_ = param.as_double();
|
||||
}
|
||||
else if (param.get_name() == "odom_frame")
|
||||
{
|
||||
odomFrame_ = param.as_string();
|
||||
}
|
||||
}
|
||||
|
||||
rcl_interfaces::msg::SetParametersResult result;
|
||||
result.successful = true;
|
||||
result.reason = "success";
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* setWorkingMode()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
void CpOdomTracker::setWorkingMode(WorkingMode workingMode)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
|
||||
switch (workingMode)
|
||||
{
|
||||
case WorkingMode::RECORD_PATH:
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(),
|
||||
"[CpOdomTracker] setting working mode to RECORD - record_point_distance_threshold: "
|
||||
<< recordPointDistanceThreshold_
|
||||
<< ", record_angular_distance_threshold: " << recordAngularDistanceThreshold_);
|
||||
break;
|
||||
case WorkingMode::CLEAR_PATH:
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(),
|
||||
"[CpOdomTracker] setting working mode to CLEAR - clear_point_distance_threshold: "
|
||||
<< clearPointDistanceThreshold_
|
||||
<< ", clear_angular_distance_threshold: " << clearAngularDistanceThreshold_);
|
||||
break;
|
||||
case WorkingMode::IDLE:
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CpOdomTracker] setting working mode to IDLE");
|
||||
break;
|
||||
default:
|
||||
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CpOdomTracker] setting working mode to <UNKNOWN>");
|
||||
}
|
||||
|
||||
if (this->odomSub_ != nullptr && this->odomSub_->get_publisher_count() == 0)
|
||||
{
|
||||
RCLCPP_ERROR_STREAM(
|
||||
getLogger(),
|
||||
"[CpOdomTracker] Odom tracker cannot record the path because there is no publisher to the "
|
||||
"odometry topic");
|
||||
}
|
||||
|
||||
workingMode_ = workingMode;
|
||||
// RCLCPP_INFO(getLogger(),"odom_tracker m_mutex release");
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* setPublishMessages()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
void CpOdomTracker::setPublishMessages(bool value)
|
||||
{
|
||||
// RCLCPP_INFO(getLogger(),"odom_tracker m_mutex acquire");
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
publishMessages = value;
|
||||
// RCLCPP_INFO(getLogger(),"odom_tracker m_mutex release");
|
||||
this->updateAggregatedStackPath();
|
||||
}
|
||||
|
||||
void CpOdomTracker::pushPath() { this->pushPath(std::string()); }
|
||||
|
||||
void CpOdomTracker::pushPath(std::string pathname)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "odom_tracker m_mutex acquire, to push path");
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
|
||||
this->logStateString(false);
|
||||
if (this->odomSub_ != nullptr && this->odomSub_->get_publisher_count() == 0)
|
||||
{
|
||||
RCLCPP_ERROR_STREAM(
|
||||
getLogger(),
|
||||
"[CpOdomTracker] Odom tracker cannot record the path because there is no publisher to the "
|
||||
"odometry topic");
|
||||
}
|
||||
|
||||
pathInfos_.push_back({currentPathName_, this->currentMotionGoal_});
|
||||
pathStack_.push_back(baseTrajectory_);
|
||||
|
||||
geometry_msgs::msg::PoseStamped goalPose;
|
||||
if (this->currentMotionGoal_) goalPose = *this->currentMotionGoal_;
|
||||
|
||||
RCLCPP_INFO_STREAM(
|
||||
getLogger(), "[CpOdomTracker] currentPathName: " << pathname
|
||||
<< " size: " << baseTrajectory_.poses.size()
|
||||
<< " current motion goal: " << goalPose);
|
||||
|
||||
currentPathName_ = pathname;
|
||||
|
||||
// clean the current trajectory to start a new one
|
||||
baseTrajectory_.poses.clear();
|
||||
|
||||
this->logStateString(false);
|
||||
this->updateAggregatedStackPath();
|
||||
|
||||
this->currentMotionGoal_.reset();
|
||||
}
|
||||
|
||||
void CpOdomTracker::popPath(int popCount, bool keepPreviousPath)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "odom_tracker m_mutex acquire to pop path");
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
|
||||
RCLCPP_INFO(getLogger(), "POP PATH ENTRY");
|
||||
this->logStateString();
|
||||
|
||||
if (this->odomSub_ != nullptr && this->odomSub_->get_publisher_count() == 0)
|
||||
{
|
||||
RCLCPP_ERROR_STREAM(
|
||||
getLogger(),
|
||||
"[CpOdomTracker] Odom tracker cannot record the path because there is no publisher to the "
|
||||
"odometry topic");
|
||||
}
|
||||
|
||||
if (!keepPreviousPath)
|
||||
{
|
||||
baseTrajectory_.poses.clear();
|
||||
}
|
||||
|
||||
while (popCount > 0 && !pathStack_.empty())
|
||||
{
|
||||
auto & stackedPath = pathStack_.back().poses;
|
||||
auto & stackedPathInfo = pathInfos_.back();
|
||||
|
||||
baseTrajectory_.poses.insert(
|
||||
baseTrajectory_.poses.begin(), stackedPath.begin(), stackedPath.end());
|
||||
this->currentMotionGoal_ = stackedPathInfo.goalPose;
|
||||
pathStack_.pop_back();
|
||||
pathInfos_.pop_back();
|
||||
popCount--;
|
||||
|
||||
RCLCPP_INFO(getLogger(), "POP PATH Iteration ");
|
||||
this->logStateString();
|
||||
}
|
||||
|
||||
RCLCPP_INFO(getLogger(), "POP PATH EXITING");
|
||||
this->logStateString();
|
||||
RCLCPP_INFO(getLogger(), "odom_tracker m_mutex release");
|
||||
this->updateAggregatedStackPath();
|
||||
|
||||
this->currentMotionGoal_.reset();
|
||||
}
|
||||
|
||||
void CpOdomTracker::logStateString(bool debug)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "--- odom tracker state ---" << std::endl;
|
||||
ss
|
||||
<< " - path stack -" << currentPathName_ << " - size:"
|
||||
<< pathStack_.size()
|
||||
//<< " goal: " << (getCurrentMotionGoal()? getCurrentMotionGoal()->pose: geometry_msgs::msg::Pose())
|
||||
<< std::endl;
|
||||
ss << " - [STACK-HEAD active path size: " << baseTrajectory_.poses.size() << "]" << std::endl;
|
||||
int i = 0;
|
||||
for (auto & p : pathStack_ | boost::adaptors::reversed)
|
||||
{
|
||||
auto & pathinfo = pathInfos_[pathInfos_.size() - i - 1];
|
||||
std::string goalstr = "[]";
|
||||
if (pathinfo.goalPose)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << *(pathinfo.goalPose);
|
||||
goalstr = ss.str();
|
||||
}
|
||||
|
||||
ss << " - p " << i << "[" << p.header.stamp << "], size: " << p.poses.size() << " - "
|
||||
<< pathinfo.name << " - goal: " << goalstr << std::endl;
|
||||
i++;
|
||||
}
|
||||
ss << "---";
|
||||
|
||||
if (this->odomSub_ != nullptr && this->odomSub_->get_publisher_count() == 0)
|
||||
{
|
||||
ss << std::endl
|
||||
<< "[CpOdomTracker] Odom tracker cannot record the path because there is no publisher to "
|
||||
"the odometry topic"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
RCLCPP_DEBUG(getLogger(), ss.str().c_str());
|
||||
else
|
||||
RCLCPP_INFO(getLogger(), ss.str().c_str());
|
||||
}
|
||||
|
||||
void CpOdomTracker::clearPath()
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "odom_tracker m_mutex acquire to clear path");
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
baseTrajectory_.poses.clear();
|
||||
|
||||
rtPublishPaths(getNode()->now());
|
||||
this->logStateString();
|
||||
this->updateAggregatedStackPath();
|
||||
|
||||
this->currentMotionGoal_.reset();
|
||||
}
|
||||
|
||||
void CpOdomTracker::setCurrentPathName(const std::string & currentPathName)
|
||||
{
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CpOdomTracker] set current path name: " << currentPathName);
|
||||
currentPathName_ = currentPathName;
|
||||
}
|
||||
|
||||
void CpOdomTracker::setStartPoint(const geometry_msgs::msg::PoseStamped & pose)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CpOdomTracker] set current path starting point: " << pose);
|
||||
if (baseTrajectory_.poses.size() > 0)
|
||||
{
|
||||
baseTrajectory_.poses[0] = pose;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseTrajectory_.poses.push_back(pose);
|
||||
}
|
||||
this->updateAggregatedStackPath();
|
||||
}
|
||||
|
||||
void CpOdomTracker::setStartPoint(const geometry_msgs::msg::Pose & pose)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CpOdomTracker] set current path starting point: " << pose);
|
||||
geometry_msgs::msg::PoseStamped posestamped;
|
||||
posestamped.header.frame_id = this->odomFrame_;
|
||||
posestamped.header.stamp = getNode()->now();
|
||||
posestamped.pose = pose;
|
||||
|
||||
if (baseTrajectory_.poses.size() > 0)
|
||||
{
|
||||
baseTrajectory_.poses[0] = posestamped;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseTrajectory_.poses.push_back(posestamped);
|
||||
}
|
||||
this->updateAggregatedStackPath();
|
||||
}
|
||||
|
||||
void CpOdomTracker::setCurrentMotionGoal(const geometry_msgs::msg::PoseStamped & pose)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
this->currentMotionGoal_ = pose;
|
||||
}
|
||||
|
||||
std::optional<geometry_msgs::msg::PoseStamped> CpOdomTracker::getCurrentMotionGoal()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
return this->currentMotionGoal_;
|
||||
}
|
||||
|
||||
nav_msgs::msg::Path CpOdomTracker::getPath()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
return this->baseTrajectory_;
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* rtPublishPaths()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
void CpOdomTracker::rtPublishPaths(rclcpp::Time timestamp)
|
||||
{
|
||||
baseTrajectory_.header.stamp = timestamp;
|
||||
robotBasePathPub_->publish(baseTrajectory_);
|
||||
|
||||
aggregatedStackPathMsg_.header.stamp = timestamp;
|
||||
robotBasePathStackedPub_->publish(aggregatedStackPathMsg_);
|
||||
}
|
||||
|
||||
void CpOdomTracker::updateAggregatedStackPath()
|
||||
{
|
||||
aggregatedStackPathMsg_.poses.clear();
|
||||
for (auto & p : pathStack_)
|
||||
{
|
||||
aggregatedStackPathMsg_.poses.insert(
|
||||
aggregatedStackPathMsg_.poses.end(), p.poses.begin(), p.poses.end());
|
||||
}
|
||||
|
||||
aggregatedStackPathMsg_.header.frame_id = this->odomFrame_;
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* updateBackward()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
bool CpOdomTracker::updateClearPath(const geometry_msgs::msg::PoseStamped & base_pose)
|
||||
{
|
||||
// we initially accept any message if the queue is empty
|
||||
/// Track robot base pose
|
||||
baseTrajectory_.header = base_pose.header;
|
||||
|
||||
bool acceptBackward = false;
|
||||
bool clearingError = false;
|
||||
bool finished = false;
|
||||
|
||||
while (!finished)
|
||||
{
|
||||
if (
|
||||
baseTrajectory_.poses.size() <=
|
||||
1) // we at least keep always the first point of the forward path when clearing
|
||||
// (this is important for backwards planner replanning and not losing the
|
||||
// last goal)
|
||||
{
|
||||
acceptBackward = false;
|
||||
finished = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto & carrotPose = baseTrajectory_.poses.back().pose;
|
||||
auto & carrotPoint = carrotPose.position;
|
||||
|
||||
double carrotAngle = tf2::getYaw(carrotPose.orientation);
|
||||
|
||||
auto & currePose = base_pose.pose;
|
||||
auto & currePoint = currePose.position;
|
||||
double currentAngle = tf2::getYaw(currePose.orientation);
|
||||
|
||||
double lastpointdist = p2pDistance(carrotPoint, currePoint);
|
||||
double goalAngleOffset = fabs(angles::shortest_angular_distance(carrotAngle, currentAngle));
|
||||
|
||||
acceptBackward = !baseTrajectory_.poses.empty() &&
|
||||
lastpointdist < clearPointDistanceThreshold_ &&
|
||||
goalAngleOffset < clearAngularDistanceThreshold_;
|
||||
|
||||
clearingError = lastpointdist > 2 * clearPointDistanceThreshold_;
|
||||
RCLCPP_DEBUG_STREAM(
|
||||
getLogger(), "[CpOdomTracker] clearing (accepted: " << acceptBackward
|
||||
<< ") linerr: " << lastpointdist
|
||||
<< ", anglerr: " << goalAngleOffset);
|
||||
}
|
||||
|
||||
// RCLCPP_INFO(getLogger(),"Backwards, last distance: %lf < %lf accept: %d", dist,
|
||||
// minPointDistanceBackwardThresh_, acceptBackward);
|
||||
if (
|
||||
acceptBackward &&
|
||||
baseTrajectory_.poses.size() > 1) /* we always leave at least one item, specially interesting
|
||||
for the backward local planner reach
|
||||
the backwards goal with enough precision*/
|
||||
{
|
||||
baseTrajectory_.poses.pop_back();
|
||||
}
|
||||
else if (clearingError)
|
||||
{
|
||||
finished = true;
|
||||
RCLCPP_WARN(getLogger(), "[CpOdomTracker] Incorrect odom clearing motion.");
|
||||
}
|
||||
else
|
||||
{
|
||||
finished = true;
|
||||
/// Not removing point because it is enough far from the last cord point
|
||||
}
|
||||
}
|
||||
|
||||
return acceptBackward;
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* updateRecordPath()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
bool CpOdomTracker::updateRecordPath(const geometry_msgs::msg::PoseStamped & base_pose)
|
||||
{
|
||||
/// Track robot base pose
|
||||
baseTrajectory_.header = base_pose.header;
|
||||
|
||||
bool enqueueOdomMessage = false;
|
||||
|
||||
double dist = -1;
|
||||
if (baseTrajectory_.poses.empty())
|
||||
{
|
||||
enqueueOdomMessage = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto & prevPose = baseTrajectory_.poses.back().pose;
|
||||
const geometry_msgs::msg::Point & prevPoint = prevPose.position;
|
||||
double prevAngle = tf2::getYaw(prevPose.orientation);
|
||||
|
||||
const geometry_msgs::msg::Point & currePoint = base_pose.pose.position;
|
||||
double currentAngle = tf2::getYaw(base_pose.pose.orientation);
|
||||
|
||||
dist = p2pDistance(prevPoint, currePoint);
|
||||
double goalAngleOffset = fabs(angles::shortest_angular_distance(prevAngle, currentAngle));
|
||||
|
||||
// RCLCPP_WARN(getLogger(),"dist %lf vs min %lf", dist, recordPointDistanceThreshold_);
|
||||
|
||||
RCLCPP_WARN_THROTTLE(getLogger(), *getNode()->get_clock(), 2000, "odom received");
|
||||
|
||||
if (dist > recordPointDistanceThreshold_ || goalAngleOffset > recordAngularDistanceThreshold_)
|
||||
{
|
||||
enqueueOdomMessage = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// RCLCPP_WARN(getLogger(),"skip odom, dist: %lf", dist);
|
||||
enqueueOdomMessage = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (enqueueOdomMessage)
|
||||
{
|
||||
RCLCPP_WARN_THROTTLE(
|
||||
getLogger(), *getNode()->get_clock(), 2000, "enqueue odom tracker pose. dist %lf vs min %lf",
|
||||
dist, recordPointDistanceThreshold_);
|
||||
baseTrajectory_.poses.push_back(base_pose);
|
||||
}
|
||||
|
||||
return enqueueOdomMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* reconfigCB()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
void CpOdomTracker::updateConfiguration()
|
||||
{
|
||||
return;
|
||||
|
||||
if (!getNode()->get_parameter("odom_frame", this->odomFrame_))
|
||||
{
|
||||
}
|
||||
|
||||
if (!getNode()->get_parameter("record_point_distance_threshold", recordPointDistanceThreshold_))
|
||||
{
|
||||
}
|
||||
|
||||
if (!getNode()->get_parameter(
|
||||
"record_angular_distance_threshold", recordAngularDistanceThreshold_))
|
||||
{
|
||||
}
|
||||
|
||||
if (!getNode()->get_parameter("clear_point_distance_threshold", clearPointDistanceThreshold_))
|
||||
{
|
||||
}
|
||||
|
||||
if (!getNode()->get_parameter("clear_angular_distance_threshold", clearAngularDistanceThreshold_))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* update()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
void CpOdomTracker::update()
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "odom_tracker update");
|
||||
auto pose = robotPose_->toPoseStampedMsg();
|
||||
RCLCPP_INFO(getLogger(), "odom tracker updatd pose, frame: %s", pose.header.frame_id.c_str());
|
||||
processNewPose(pose);
|
||||
RCLCPP_INFO(getLogger(), "odom_tracker update end");
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* odomMessageCallback()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
void CpOdomTracker::odomMessageCallback(const nav_msgs::msg::Odometry::SharedPtr odom)
|
||||
{
|
||||
geometry_msgs::msg::PoseStamped base_pose;
|
||||
base_pose.pose = odom->pose.pose;
|
||||
base_pose.header = odom->header;
|
||||
|
||||
processNewPose(base_pose);
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* processNewPose()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
void CpOdomTracker::processNewPose(const geometry_msgs::msg::PoseStamped & odom)
|
||||
{
|
||||
RCLCPP_INFO_THROTTLE(
|
||||
getLogger(), *getNode()->get_clock(), 5000,
|
||||
"[odom_tracker] processing odom msg update heartbeat");
|
||||
std::lock_guard<std::mutex> lock(m_mutex_);
|
||||
|
||||
updateConfiguration();
|
||||
|
||||
if (workingMode_ == WorkingMode::RECORD_PATH)
|
||||
{
|
||||
updateRecordPath(odom);
|
||||
}
|
||||
else if (workingMode_ == WorkingMode::CLEAR_PATH)
|
||||
{
|
||||
updateClearPath(odom);
|
||||
}
|
||||
|
||||
// RCLCPP_WARN(getLogger(),"odomTracker odometry callback");
|
||||
if (publishMessages)
|
||||
{
|
||||
rtPublishPaths(odom.header.stamp);
|
||||
}
|
||||
|
||||
// RCLCPP_INFO(getLogger(),"odom_tracker m_mutex release");
|
||||
}
|
||||
} // namespace odom_tracker
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,123 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
//#include <actionlib/server/simple_action_server.h>
|
||||
#include <odom_tracker/CpOdomTrackerAction.h>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <memory>
|
||||
|
||||
typedef actionlib::SimpleActionServer<odom_tracker::CpOdomTrackerAction> Server;
|
||||
|
||||
using namespace odom_tracker;
|
||||
using namespace cl_nav2z::odom_tracker;
|
||||
|
||||
class CpOdomTrackerActionServer
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<Server> as_;
|
||||
CpOdomTracker odomTracker;
|
||||
|
||||
CpOdomTrackerActionServer() : odomTracker("move_base") {}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* execute()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
void execute(
|
||||
const CpOdomTrackerGoalConstPtr & goal) // Note: "Action" is not appended to DoDishes here
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (goal->command)
|
||||
{
|
||||
case CpOdomTrackerGoal::RECORD_PATH:
|
||||
odomTracker.setWorkingMode(WorkingMode::RECORD_PATH);
|
||||
break;
|
||||
|
||||
case CpOdomTrackerGoal::CLEAR_PATH:
|
||||
odomTracker.setWorkingMode(WorkingMode::CLEAR_PATH);
|
||||
break;
|
||||
|
||||
case CpOdomTrackerGoal::IDLE:
|
||||
odomTracker.setWorkingMode(WorkingMode::IDLE);
|
||||
break;
|
||||
|
||||
case CpOdomTrackerGoal::START_BROADCAST_PATH:
|
||||
odomTracker.setPublishMessages(true);
|
||||
break;
|
||||
|
||||
case CpOdomTrackerGoal::STOP_BROADCAST_PATH:
|
||||
odomTracker.setPublishMessages(false);
|
||||
break;
|
||||
|
||||
case CpOdomTrackerGoal::PUSH_PATH:
|
||||
odomTracker.pushPath();
|
||||
break;
|
||||
|
||||
case CpOdomTrackerGoal::POP_PATH:
|
||||
odomTracker.popPath();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
RCLCPP_ERROR(
|
||||
getLogger(), "Odom Tracker Node - Action Server execute error: incorrect command - %d",
|
||||
goal->command);
|
||||
as_->setAborted();
|
||||
}
|
||||
|
||||
// never reach succeeded because were are interested in keeping the feedback alive
|
||||
as_->setSucceeded();
|
||||
}
|
||||
catch (std::exception & ex)
|
||||
{
|
||||
RCLCPP_ERROR(getLogger(), "Odom Tracker Node - Action Server execute error: %s", ex.what());
|
||||
as_->setAborted();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************************************************
|
||||
* run()
|
||||
******************************************************************************************************************
|
||||
*/
|
||||
void run()
|
||||
{
|
||||
rclcpp::Node::SharedPtr n;
|
||||
RCLCPP_INFO(getLogger(), "Creating odom tracker action server");
|
||||
|
||||
as_ = std::make_shared<Server>(
|
||||
n, "odom_tracker",
|
||||
std::bind(&CpOdomTrackerActionServer::execute, this, std::placeholders::_1), false);
|
||||
RCLCPP_INFO(getLogger(), "Starting CpOdomTracker Action Server");
|
||||
|
||||
as_->start();
|
||||
|
||||
ros::spin();
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
ros::init(argc, argv, "odom_tracker_node");
|
||||
CpOdomTrackerActionServer as;
|
||||
|
||||
as.run();
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/components/planner_switcher/cp_planner_switcher.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CpPlannerSwitcher::CpPlannerSwitcher() {}
|
||||
|
||||
void CpPlannerSwitcher::onInitialize()
|
||||
{
|
||||
rclcpp::QoS qos(rclcpp::KeepLast(1));
|
||||
qos.transient_local().reliable();
|
||||
|
||||
this->planner_selector_pub_ =
|
||||
getNode()->create_publisher<std_msgs::msg::String>("planner_selector", qos);
|
||||
this->controller_selector_pub_ =
|
||||
getNode()->create_publisher<std_msgs::msg::String>("controller_selector", qos);
|
||||
}
|
||||
|
||||
void CpPlannerSwitcher::setDesiredGlobalPlanner(std::string plannerName)
|
||||
{
|
||||
desired_planner_ = plannerName;
|
||||
}
|
||||
|
||||
void CpPlannerSwitcher::setDesiredController(std::string controllerName)
|
||||
{
|
||||
desired_controller_ = controllerName;
|
||||
}
|
||||
|
||||
void CpPlannerSwitcher::setUndoPathBackwardPlanner(bool commit)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CpPlannerSwitcher] Planner Switcher: Trying to set BackwardPlanner");
|
||||
|
||||
desired_planner_ = "UndoPathGlobalPlanner";
|
||||
desired_controller_ = "BackwardLocalPlanner";
|
||||
|
||||
if (commit) commitPublish();
|
||||
}
|
||||
|
||||
void CpPlannerSwitcher::setBackwardPlanner(bool commit)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CpPlannerSwitcher] Planner Switcher: Trying to set BackwardPlanner");
|
||||
|
||||
desired_planner_ = "BackwardGlobalPlanner";
|
||||
desired_controller_ = "BackwardLocalPlanner";
|
||||
|
||||
if (commit) commitPublish();
|
||||
}
|
||||
|
||||
void CpPlannerSwitcher::setForwardPlanner(bool commit)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[CpPlannerSwitcher] Planner Switcher: Trying to set ForwardPlanner");
|
||||
|
||||
desired_planner_ = "ForwardGlobalPlanner";
|
||||
desired_controller_ = "ForwardLocalPlanner";
|
||||
|
||||
if (commit) commitPublish();
|
||||
}
|
||||
|
||||
void CpPlannerSwitcher::setPureSpinningPlanner(bool commit)
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpPlannerSwitcher] Planner Switcher: Trying to set PureSpinningPlanner");
|
||||
|
||||
desired_planner_ = "ForwardGlobalPlanner";
|
||||
desired_controller_ = "PureSpinningLocalPlanner";
|
||||
|
||||
if (commit) commitPublish();
|
||||
}
|
||||
|
||||
void CpPlannerSwitcher::setDefaultPlanners(bool commit)
|
||||
{
|
||||
desired_planner_ = "GridBased";
|
||||
desired_controller_ = "FollowPath";
|
||||
|
||||
if (commit) commitPublish();
|
||||
}
|
||||
|
||||
void CpPlannerSwitcher::commitPublish()
|
||||
{
|
||||
std_msgs::msg::String planner_msg;
|
||||
planner_msg.data = desired_planner_;
|
||||
this->planner_selector_pub_->publish(planner_msg);
|
||||
|
||||
std_msgs::msg::String controller_msg;
|
||||
controller_msg.data = desired_controller_;
|
||||
this->controller_selector_pub_->publish(controller_msg);
|
||||
}
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,170 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
// static
|
||||
std::shared_ptr<tf2_ros::TransformListener> Pose::tfListener_;
|
||||
std::shared_ptr<tf2_ros::Buffer> Pose::tfBuffer_;
|
||||
std::mutex Pose::listenerMutex_;
|
||||
|
||||
Pose::Pose(std::string targetFrame, std::string referenceFrame)
|
||||
: isInitialized(false), poseFrameName_(targetFrame), referenceFrame_(referenceFrame)
|
||||
|
||||
{
|
||||
this->pose_.header.frame_id = referenceFrame_;
|
||||
}
|
||||
|
||||
std::string referenceFrameToString(StandardReferenceFrames referenceFrame)
|
||||
{
|
||||
switch (referenceFrame)
|
||||
{
|
||||
case StandardReferenceFrames::Map:
|
||||
return "map";
|
||||
case StandardReferenceFrames::Odometry:
|
||||
return "odom";
|
||||
default:
|
||||
return "odom";
|
||||
}
|
||||
}
|
||||
|
||||
Pose::Pose(StandardReferenceFrames referenceFrame)
|
||||
: Pose("base_link", referenceFrameToString(referenceFrame))
|
||||
{
|
||||
}
|
||||
|
||||
void Pose::onInitialize()
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[Pose] Creating Pose tracker component to track %s in the reference frame %s",
|
||||
poseFrameName_.c_str(), referenceFrame_.c_str());
|
||||
|
||||
{
|
||||
// singleton
|
||||
std::lock_guard<std::mutex> guard(listenerMutex_);
|
||||
if (tfListener_ == nullptr)
|
||||
{
|
||||
tfBuffer_ = std::make_shared<tf2_ros::Buffer>(getNode()->get_clock());
|
||||
tfListener_ = std::make_shared<tf2_ros::TransformListener>(*tfBuffer_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Pose::waitTransformUpdate(rclcpp::Rate r)
|
||||
{
|
||||
bool found = false;
|
||||
RCLCPP_INFO(getLogger(), "[Pose Component] waitTransformUpdate");
|
||||
while (rclcpp::ok() && !found)
|
||||
{
|
||||
tf2::Stamped<tf2::Transform> transform;
|
||||
try
|
||||
{
|
||||
{
|
||||
RCLCPP_INFO_THROTTLE(
|
||||
getLogger(), *(getNode()->get_clock()), 1000,
|
||||
"[Pose Component] waiting transform %s -> %s", referenceFrame_.c_str(),
|
||||
poseFrameName_.c_str());
|
||||
std::lock_guard<std::mutex> lock(listenerMutex_);
|
||||
auto transformstamped =
|
||||
tfBuffer_->lookupTransform(referenceFrame_, poseFrameName_, getNode()->now());
|
||||
tf2::fromMsg(transformstamped, transform);
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_mutex_);
|
||||
tf2::toMsg(transform, this->pose_.pose);
|
||||
this->pose_.header.stamp = tf2_ros::toRclcpp(transform.stamp_);
|
||||
this->pose_.header.frame_id = referenceFrame_;
|
||||
found = true;
|
||||
this->isInitialized = true;
|
||||
}
|
||||
}
|
||||
catch (tf2::TransformException & ex)
|
||||
{
|
||||
RCLCPP_ERROR_STREAM_THROTTLE(
|
||||
getLogger(), *(getNode()->get_clock()), 1000,
|
||||
"[Component pose] (" << poseFrameName_ << "/[" << referenceFrame_
|
||||
<< "] ) is failing on pose update : " << ex.what());
|
||||
}
|
||||
|
||||
r.sleep();
|
||||
}
|
||||
RCLCPP_INFO(getLogger(), "[Pose Component] waitTransformUpdate -> pose found!");
|
||||
}
|
||||
|
||||
float Pose::getYaw() { return tf2::getYaw(pose_.pose.orientation); }
|
||||
|
||||
float Pose::getX() { return pose_.pose.position.x; }
|
||||
float Pose::getY() { return pose_.pose.position.y; }
|
||||
float Pose::getZ() { return pose_.pose.position.z; }
|
||||
|
||||
void Pose::update()
|
||||
{
|
||||
tf2::Stamped<tf2::Transform> transform;
|
||||
try
|
||||
{
|
||||
if (!frozenReferenceFrameTime)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(listenerMutex_);
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[pose] looking up transform: %s -> %s", referenceFrame_.c_str(),
|
||||
poseFrameName_.c_str());
|
||||
auto transformstamped =
|
||||
tfBuffer_->lookupTransform(referenceFrame_, poseFrameName_, rclcpp::Time(0));
|
||||
tf2::fromMsg(transformstamped, transform);
|
||||
RCLCPP_INFO(getLogger(), "[pose] transform found");
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[pose] looking up transform: %s -> %s", referenceFrame_.c_str(),
|
||||
poseFrameName_.c_str());
|
||||
auto transformstamped = tfBuffer_->lookupTransform(
|
||||
referenceFrame_, *frozenReferenceFrameTime, poseFrameName_, rclcpp::Time(0),
|
||||
referenceFrame_, 1s);
|
||||
tf2::fromMsg(transformstamped, transform);
|
||||
RCLCPP_INFO(getLogger(), "[pose] transform found");
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_mutex_);
|
||||
tf2::toMsg(transform, this->pose_.pose);
|
||||
this->pose_.header.stamp = tf2_ros::toRclcpp(transform.stamp_);
|
||||
this->pose_.header.frame_id = referenceFrame_;
|
||||
this->isInitialized = true;
|
||||
}
|
||||
}
|
||||
catch (tf2::TransformException & ex)
|
||||
{
|
||||
// RCLCPP_DEBUG(getLogger(), "[pose] EXCEPTION");
|
||||
RCLCPP_ERROR_STREAM_THROTTLE(
|
||||
getLogger(), *(getNode()->get_clock()), 1000,
|
||||
"[Component pose] (" << poseFrameName_ << "/[" << referenceFrame_
|
||||
<< "] ) is failing on pose update : " << ex.what());
|
||||
}
|
||||
}
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,40 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/components/slam_toolbox/cp_slam_toolbox.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
CpSlamToolbox::CpSlamToolbox() : state_(SlamToolboxState::Resumed) {}
|
||||
CpSlamToolbox::~CpSlamToolbox() {}
|
||||
|
||||
void CpSlamToolbox::toggleState()
|
||||
{
|
||||
if (state_ == SlamToolboxState::Paused)
|
||||
{
|
||||
state_ = SlamToolboxState::Resumed;
|
||||
}
|
||||
else
|
||||
{
|
||||
state_ = SlamToolboxState::Paused;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,30 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_event_dispatcher.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
void WaypointEventDispatcher::postWaypointEvent(int index)
|
||||
{
|
||||
auto & fn = postWaypointFn[index % WAYPOINTS_EVENTCOUNT];
|
||||
if (fn != nullptr) fn();
|
||||
}
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,579 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <tf2/transform_datatypes.h>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
#include <ament_index_cpp/get_package_share_directory.hpp>
|
||||
#include <cl_nav2z/cl_nav2z.hpp>
|
||||
#include <cl_nav2z/common.hpp>
|
||||
#include <cl_nav2z/components/goal_checker_switcher/cp_goal_checker_switcher.hpp>
|
||||
#include <cl_nav2z/components/odom_tracker/cp_odom_tracker.hpp>
|
||||
#include <cl_nav2z/components/planner_switcher/cp_planner_switcher.hpp>
|
||||
#include <cl_nav2z/components/pose/cp_pose.hpp>
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_navigator.hpp>
|
||||
#include <fstream>
|
||||
#include <rclcpp/rclcpp.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
CpWaypointNavigatorBase::CpWaypointNavigatorBase() : currentWaypoint_(0), waypoints_(0) {}
|
||||
|
||||
CpWaypointNavigatorBase::~CpWaypointNavigatorBase() {}
|
||||
|
||||
CpWaypointNavigator::CpWaypointNavigator() {}
|
||||
|
||||
void CpWaypointNavigatorBase::onInitialize() {}
|
||||
|
||||
void CpWaypointNavigator::onInitialize()
|
||||
{
|
||||
client_ = dynamic_cast<ClNav2Z *>(owner_);
|
||||
this->requiresComponent(nav2ActionInterface_);
|
||||
}
|
||||
|
||||
void CpWaypointNavigator::onGoalCancelled(
|
||||
const components::CpNav2ActionInterface::WrappedResult & /*res*/)
|
||||
{
|
||||
stopWaitingResult();
|
||||
|
||||
this->onNavigationRequestCancelled();
|
||||
}
|
||||
|
||||
void CpWaypointNavigator::onGoalAborted(
|
||||
const components::CpNav2ActionInterface::WrappedResult & /*res*/)
|
||||
{
|
||||
stopWaitingResult();
|
||||
|
||||
this->onNavigationRequestAborted();
|
||||
}
|
||||
|
||||
void CpWaypointNavigator::onGoalReached(
|
||||
const components::CpNav2ActionInterface::WrappedResult & /*res*/)
|
||||
{
|
||||
waypointsEventDispatcher.postWaypointEvent(currentWaypoint_);
|
||||
currentWaypoint_++;
|
||||
RCLCPP_WARN(
|
||||
getLogger(), "[CpWaypointNavigator] Goal result received, incrementing waypoint index: %ld",
|
||||
currentWaypoint_);
|
||||
stopWaitingResult();
|
||||
|
||||
this->notifyGoalReached();
|
||||
|
||||
onNavigationRequestSucceded();
|
||||
}
|
||||
|
||||
void CpWaypointNavigatorBase::rewind(int /*count*/)
|
||||
{
|
||||
currentWaypoint_--;
|
||||
if (currentWaypoint_ < 0) currentWaypoint_ = 0;
|
||||
}
|
||||
|
||||
void CpWaypointNavigatorBase::forward(int /*count*/)
|
||||
{
|
||||
currentWaypoint_++;
|
||||
if (currentWaypoint_ >= (long)waypoints_.size() - 1)
|
||||
currentWaypoint_ = (long)waypoints_.size() - 1;
|
||||
}
|
||||
|
||||
void CpWaypointNavigatorBase::seekName(std::string name)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
auto previousWaypoint = currentWaypoint_;
|
||||
|
||||
while (!found && currentWaypoint_ < (long)waypoints_.size())
|
||||
{
|
||||
auto & nextName = waypointsNames_[currentWaypoint_];
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpWaypointNavigator] seeking ,%ld/%ld candidate waypoint: %s",
|
||||
currentWaypoint_, waypoints_.size(), nextName.c_str());
|
||||
if (name == nextName)
|
||||
{
|
||||
found = true;
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpWaypointNavigator] found target waypoint: %s == %s-> found",
|
||||
nextName.c_str(), name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpWaypointNavigator] current waypoint: %s != %s -> forward",
|
||||
nextName.c_str(), name.c_str());
|
||||
currentWaypoint_++;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (currentWaypoint_ >= (long)waypoints_.size() - 1)
|
||||
currentWaypoint_ = (long)waypoints_.size() - 1;
|
||||
}
|
||||
else // search backwards
|
||||
{
|
||||
currentWaypoint_ = previousWaypoint;
|
||||
while (!found && currentWaypoint_ > 0)
|
||||
{
|
||||
auto & nextName = waypointsNames_[currentWaypoint_];
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpWaypointNavigator] seeking , candidate waypoint: %s", nextName.c_str());
|
||||
if (name == nextName)
|
||||
{
|
||||
found = true;
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpWaypointNavigator] found target waypoint: %s == %s-> found",
|
||||
nextName.c_str(), name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpWaypointNavigator] current waypoint: %s != %s -> rewind",
|
||||
nextName.c_str(), name.c_str());
|
||||
currentWaypoint_--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpWaypointNavigator] seekName( %s), previous index: %ld, after index: %ld",
|
||||
name.c_str(), previousWaypoint, currentWaypoint_);
|
||||
}
|
||||
|
||||
void CpWaypointNavigatorBase::loadWaypointsFromYamlParameter(
|
||||
std::string parameter_name, std::string yaml_file_package_name)
|
||||
{
|
||||
// if it is the first time and the waypoints navigator is not configured
|
||||
std::string planfilepath;
|
||||
planfilepath = getNode()->declare_parameter(parameter_name, planfilepath);
|
||||
RCLCPP_INFO(getLogger(), "waypoints plan parameter: %s", planfilepath.c_str());
|
||||
if (getNode()->get_parameter(parameter_name, planfilepath))
|
||||
{
|
||||
std::string package_share_directory =
|
||||
ament_index_cpp::get_package_share_directory(yaml_file_package_name);
|
||||
|
||||
RCLCPP_INFO(getLogger(), "file macro path: %s", planfilepath.c_str());
|
||||
|
||||
boost::replace_all(planfilepath, "$(pkg_share)", package_share_directory);
|
||||
|
||||
RCLCPP_INFO(getLogger(), "package share path: %s", package_share_directory.c_str());
|
||||
RCLCPP_INFO(getLogger(), "waypoints plan file: %s", planfilepath.c_str());
|
||||
|
||||
this->loadWayPointsFromFile(planfilepath);
|
||||
RCLCPP_INFO(getLogger(), "waypoints plan: %s", planfilepath.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_ERROR(getLogger(), "waypoints plan file not found: NONE");
|
||||
}
|
||||
}
|
||||
|
||||
void CpWaypointNavigator::stopWaitingResult()
|
||||
{
|
||||
if (succeddedNav2ZClientConnection_.connected())
|
||||
{
|
||||
this->succeddedNav2ZClientConnection_.disconnect();
|
||||
this->cancelledNav2ZClientConnection_.disconnect();
|
||||
this->abortedNav2ZClientConnection_.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::shared_future<
|
||||
std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose>>>>
|
||||
CpWaypointNavigator::sendNextGoal(std::optional<NavigateNextWaypointOptions> options)
|
||||
{
|
||||
if (currentWaypoint_ >= 0 && currentWaypoint_ < (int)waypoints_.size())
|
||||
{
|
||||
auto & next = waypoints_[currentWaypoint_];
|
||||
|
||||
std::string nextName;
|
||||
if ((long)waypointsNames_.size() > currentWaypoint_)
|
||||
{
|
||||
nextName = waypointsNames_[currentWaypoint_];
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpWaypointNavigator] sending goal, waypoint: %s", nextName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_INFO(
|
||||
getLogger(), "[CpWaypointNavigator] sending goal, waypoint: %ld", currentWaypoint_);
|
||||
}
|
||||
|
||||
nav2_msgs::action::NavigateToPose::Goal goal;
|
||||
auto p = client_->getComponent<cl_nav2z::Pose>();
|
||||
auto pose = p->toPoseMsg();
|
||||
|
||||
// configuring goal
|
||||
goal.pose.header.frame_id = p->getReferenceFrame();
|
||||
//goal.pose.header.stamp = getNode()->now();
|
||||
goal.pose.pose = next;
|
||||
|
||||
auto plannerSwitcher = client_->getComponent<CpPlannerSwitcher>();
|
||||
plannerSwitcher->setDefaultPlanners(false);
|
||||
if (options && options->controllerName_)
|
||||
{
|
||||
RCLCPP_WARN(
|
||||
getLogger(), "[WaypointsNavigator] override controller: %s",
|
||||
options->controllerName_->c_str());
|
||||
|
||||
plannerSwitcher->setDesiredController(*options->controllerName_);
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_WARN(getLogger(), "[WaypointsNavigator] Configuring default planners");
|
||||
}
|
||||
|
||||
auto goalCheckerSwitcher = client_->getComponent<CpGoalCheckerSwitcher>();
|
||||
|
||||
if (options && options->goalCheckerName_)
|
||||
{
|
||||
RCLCPP_WARN(
|
||||
getLogger(), "[WaypointsNavigator] override goal checker: %s",
|
||||
options->goalCheckerName_->c_str());
|
||||
|
||||
goalCheckerSwitcher->setGoalCheckerId(*options->goalCheckerName_);
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_WARN(getLogger(), "[WaypointsNavigator] Configuring default goal checker");
|
||||
goalCheckerSwitcher->setGoalCheckerId("goal_checker");
|
||||
}
|
||||
|
||||
plannerSwitcher->commitPublish();
|
||||
|
||||
// publish stuff
|
||||
// rclcpp::sleep_for(5s);
|
||||
|
||||
RCLCPP_INFO(getLogger(), "[WaypointsNavigator] Getting odom tracker");
|
||||
auto odomTracker = client_->getComponent<cl_nav2z::odom_tracker::CpOdomTracker>();
|
||||
if (odomTracker != nullptr)
|
||||
{
|
||||
RCLCPP_INFO(getLogger(), "[WaypointsNavigator] Storing path in odom tracker");
|
||||
|
||||
auto pathname = this->owner_->getStateMachine()->getCurrentState()->getName() + " - " +
|
||||
getName() + " - " + nextName;
|
||||
odomTracker->pushPath(pathname);
|
||||
odomTracker->setStartPoint(pose);
|
||||
odomTracker->setWorkingMode(cl_nav2z::odom_tracker::WorkingMode::RECORD_PATH);
|
||||
}
|
||||
|
||||
// SEND GOAL
|
||||
// if (!succeddedNav2ZClientConnection_.connected())
|
||||
// {
|
||||
// this->succeddedNav2ZClientConnection_ =
|
||||
// client_->onSucceeded(&WaypointNavigator::onGoalReached, this);
|
||||
// this->cancelledNav2ZClientConnection_ =
|
||||
// client_->onAborted(&WaypointNavigator::onGoalCancelled, this);
|
||||
// this->abortedNav2ZClientConnection_ =
|
||||
// client_->onCancelled(&WaypointNavigator::onGoalAborted, this);
|
||||
// }
|
||||
|
||||
// Set up navigation result handling
|
||||
if (!succeddedNav2ZClientConnection_.connected())
|
||||
{
|
||||
succeddedNav2ZClientConnection_ =
|
||||
nav2ActionInterface_->onNavigationSucceeded(&CpWaypointNavigator::onGoalReached, this);
|
||||
abortedNav2ZClientConnection_ =
|
||||
nav2ActionInterface_->onNavigationAborted(&CpWaypointNavigator::onGoalAborted, this);
|
||||
cancelledNav2ZClientConnection_ =
|
||||
nav2ActionInterface_->onNavigationCancelled(&CpWaypointNavigator::onGoalCancelled, this);
|
||||
}
|
||||
|
||||
return nav2ActionInterface_->sendGoal(goal);
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_WARN(
|
||||
getLogger(),
|
||||
"[CpWaypointsNavigator] All waypoints were consumed. There is no more waypoints available.");
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void CpWaypointNavigatorBase::notifyGoalReached()
|
||||
{
|
||||
// when it is the last waypoint post an finalization EOF event
|
||||
if (currentWaypoint_ == (long)waypoints_.size() - 1)
|
||||
{
|
||||
RCLCPP_WARN(getLogger(), "[CpWaypointNavigator] Last waypoint reached, posting EOF event. ");
|
||||
this->postEvent<EvWaypointFinal>();
|
||||
}
|
||||
}
|
||||
|
||||
void CpWaypointNavigator::onNavigationResult(
|
||||
const components::CpNav2ActionInterface::WrappedResult & r)
|
||||
{
|
||||
if (r.code == rclcpp_action::ResultCode::SUCCEEDED)
|
||||
{
|
||||
this->onGoalReached(r);
|
||||
}
|
||||
else if (r.code == rclcpp_action::ResultCode::ABORTED)
|
||||
{
|
||||
this->onGoalAborted(r);
|
||||
}
|
||||
else if (r.code == rclcpp_action::ResultCode::CANCELED)
|
||||
{
|
||||
this->onGoalCancelled(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->onGoalAborted(r);
|
||||
}
|
||||
}
|
||||
|
||||
void CpWaypointNavigatorBase::insertWaypoint(int index, geometry_msgs::msg::Pose & newpose)
|
||||
{
|
||||
if (index >= 0 && index <= (int)waypoints_.size())
|
||||
{
|
||||
waypoints_.insert(waypoints_.begin(), index, newpose);
|
||||
}
|
||||
}
|
||||
|
||||
void CpWaypointNavigatorBase::setWaypoints(const std::vector<geometry_msgs::msg::Pose> & waypoints)
|
||||
{
|
||||
this->waypoints_ = waypoints;
|
||||
}
|
||||
|
||||
void CpWaypointNavigatorBase::setWaypoints(const std::vector<Pose2D> & waypoints)
|
||||
{
|
||||
waypoints_.clear();
|
||||
waypointsNames_.clear();
|
||||
int i = 0;
|
||||
for (auto & p : waypoints)
|
||||
{
|
||||
geometry_msgs::msg::Pose pose;
|
||||
pose.position.x = p.x_;
|
||||
pose.position.y = p.y_;
|
||||
pose.position.z = 0.0;
|
||||
tf2::Quaternion q;
|
||||
q.setRPY(0, 0, p.yaw_);
|
||||
pose.orientation = tf2::toMsg(q);
|
||||
|
||||
waypoints_.push_back(pose);
|
||||
waypointsNames_.push_back(std::to_string(i++));
|
||||
}
|
||||
}
|
||||
|
||||
void CpWaypointNavigatorBase::removeWaypoint(int index)
|
||||
{
|
||||
if (index >= 0 && index < (int)waypoints_.size())
|
||||
{
|
||||
waypoints_.erase(waypoints_.begin() + index);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<geometry_msgs::msg::Pose> & CpWaypointNavigatorBase::getWaypoints() const
|
||||
{
|
||||
return waypoints_;
|
||||
}
|
||||
|
||||
geometry_msgs::msg::Pose CpWaypointNavigatorBase::getPose(int index) const
|
||||
{
|
||||
if (index >= 0 && index < (int)waypoints_.size())
|
||||
{
|
||||
return waypoints_[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::out_of_range("Waypoint index out of range");
|
||||
}
|
||||
}
|
||||
geometry_msgs::msg::Pose CpWaypointNavigatorBase::getCurrentPose() const
|
||||
{
|
||||
if (currentWaypoint_ >= 0 && currentWaypoint_ < (int)waypoints_.size())
|
||||
{
|
||||
return waypoints_[currentWaypoint_];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::out_of_range("Waypoint index out of range");
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<geometry_msgs::msg::Pose> CpWaypointNavigatorBase::getNamedPose(
|
||||
std::string name) const
|
||||
{
|
||||
if (this->waypointsNames_.size() > 0)
|
||||
{
|
||||
for (int i = 0; i < (int)this->waypointsNames_.size(); i++)
|
||||
{
|
||||
if (this->waypointsNames_[i] == name)
|
||||
{
|
||||
return this->waypoints_[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::vector<std::string> & CpWaypointNavigatorBase::getWaypointNames() const
|
||||
{
|
||||
return waypointsNames_;
|
||||
}
|
||||
|
||||
std::optional<std::string> CpWaypointNavigatorBase::getCurrentWaypointName() const
|
||||
{
|
||||
if (currentWaypoint_ >= 0 && currentWaypoint_ < (int)waypointsNames_.size())
|
||||
{
|
||||
return waypointsNames_[currentWaypoint_];
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
long CpWaypointNavigatorBase::getCurrentWaypointIndex() const { return currentWaypoint_; }
|
||||
|
||||
#define HAVE_NEW_YAMLCPP
|
||||
void CpWaypointNavigatorBase::loadWayPointsFromFile(std::string filepath)
|
||||
{
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CpWaypointNavigatorBase] Loading file:" << filepath);
|
||||
this->waypoints_.clear();
|
||||
std::ifstream ifs(filepath.c_str(), std::ifstream::in);
|
||||
if (ifs.good() == false)
|
||||
{
|
||||
throw std::string("Waypoints file not found");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
#ifdef HAVE_NEW_YAMLCPP
|
||||
YAML::Node node = YAML::Load(ifs);
|
||||
#else
|
||||
YAML::Parser parser(ifs);
|
||||
parser.GetNextDocument(node);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NEW_YAMLCPP
|
||||
const YAML::Node & wp_node_tmp = node["waypoints"];
|
||||
const YAML::Node * wp_node = wp_node_tmp ? &wp_node_tmp : NULL;
|
||||
#else
|
||||
const YAML::Node * wp_node = node.FindValue("waypoints");
|
||||
#endif
|
||||
|
||||
if (wp_node != NULL)
|
||||
{
|
||||
for (int64_t i = 0; i < wp_node->size(); ++i)
|
||||
{
|
||||
// Parse waypoint entries on YAML
|
||||
geometry_msgs::msg::Pose wp;
|
||||
|
||||
try
|
||||
{
|
||||
// (*wp_node)[i]["name"] >> wp.name;
|
||||
// (*wp_node)[i]["frame_id"] >> wp.header.frame_id;
|
||||
|
||||
auto wpnodei = (*wp_node)[i];
|
||||
wp.position.x = wpnodei["position"]["x"].as<double>();
|
||||
wp.position.y = wpnodei["position"]["y"].as<double>();
|
||||
wp.position.z = wpnodei["position"]["z"].as<double>();
|
||||
wp.orientation.x = wpnodei["orientation"]["x"].as<double>();
|
||||
wp.orientation.y = wpnodei["orientation"]["y"].as<double>();
|
||||
wp.orientation.z = wpnodei["orientation"]["z"].as<double>();
|
||||
wp.orientation.w = wpnodei["orientation"]["w"].as<double>();
|
||||
|
||||
if (wpnodei["name"].IsDefined())
|
||||
{
|
||||
this->waypointsNames_.push_back(wpnodei["name"].as<std::string>());
|
||||
}
|
||||
|
||||
this->waypoints_.push_back(wp);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
RCLCPP_ERROR(getLogger(), "parsing waypoint file, syntax error in point %ld", i);
|
||||
}
|
||||
}
|
||||
RCLCPP_INFO_STREAM(getLogger(), "Parsed " << this->waypoints_.size() << " waypoints.");
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_WARN_STREAM(getLogger(), "Couldn't find any waypoints in the provided yaml file.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException & ex)
|
||||
{
|
||||
RCLCPP_ERROR_STREAM(
|
||||
getLogger(), "Error loading the Waypoints YAML file. Incorrect syntax: " << ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
void CpWaypointNavigatorBase::loadWayPointsFromFile2(std::string filepath)
|
||||
{
|
||||
RCLCPP_INFO_STREAM(getLogger(), "[CpWaypointNavigator] Loading file:" << filepath);
|
||||
this->waypoints_.clear();
|
||||
std::ifstream ifs(filepath.c_str(), std::ifstream::in);
|
||||
if (ifs.good() == false)
|
||||
{
|
||||
throw std::string("Waypoints file not found");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
#ifdef HAVE_NEW_YAMLCPP
|
||||
YAML::Node node = YAML::Load(ifs);
|
||||
#else
|
||||
YAML::Parser parser(ifs);
|
||||
parser.GetNextDocument(node);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NEW_YAMLCPP
|
||||
const YAML::Node & wp_node_tmp = node["waypoints"];
|
||||
const YAML::Node * wp_node = wp_node_tmp ? &wp_node_tmp : NULL;
|
||||
#else
|
||||
const YAML::Node * wp_node = node.FindValue("waypoints");
|
||||
#endif
|
||||
|
||||
if (wp_node != NULL)
|
||||
{
|
||||
for (int64_t i = 0; i < wp_node->size(); ++i)
|
||||
{
|
||||
// Parse waypoint entries on YAML
|
||||
geometry_msgs::msg::Pose wp;
|
||||
|
||||
try
|
||||
{
|
||||
// (*wp_node)[i]["name"] >> wp.name;
|
||||
// (*wp_node)[i]["frame_id"] >> wp.header.frame_id;
|
||||
wp.position.x = (*wp_node)[i]["x"].as<double>();
|
||||
wp.position.y = (*wp_node)[i]["y"].as<double>();
|
||||
auto name = (*wp_node)[i]["name"].as<std::string>();
|
||||
|
||||
this->waypoints_.push_back(wp);
|
||||
this->waypointsNames_.push_back(name);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
RCLCPP_ERROR(getLogger(), "parsing waypoint file, syntax error in point %ld", i);
|
||||
}
|
||||
}
|
||||
RCLCPP_INFO_STREAM(getLogger(), "Parsed " << this->waypoints_.size() << " waypoints.");
|
||||
}
|
||||
else
|
||||
{
|
||||
RCLCPP_WARN_STREAM(getLogger(), "Couldn't find any waypoints in the provided yaml file.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException & ex)
|
||||
{
|
||||
RCLCPP_ERROR_STREAM(
|
||||
getLogger(), "Error loading the Waypoints YAML file. Incorrect syntax: " << ex.what());
|
||||
}
|
||||
}
|
||||
} // namespace cl_nav2z
|
||||
@@ -1,156 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*****************************************************************************************************************
|
||||
*
|
||||
* Authors: Pablo Inigo Blasco, Brett Aldrich
|
||||
*
|
||||
******************************************************************************************************************/
|
||||
|
||||
#include <cl_nav2z/components/waypoints_navigator/cp_waypoints_visualizer.hpp>
|
||||
|
||||
namespace cl_nav2z
|
||||
{
|
||||
const std::string frameid = "map";
|
||||
|
||||
CpWaypointsVisualizer::CpWaypointsVisualizer(rclcpp::Duration duration) : ISmaccUpdatable(duration)
|
||||
{
|
||||
}
|
||||
|
||||
void CpWaypointsVisualizer::onInitialize()
|
||||
{
|
||||
markersPub_ = getNode()->create_publisher<visualization_msgs::msg::MarkerArray>(
|
||||
"cp_waypoints_visualizer/visualization_markers", rclcpp::QoS(rclcpp::KeepLast(1)));
|
||||
|
||||
this->requiresComponent(waypointsNavigator_);
|
||||
auto & waypoints = waypointsNavigator_->getWaypoints();
|
||||
auto & waypointsNames = waypointsNavigator_->getWaypointNames();
|
||||
|
||||
int i = 0;
|
||||
for (auto & waypoint : waypoints)
|
||||
{
|
||||
std::string name;
|
||||
if ((long)waypointsNames.size() > i)
|
||||
{
|
||||
name = waypointsNames[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
name = "waypoint_" + std::to_string(i);
|
||||
}
|
||||
|
||||
visualization_msgs::msg::Marker marker;
|
||||
createMarker(waypoint, marker);
|
||||
markers_.markers.push_back(marker);
|
||||
|
||||
visualization_msgs::msg::Marker markerlabel;
|
||||
createMarkerLabel(waypoint, name, markerlabel);
|
||||
markerLabels_.markers.push_back(markerlabel);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void CpWaypointsVisualizer::createMarkerLabel(
|
||||
const geometry_msgs::msg::Pose & waypoint, std::string label,
|
||||
visualization_msgs::msg::Marker & marker)
|
||||
{
|
||||
marker.header.frame_id = frameid;
|
||||
marker.header.stamp = getNode()->now();
|
||||
marker.ns = "waypoints_labels";
|
||||
|
||||
marker.id = markers_.markers.size();
|
||||
marker.type = visualization_msgs::msg::Marker::TEXT_VIEW_FACING;
|
||||
marker.action = visualization_msgs::msg::Marker::ADD;
|
||||
marker.scale.x = 0.3;
|
||||
marker.scale.y = 0.3;
|
||||
marker.scale.z = 0.3;
|
||||
marker.text = label;
|
||||
|
||||
marker.color.a = 1.0;
|
||||
marker.pose = waypoint;
|
||||
marker.pose.position.z += 0.3;
|
||||
}
|
||||
|
||||
void CpWaypointsVisualizer::createMarker(
|
||||
const geometry_msgs::msg::Pose & waypoint, visualization_msgs::msg::Marker & marker)
|
||||
{
|
||||
marker.header.frame_id = frameid;
|
||||
marker.header.stamp = getNode()->now();
|
||||
marker.ns = "waypoints";
|
||||
|
||||
marker.id = markers_.markers.size();
|
||||
marker.type = visualization_msgs::msg::Marker::SPHERE;
|
||||
marker.action = visualization_msgs::msg::Marker::ADD;
|
||||
marker.scale.x = 0.1;
|
||||
marker.scale.y = 0.1;
|
||||
marker.scale.z = 0.1;
|
||||
|
||||
marker.color.a = 1.0;
|
||||
marker.pose = waypoint;
|
||||
}
|
||||
|
||||
void CpWaypointsVisualizer::update()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_mutex_);
|
||||
|
||||
auto index = waypointsNavigator_->getCurrentWaypointIndex();
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (auto & marker : markers_.markers)
|
||||
{
|
||||
marker.header.stamp = getNode()->now();
|
||||
|
||||
if (i >= index)
|
||||
{
|
||||
marker.color.r = 1.0;
|
||||
marker.color.g = 0;
|
||||
marker.color.b = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
marker.color.r = 0.0;
|
||||
marker.color.g = 1.0;
|
||||
marker.color.b = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (auto & marker : markerLabels_.markers)
|
||||
{
|
||||
marker.header.stamp = getNode()->now();
|
||||
|
||||
if (i >= index)
|
||||
{
|
||||
marker.color.r = 1.0;
|
||||
marker.color.g = 0;
|
||||
marker.color.b = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
marker.color.r = 0.0;
|
||||
marker.color.g = 1.0;
|
||||
marker.color.b = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
//markers_.header.stamp = getNode()->now();
|
||||
markersPub_->publish(markers_);
|
||||
markersPub_->publish(markerLabels_);
|
||||
}
|
||||
|
||||
} // namespace cl_nav2z
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user