Skip to content

Commit

Permalink
Feature/fix mutex galactic (#319)
Browse files Browse the repository at this point in the history
* bug fix galactic mutex

* testing undo motion and  also improving action client

* important refactoring smacc action client

* fix

* progress in smacc action client

* progress in the smacc action client fork based on signals

* more changes

* more testing

* more testing

* more testing on abort

* minor

* adding smaccServiceerver client to galactic

* Update cb_default_keyboard_behavior.hpp

* testing more husky robot

* progress in tests husky demo

* testing abort forward and undo

* finishing cancel and undo behavior tests
  • Loading branch information
pabloinigoblasco committed Oct 25, 2022
1 parent cb7f8ec commit 193a8a3
Show file tree
Hide file tree
Showing 59 changed files with 2,303 additions and 150 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,15 @@
"node": "cpp",
"callback": "cpp",
"image": "cpp",
"primitiveset": "cpp"
"primitiveset": "cpp",
"*.ipp": "cpp"
},
"python.autoComplete.extraPaths": [
"/opt/ros/galactic/lib/python3.8/site-packages"
],
"python.analysis.extraPaths": [
"/opt/ros/galactic/lib/python3.8/site-packages"
],
"cmake.sourceDirectory": "${workspaceFolder}/SMACC2/smacc2",

}
101 changes: 63 additions & 38 deletions smacc2/include/smacc2/client_bases/smacc_action_client_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class SmaccActionClientBase : public ISmaccActionClient
using CancelResponse = typename ActionType::Impl::CancelGoalService::Response;
using CancelCallback = std::function<void(typename CancelResponse::SharedPtr)>;

typedef smacc2::SmaccSignal<void(const WrappedResult &)> SmaccActionResultSignal;

std::string action_endpoint_;
SmaccActionClientBase(std::string actionServerName) : ISmaccActionClient()
{
Expand Down Expand Up @@ -89,25 +91,23 @@ class SmaccActionClientBase : public ISmaccActionClient
}

std::optional<std::shared_future<typename GoalHandle::SharedPtr>> lastRequest_;
typename GoalHandle::SharedPtr goalHandle_;
// typename GoalHandle::SharedPtr goalHandle_;

smacc2::SmaccSignal<void(const WrappedResult &)> onSucceeded_;
smacc2::SmaccSignal<void(const WrappedResult &)> onAborted_;
// smacc2::SmaccSignal<void(const WrappedResult &)> onPreempted_;
// smacc2::SmaccSignal<void(const WrappedResult &)> onRejected_;
smacc2::SmaccSignal<void(const WrappedResult &)> onCancelled_;
SmaccActionResultSignal onSucceeded_;
SmaccActionResultSignal onAborted_;
// SmaccActionResultSignal onPreempted_;
// SmaccActionResultSignal onRejected_;
SmaccActionResultSignal onCancelled_;

// event creation/posting factory functions
std::function<void(WrappedResult)> postSuccessEvent;
std::function<void(WrappedResult)> postAbortedEvent;
std::function<void(WrappedResult)> postCancelledEvent;
// std::function<void(WrappedResult)> postPreemptedEvent;
// std::function<void(WrappedResult)> postRejectedEvent;
std::function<void(WrappedResult)> postCancelledEvent;

std::function<void(const Feedback &)> postFeedbackEvent;

ResultCallback done_cb;
// SimpleActiveCallback active_cb;
FeedbackCallback feedback_cb;

template <typename EvType>
Expand Down Expand Up @@ -135,6 +135,7 @@ class SmaccActionClientBase : public ISmaccActionClient
postCancelledEvent = [this](auto msg) {
this->postResultEvent<EvActionCancelled<TSourceObject, TOrthogonal>>(msg);
};

postFeedbackEvent = [this](auto msg) {
auto actionFeedbackEvent = new EvActionFeedback<Feedback, TOrthogonal>();
actionFeedbackEvent->client = this;
Expand All @@ -143,9 +144,10 @@ class SmaccActionClientBase : public ISmaccActionClient
RCLCPP_DEBUG(getLogger(), "[%s] FEEDBACK EVENT", demangleType(typeid(*this)).c_str());
};

done_cb = [this](auto r) { this->onResult(r); };
// done_cb = boost::bind(&SmaccActionClientBase<ActionType>::onResult, this, _1, _2);
// result_cb = [this](auto r) { this->onResult(r); };
// result_cb = boost::bind(&SmaccActionClientBase<ActionType>::onResult, this, _1, _2);
// active_cb;

feedback_cb = [this](auto client, auto feedback) { this->onFeedback(client, feedback); };
}

Expand Down Expand Up @@ -213,32 +215,41 @@ class SmaccActionClientBase : public ISmaccActionClient

