Merge branch 'new_rclcpp_process'

This commit is contained in:
Bastian Hofmann 2023-02-02 06:20:54 +00:00
commit 355c8ff3b3
2 changed files with 222 additions and 114 deletions

View File

@ -3,7 +3,6 @@
// //
#include <chrono> #include <chrono>
#include <cstdio>
#include <ign_actor_plugin_msgs/action/detail/animation__struct.hpp> #include <ign_actor_plugin_msgs/action/detail/animation__struct.hpp>
#include <ignition/common/Console.hh> #include <ignition/common/Console.hh>
#include <ignition/gazebo/Entity.hh> #include <ignition/gazebo/Entity.hh>
@ -19,6 +18,9 @@
#include <ignition/common/MeshManager.hh> #include <ignition/common/MeshManager.hh>
#include <ignition/common/SkeletonAnimation.hh> #include <ignition/common/SkeletonAnimation.hh>
#include <ignition/common/Mesh.hh> #include <ignition/common/Mesh.hh>
#include <sys/mman.h>
#include <fcntl.h>
#include <cstdio>
IGNITION_ADD_PLUGIN( IGNITION_ADD_PLUGIN(
ignition::gazebo::ActorSystem, ignition::gazebo::ActorSystem,
@ -34,7 +36,7 @@ ActorSystem::ActorSystem() = default;
ActorSystem::~ActorSystem() = default; ActorSystem::~ActorSystem() = default;
void ActorSystem::switchAnimation(EntityComponentManager &_ecm, std::string& animationName){ void ActorSystem::switchAnimation(EntityComponentManager &_ecm, char* animationName){
igndbg << "Initial setup for new animation." << std::endl; igndbg << "Initial setup for new animation." << std::endl;
auto actorComp = _ecm.Component<components::Actor>(entity); auto actorComp = _ecm.Component<components::Actor>(entity);
@ -81,8 +83,6 @@ void ActorSystem::switchAnimation(EntityComponentManager &_ecm, std::string& ani
ignerr << "No skeleton found!" << std::endl; ignerr << "No skeleton found!" << std::endl;
} }
auto initialPose = currentRootNodeAnimation -> FrameAt(0).Pose(); auto initialPose = currentRootNodeAnimation -> FrameAt(0).Pose();
auto poseComponent = _ecm.Component<components::Pose>(entity); auto poseComponent = _ecm.Component<components::Pose>(entity);
@ -97,8 +97,8 @@ void ActorSystem::switchAnimation(EntityComponentManager &_ecm, std::string& ani
} }
void ActorSystem::PreUpdate(const UpdateInfo &_info, EntityComponentManager &_ecm) { void ActorSystem::PreUpdate(const UpdateInfo &_info, EntityComponentManager &_ecm) {
threadMutex.lock(); pthread_mutex_lock(&shared_mmap->mutex);
switch(this->currentState){ switch(shared_mmap->currentState){
case SETUP: { case SETUP: {
igndbg << "Setting up actor plugin" << std::endl; igndbg << "Setting up actor plugin" << std::endl;
@ -124,25 +124,25 @@ void ActorSystem::PreUpdate(const UpdateInfo &_info, EntityComponentManager &_ec
_ecm.CreateComponent(entity, components::TrajectoryPose(ignition::math::Pose3d::Zero)); _ecm.CreateComponent(entity, components::TrajectoryPose(ignition::math::Pose3d::Zero));
} }
currentState = ActorSystemState::IDLE; shared_mmap->currentState = ActorSystemState::IDLE;
break; break;
} }
case ANIMATION: { case ANIMATION: {
if (lastState == ActorSystemState::IDLE){ if (shared_mmap->lastState == ActorSystemState::IDLE){
switchAnimation(_ecm, animationTarget.animation_name); switchAnimation(_ecm, shared_mmap->animation_name);
} }
auto animationTimeComponent = _ecm.Component<components::AnimationTime>(this->entity); auto animationTimeComponent = _ecm.Component<components::AnimationTime>(this->entity);
auto newTime = animationTimeComponent->Data() + _info.dt; auto newTime = animationTimeComponent->Data() + _info.dt;
auto newTimeSeconds = std::chrono::duration<double>(newTime).count(); auto newTimeSeconds = std::chrono::duration<double>(newTime).count();
auto feedback = std::make_shared<action::Animation::Feedback>();
auto feedback = (float) (newTimeSeconds/duration);
feedback->set__progress((float) (newTimeSeconds/duration)); write(feedback_pipe[1],&feedback,sizeof(float));
currentAnimationGoalPtr->publish_feedback(feedback); //currentAnimationGoalPtr->publish_feedback(feedback);
if (newTimeSeconds >= duration){ if (newTimeSeconds >= duration){
currentAnimationGoalPtr->succeed(std::make_shared<action::Animation::Result>()); //currentAnimationGoalPtr->succeed(std::make_shared<action::Animation::Result>());
igndbg << "Animation " << animationTarget.animation_name << " finished." << std::endl; igndbg << "Animation " << shared_mmap->animation_name << " finished." << std::endl;
currentState = ActorSystemState::IDLE; shared_mmap->currentState = ActorSystemState::IDLE;
break; break;
} }
@ -170,20 +170,22 @@ void ActorSystem::PreUpdate(const UpdateInfo &_info, EntityComponentManager &_ec
break; break;
} }
case MOVEMENT:{ case MOVEMENT:{
if (lastState == ActorSystemState::IDLE){ if (shared_mmap->lastState == ActorSystemState::IDLE){
igndbg << "Starting Movement..." << std::endl; igndbg << "Starting Movement..." << std::endl;
switchAnimation(_ecm, movementTarget.animation_name); switchAnimation(_ecm, shared_mmap->animation_name);
} }
auto trajectoryPoseComp = _ecm.Component<components::TrajectoryPose>(this->entity); auto trajectoryPoseComp = _ecm.Component<components::TrajectoryPose>(this->entity);
auto actorPose = trajectoryPoseComp->Data(); auto actorPose = trajectoryPoseComp->Data();
auto targetPose = movementTarget.target_position; auto targetPose = shared_mmap->target_position;
auto targetDirection = math::Vector3d(targetPose[0],targetPose[1],targetPose[2]) - actorPose.Pos(); auto targetDirection = math::Vector3d(targetPose[0],targetPose[1],targetPose[2]) - actorPose.Pos();
if (targetDirection.Length()<0.05){ if (targetDirection.Length()<0.05){
currentMovementGoalPtr->succeed(std::make_shared<action::Movement::Result>()); float feedback = 1.0f;
currentState = ActorSystemState::IDLE; write(feedback_pipe[1],&feedback,sizeof(float));
//currentMovementGoalPtr->succeed(std::make_shared<action::Movement::Result>());
shared_mmap->currentState = ActorSystemState::IDLE;
break; break;
} }
@ -218,7 +220,7 @@ void ActorSystem::PreUpdate(const UpdateInfo &_info, EntityComponentManager &_ec
break; break;
} }
double distance = (deltaTimeSeconds/duration)*movementTarget.animation_distance; double distance = (deltaTimeSeconds/duration)*shared_mmap->animation_distance;
actorPose.Pos() += targetDirection.Normalize() * distance; actorPose.Pos() += targetDirection.Normalize() * distance;
@ -232,13 +234,140 @@ void ActorSystem::PreUpdate(const UpdateInfo &_info, EntityComponentManager &_ec
break; break;
} }
case IDLE: case IDLE:
if (lastState != currentState){ if (shared_mmap->lastState != shared_mmap->currentState){
igndbg << "Now idling..." << std::endl; igndbg << "Now idling..." << std::endl;
} }
break; break;
} }
lastState = currentState; shared_mmap->lastState = shared_mmap->currentState;
threadMutex.unlock(); pthread_mutex_unlock(&shared_mmap->mutex);
}
void ActorSystem::client(const std::string& topic){
rclcpp::init(0, {});
auto node = rclcpp::Node::make_shared("moveService", topic);
AnimationServerGoalPtr currentAnimationGoalPtr;
MovementServerGoalPtr currentMovementGoalPtr;
#pragma clang diagnostic push
#pragma ide diagnostic ignored "UnusedValue"
auto animationServer = rclcpp_action::create_server<action::Animation>(
node,
"animation",
[this](const rclcpp_action::GoalUUID goalUuid, const AnimationGoalPtr &animationGoal) {
if (shared_mmap->currentState == ActorSystemState::IDLE) {
pthread_mutex_lock(&shared_mmap->mutex);
//animationTarget = *animationGoal;
strcpy(shared_mmap->animation_name,animationGoal->animation_name.data());
pthread_mutex_unlock(&shared_mmap->mutex);
return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
}else{
return rclcpp_action::GoalResponse::REJECT;
}
},
[this,&currentAnimationGoalPtr](const AnimationServerGoalPtr& animationGoalPtr) {
currentAnimationGoalPtr = nullptr;
if (shared_mmap->currentState == ActorSystemState::IDLE) {
return rclcpp_action::CancelResponse::REJECT;
}else{
pthread_mutex_lock(&shared_mmap->mutex);
shared_mmap->currentState = ActorSystemState::IDLE;
pthread_mutex_unlock(&shared_mmap->mutex);
return rclcpp_action::CancelResponse::ACCEPT;
}
},
[this,&currentAnimationGoalPtr](const AnimationServerGoalPtr& animationGoalPtr) {
pthread_mutex_lock(&shared_mmap->mutex);
currentAnimationGoalPtr = animationGoalPtr;
shared_mmap->currentState = ActorSystemState::ANIMATION;
pthread_mutex_unlock(&shared_mmap->mutex);
}
);
auto movementServer = rclcpp_action::create_server<action::Movement>(
node,
"movement",
[this](const rclcpp_action::GoalUUID goalUuid, const MovementGoalPtr &movementGoal ){
if (shared_mmap->currentState == ActorSystemState::IDLE) {
pthread_mutex_lock(&shared_mmap->mutex);
//movementTarget = *movementGoal;
shared_mmap->target_position = math::Vector3d(
movementGoal->target_position[0],
movementGoal->target_position[1],
movementGoal->target_position[2]);
shared_mmap->animation_distance = movementGoal->animation_distance;
strcpy(shared_mmap->animation_name,movementGoal->animation_name.data());
pthread_mutex_unlock(&shared_mmap->mutex);
return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
}else{
return rclcpp_action::GoalResponse::REJECT;
}
},
[this,&currentMovementGoalPtr](const MovementServerGoalPtr& movementGoalPtr ){
currentMovementGoalPtr = nullptr;
if (shared_mmap->currentState == ActorSystemState::IDLE) {
return rclcpp_action::CancelResponse::REJECT;
}else{
pthread_mutex_lock(&shared_mmap->mutex);
shared_mmap->currentState = ActorSystemState::IDLE;
pthread_mutex_unlock(&shared_mmap->mutex);
return rclcpp_action::CancelResponse::ACCEPT;
}
},
[this,&currentMovementGoalPtr](const MovementServerGoalPtr& movementGoalPtr ){
pthread_mutex_lock(&shared_mmap->mutex);
currentMovementGoalPtr = movementGoalPtr;
shared_mmap->currentState = ActorSystemState::MOVEMENT;
pthread_mutex_unlock(&shared_mmap->mutex);
}
);
#pragma clang diagnostic pop
std::thread t([this,&currentAnimationGoalPtr,&currentMovementGoalPtr]() {
float progress;
while(true) {
read(feedback_pipe[0], &progress, sizeof(float));
pthread_mutex_lock(&shared_mmap->mutex);
if(currentAnimationGoalPtr!=nullptr){
auto feedback = std::make_shared<action::Animation::Feedback>();
feedback->set__progress(progress);
currentAnimationGoalPtr->publish_feedback(feedback);
}
if(currentMovementGoalPtr!=nullptr){
auto feedback = std::make_shared<action::Movement::Feedback>();
feedback->set__progress(progress);
currentMovementGoalPtr->publish_feedback(feedback);
}
if(progress == 1.0){
if(currentAnimationGoalPtr!=nullptr){
currentAnimationGoalPtr->succeed(std::make_shared<action::Animation::Result>());
}
if(currentMovementGoalPtr!=nullptr){
currentMovementGoalPtr->succeed(std::make_shared<action::Movement::Result>());
}
currentMovementGoalPtr = nullptr;
currentAnimationGoalPtr = nullptr;
}
pthread_mutex_unlock(&shared_mmap->mutex);
}
});
t.detach();
igndbg << "Spinning node..." << std::endl;
while (true) {
printf("Spinning...\n");
rclcpp::spin(node);
}
} }
// Found too late: https://github.com/AlanSixth/gazebo_ros_action_tutorial/blob/master/src/gazebo_ros_action_tutorial.cc // Found too late: https://github.com/AlanSixth/gazebo_ros_action_tutorial/blob/master/src/gazebo_ros_action_tutorial.cc
@ -252,95 +381,63 @@ void ActorSystem::Configure(const Entity &_entity, const std::shared_ptr<const s
ignerr << "Plugin not attached to actor, terminating." << std::endl; ignerr << "Plugin not attached to actor, terminating." << std::endl;
return; return;
} }
this->entity = _entity;
this->currentState = ActorSystemState::SETUP;
this->lastState = ActorSystemState::IDLE;
rclcpp::init(0, {});
std::string topic = "ActorPlugin"; std::string topic = "ActorPlugin";
if (_sdf->HasElement("topic")) { if (_sdf->HasElement("topic")) {
topic = _sdf->Get<std::string>("topic"); topic = _sdf->Get<std::string>("topic");
} }
node = rclcpp::Node::make_shared("moveService", topic); this->entity = _entity;
#pragma clang diagnostic push
#pragma ide diagnostic ignored "UnusedValue"
animationServer = rclcpp_action::create_server<action::Animation>(
node,
"animation",
[this](const rclcpp_action::GoalUUID goalUuid, const AnimationGoalPtr &animationGoal) {
if (this->currentState == ActorSystemState::IDLE) {
threadMutex.lock();
animationTarget = *animationGoal;
threadMutex.unlock();
return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
}else{
return rclcpp_action::GoalResponse::REJECT;
}
}, igndbg << "shmem setup" << std::endl;
[this](const AnimationServerGoalPtr& animationGoalPtr) { int fd = open(".", O_TMPFILE|O_RDWR, 00600);
if (this->currentState == ActorSystemState::IDLE) { auto structSize = sizeof(struct sharedMmap);
return rclcpp_action::CancelResponse::REJECT; if(ftruncate(fd, structSize)!=0){
}else{ ignerr << "ftruncate" << std::endl;
threadMutex.lock(); return;
this->currentState = ActorSystemState::IDLE; }
threadMutex.unlock(); shared_mmap = (struct sharedMmap *) mmap(nullptr,structSize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
return rclcpp_action::CancelResponse::ACCEPT; //close(fd);
}
}, if (shared_mmap == MAP_FAILED){
[this](const AnimationServerGoalPtr& animationGoalPtr) { ignerr << "MAP_FAILED" << std::endl;
threadMutex.lock(); return;
currentAnimationGoalPtr = animationGoalPtr; }
currentState = ActorSystemState::ANIMATION;
threadMutex.unlock();
}
);
pthread_mutexattr_t mutexattr;
if(pthread_mutexattr_init(&mutexattr)!=0){
ignerr << "pthread_mutexattr_init" << std::endl;
return;
}
if(pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED)!=0){
ignerr << "pthread_mutexattr_setpshared" << std::endl;
return;
}
if(pthread_mutex_init(&shared_mmap->mutex, &mutexattr)!=0){
ignerr << "pthread_mutex_init" << std::endl;
return;
}
movementServer = rclcpp_action::create_server<action::Movement>( shared_mmap->currentState = ActorSystemState::SETUP;
node, shared_mmap->lastState = ActorSystemState::IDLE;
"movement",
[this](const rclcpp_action::GoalUUID goalUuid, const MovementGoalPtr &movementGoal ){
if (this->currentState == ActorSystemState::IDLE) { igndbg << "pipe setup" << std::endl;
threadMutex.lock();
movementTarget = *movementGoal;
threadMutex.unlock();
return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
}else{
return rclcpp_action::GoalResponse::REJECT;
}
},
[this](const MovementServerGoalPtr& movementGoalPtr ){
if (this->currentState == ActorSystemState::IDLE) {
return rclcpp_action::CancelResponse::REJECT;
}else{
threadMutex.lock();
this->currentState = ActorSystemState::IDLE;
threadMutex.unlock();
return rclcpp_action::CancelResponse::ACCEPT;
}
},
[this](const MovementServerGoalPtr& movementGoalPtr ){
threadMutex.lock();
currentMovementGoalPtr = movementGoalPtr;
currentState = ActorSystemState::MOVEMENT;
threadMutex.unlock();
}
);
#pragma clang diagnostic pop
igndbg << "Spinning node..." << std::endl; if (pipe(feedback_pipe) < 0){
std::thread spinThread([this]() { igndbg << "pipe failed." << std::endl;
while (true) { return;
printf("Spinning...\n"); }
rclcpp::spin(node);
} switch(fork()){
}); case -1:
spinThread.detach(); ignerr << "Could not fork." << std::endl;
break;
case 0:
ignmsg << "Child fork." << std::endl;
client(topic);
break;
default:
ignmsg << "Parent fork." << std::endl;
break;
}
} }