virtual bool cancelGoal() override
{
if (lastRequest_ && lastRequest_->valid())
{
rclcpp::spin_until_future_complete(getNode(), *lastRequest_);
auto req = lastRequest_->get();
RCLCPP_INFO_STREAM(
getLogger(), "[" << getName() << "] Cancelling goal. req id: "
<< rclcpp_action::to_string(req->get_goal_id()));
auto cancelresult = client_->async_cancel_goal(req);

// wait actively
rclcpp::spin_until_future_complete(getNode(), cancelresult);
//lastRequest_.reset();
return true;
}
else
{
RCLCPP_ERROR(
getLogger(), "%s [at %s]: not connected with actionserver, skipping cancel goal ...",
getName().c_str(), getNamespace().c_str());
return false;
}
auto fut = this->client_->async_cancel_all_goals();
fut.wait();

// if (lastRequest_ && lastRequest_->valid())
// {

// // rclcpp::spin_until_future_complete(getNode(), *lastRequest_);
// auto req = lastRequest_->get();
// RCLCPP_INFO_STREAM(
// getLogger(), "[" << getName() << "] Cancelling goal. req id: "
// << rclcpp_action::to_string(req->get_goal_id()));
// auto cancelresult = client_->async_cancel_goal(req);

// // wait actively
// // rclcpp::spin_until_future_complete(getNode(), cancelresult);
// //lastRequest_.reset();
// return true;
// }
// else
// {
// RCLCPP_ERROR(
// getLogger(), "%s [at %s]: not connected with actionserver, skipping cancel goal ...",
// getName().c_str(), getNamespace().c_str());
// return false;
// }

return true;
}