View File

@ -39,26 +39,36 @@ namespace ignition {
SETUP, IDLE, MOVEMENT, ANIMATION SETUP, IDLE, MOVEMENT, ANIMATION
}; };
struct sharedMmap{
pthread_mutex_t mutex;
ActorSystemState currentState,lastState;
char animation_name[256];
double animation_distance;
math::Vector3d target_position;
};
class ActorSystem : class ActorSystem :
public System, public System,
public ISystemPreUpdate, public ISystemPreUpdate,
public ISystemConfigure { public ISystemConfigure {
private: private:
std::shared_ptr<rclcpp::Node> node; //std::shared_ptr<rclcpp::Node> node;
std::shared_ptr<AnimationActionServer > animationServer; //std::shared_ptr<AnimationActionServer> animationServer;
std::shared_ptr<MovementActionServer > movementServer; //std::shared_ptr<MovementActionServer> movementServer;
ActorSystemState currentState, lastState; //ActorSystemState currentState, lastState;
action::Animation::Goal animationTarget; //action::Animation::Goal animationTarget;
action::Movement::Goal movementTarget; //action::Movement::Goal movementTarget;
AnimationServerGoalPtr currentAnimationGoalPtr; //AnimationServerGoalPtr currentAnimationGoalPtr;
MovementServerGoalPtr currentMovementGoalPtr; //MovementServerGoalPtr currentMovementGoalPtr;
double duration{}; double duration{};
Entity entity{kNullEntity}; Entity entity{kNullEntity};
std::mutex threadMutex; //std::mutex threadMutex;
std::shared_ptr<common::Skeleton> currentSkeleton; std::shared_ptr<common::Skeleton> currentSkeleton;
common::NodeAnimation* currentRootNodeAnimation; common::NodeAnimation* currentRootNodeAnimation;
math::Matrix4<double> currentRotationAlign, currentTranslationAlign; math::Matrix4<double> currentRotationAlign, currentTranslationAlign;
struct sharedMmap* shared_mmap;
int feedback_pipe[2];
public: public:
ActorSystem(); ActorSystem();
@ -77,7 +87,8 @@ namespace ignition {
EventManager &/*_eventMgr*/) override; EventManager &/*_eventMgr*/) override;
private: private:
void switchAnimation(EntityComponentManager &_ecm, std::string &animationName); void switchAnimation(EntityComponentManager &_ecm, char *animationName);
void client(const std::string& topic);
}; };