std::shared_future<typename GoalHandle::SharedPtr> sendGoal(Goal & goal)
std::shared_future<typename GoalHandle::SharedPtr> sendGoal(
Goal & goal, typename SmaccActionResultSignal::WeakPtr resultCallback =
typename SmaccActionResultSignal::WeakPtr())
//ResultCallback resultCallback = nullptr) // bug related with the cancel action and the issue
{
// client_->sendGoal(goal, done_cb, active_cb, feedback_cb);
// client_->sendGoal(goal, result_cb, active_cb, feedback_cb);
// std::shared_future<typename GoalHandle::SharedPtr>

SendGoalOptions options;
Expand All @@ -252,10 +263,10 @@ class SmaccActionClientBase : public ISmaccActionClient

/// Function called when the result for the goal is received.
// ResultCallback result_callback;
// options.result_callback = done_cb;
// options.result_callback = result_cb;

options.result_callback = [this](const typename rclcpp_action::ClientGoalHandle<
ActionType>::WrappedResult & result) {
options.result_callback = [this, resultCallback](const typename rclcpp_action::ClientGoalHandle<
ActionType>::WrappedResult & result) {
// TODO(#1652): a work around until rcl_action interface is updated
// if goal ids are not matched, the older goa call this callback so ignore the result
// if matched, it must be processed (including aborted)
Expand All @@ -273,7 +284,21 @@ class SmaccActionClientBase : public ISmaccActionClient
// // goal_result_available_ = true;
// // result_ = result;
// RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] Result CB Goal id matches with last request");
done_cb(result);

auto resultCallbackPtr = resultCallback.lock();

if (resultCallbackPtr != nullptr)
{
RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] Result CB calling user callback");
(*resultCallbackPtr)(result);
}
else
{
RCLCPP_INFO_STREAM(
getLogger(), "[" << getName() << "] Result CB calling default callback");
this->onResult(result);
}

// }
// else
// {
Expand Down
2 changes: 2 additions & 0 deletions smacc2/include/smacc2/client_bases/smacc_service_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class SmaccServiceClient : public smacc2::ISmaccClient
public:
std::optional<std::string> serviceName_;

SmaccServiceClient(std::string serviceName) : serviceName_(serviceName) { initialized_ = false; }

SmaccServiceClient() { initialized_ = false; }

void onInitialize() override
Expand Down
100 changes: 100 additions & 0 deletions smacc2/include/smacc2/client_bases/smacc_service_server_client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// 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 <optional>
#include <smacc2/smacc_client.hpp>
#include <smacc2/smacc_signal.hpp>

namespace smacc2
{
namespace client_bases
{
template <typename TService>
class SmaccServiceServerClient : public smacc2::ISmaccClient
{
using TServiceRequest = typename TService::Request;
using TServiceResponse = typename TService::Response;

public:
std::optional<std::string> serviceName_;
SmaccServiceServerClient() { initialized_ = false; }
SmaccServiceServerClient(std::string service_name)
{
serviceName_ = service_name;
initialized_ = false;
}

virtual ~SmaccServiceServerClient() {}

smacc2::SmaccSignal<void(
const std::shared_ptr<typename TService::Request>,
std::shared_ptr<typename TService::Response>)>
onServiceRequestReceived_;

template <typename T>
boost::signals2::connection onServiceRequestReceived(
void (T::*callback)(
const std::shared_ptr<typename TService::Request>,
std::shared_ptr<typename TService::Response>),
T * object)
{
return this->getStateMachine()->createSignalConnection(
onServiceRequestReceived_, callback, object);
}

void onInitialize() override
{
if (!initialized_)
{
if (!serviceName_)
{
RCLCPP_ERROR_STREAM(
getLogger(),
"[" << this->getName() << "] service server with no service name set. Skipping.");
}
else
{
RCLCPP_INFO_STREAM(
getLogger(), "[" << this->getName() << "] Client Service: " << *serviceName_);

server_ = getNode()->create_service<TService>(
*serviceName_, std::bind(
&SmaccServiceServerClient<TService>::serviceCallback, this,
std::placeholders::_1, std::placeholders::_2));

this->initialized_ = true;
}
}
}

private:
void serviceCallback(
const std::shared_ptr<typename TService::Request> req,
std::shared_ptr<typename TService::Response> res)
{
onServiceRequestReceived_(req, res);
}
typename rclcpp::Service<TService>::SharedPtr server_;
bool initialized_;
};
} // namespace client_bases
} // namespace smacc2
4 changes: 3 additions & 1 deletion smacc2/include/smacc2/client_behaviors/cb_sequence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ class CbSequence : public smacc2::SmaccAsyncClientBehavior
{
std::function<std::shared_ptr<smacc2::SmaccAsyncClientBehavior>()> delayedCBFactoryFn =
[this, args...]() {
RCLCPP_INFO(getLogger(), "CbSequence::then creating new sub behavior");
RCLCPP_INFO(
getLogger(), "[CbSequence] then creating new sub behavior %s ",
demangleSymbol<TBehavior>().c_str());
auto createdBh = std::shared_ptr<TBehavior>(new TBehavior(args...));

this->getCurrentState()->getOrthogonal<TOrthogonal>()->addClientBehavior(createdBh);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// 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/smacc_client_behavior.hpp>

namespace smacc2
{
template <typename TService>
class CbServiceServerCallbackBase : public smacc2::SmaccClientBehavior
{
public:
virtual void onEntry() override
{
this->requiresClient(attachedClient_);
attachedClient_->onServiceRequestReceived(
&CbServiceServerCallbackBase::onServiceRequestReceived, this);
}

virtual void onServiceRequestReceived(
const std::shared_ptr<typename TService::Request> req,
std::shared_ptr<typename TService::Response> res) = 0;

protected:
smacc2::client_bases::SmaccServiceServerClient<TService> * attachedClient_ = nullptr;
};
} // namespace smacc2
8 changes: 6 additions & 2 deletions smacc2/include/smacc2/impl/smacc_orthogonal_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,18 @@ void ISmaccOrthogonal::assignClientToOrthogonal(TClient * client)
}

template <typename TClientBehavior>
TClientBehavior * ISmaccOrthogonal::getClientBehavior()
TClientBehavior * ISmaccOrthogonal::getClientBehavior(int index)
{
int i = 0;
for (auto & cb : this->clientBehaviors_)
{
auto * ret = dynamic_cast<TClientBehavior *>(cb.get());
if (ret != nullptr)
{
return ret;
if (i == index)
return ret;
else
i++;
}
}

Expand Down
4 changes: 2 additions & 2 deletions smacc2/include/smacc2/impl/smacc_state_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,9 @@ TOrthogonal * ISmaccState::getOrthogonal()
}

template <typename TOrthogonal, typename TClientBehavior>
TClientBehavior * ISmaccState::getClientBehavior()
TClientBehavior * ISmaccState::getClientBehavior(int index)
{
return this->getStateMachine().getClientBehavior<TOrthogonal, TClientBehavior>();
return this->getStateMachine().getClientBehavior<TOrthogonal, TClientBehavior>(index);
}

template <typename TEventGenerator>
Expand Down
6 changes: 5 additions & 1 deletion smacc2/include/smacc2/smacc_orthogonal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ class ISmaccOrthogonal
template <typename T>
bool getGlobalSMData(std::string name, T & ret);

// returns a client behavior of a given type. If the client behavior is not found, it returns nullptr
// the index parameter is used to specify the client behavior in case there are more than one
template <typename TClientBehavior>
TClientBehavior * getClientBehavior();
TClientBehavior * getClientBehavior(int index = 0);

rclcpp::Node::SharedPtr getNode();
inline rclcpp::Logger getLogger() { return getNode()->get_logger(); }
Expand All @@ -79,6 +81,8 @@ class ISmaccOrthogonal

std::vector<std::shared_ptr<smacc2::ISmaccClientBehavior>> clientBehaviors_;
friend class ISmaccStateMachine;

std::mutex mutex_;
};

} // namespace smacc2

0 comments on commit 193a8a3

Please sign in to comment.