Connected and added movement part of Plugin.
This commit is contained in:
parent
38263dd13f
commit
f9f1766004
@ -48,29 +48,50 @@ void ActorSystem::switchAnimation(EntityComponentManager &_ecm, std::string& ani
|
|||||||
*animationTimeComponent = components::AnimationTime(std::chrono::milliseconds::zero());
|
*animationTimeComponent = components::AnimationTime(std::chrono::milliseconds::zero());
|
||||||
_ecm.SetChanged(entity, components::AnimationTime::typeId, ComponentState::OneTimeChange);
|
_ecm.SetChanged(entity, components::AnimationTime::typeId, ComponentState::OneTimeChange);
|
||||||
|
|
||||||
int foundIndex = -1;
|
int foundAnimationIndex = -1;
|
||||||
for (int animationIndex = 0 ; animationIndex < actorComp->Data().AnimationCount() ; animationIndex++) {
|
for (int animationIndex = 0 ; animationIndex < actorComp->Data().AnimationCount() ; animationIndex++) {
|
||||||
auto animation = actorComp->Data().AnimationByIndex(animationIndex);
|
auto animation = actorComp->Data().AnimationByIndex(animationIndex);
|
||||||
if (animation->Name() == animationName){
|
if (animation->Name() == animationName){
|
||||||
foundIndex = animationIndex;
|
foundAnimationIndex = animationIndex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(foundIndex!=-1){
|
if(foundAnimationIndex != -1){
|
||||||
igndbg << "Found animation to play" << std::endl;
|
igndbg << "Found animation to play" << std::endl;
|
||||||
auto fileName = actorComp->Data().AnimationByIndex(foundIndex)->Filename();
|
auto fileName = actorComp->Data().AnimationByIndex(foundAnimationIndex)->Filename();
|
||||||
igndbg << "Path: " << fileName << std::endl;
|
|
||||||
igndbg << "Name: " << common::MeshManager::Instance()->Load(fileName)->Name() << std::endl;
|
|
||||||
|
|
||||||
auto skeleton = common::MeshManager::Instance()->Load(fileName)->MeshSkeleton();
|
currentSkeleton = common::MeshManager::Instance()->Load(fileName)->MeshSkeleton();
|
||||||
|
|
||||||
if (skeleton != nullptr){
|
igndbg << "FileName: " << fileName << std::endl;
|
||||||
duration = skeleton->Animation(0)->Length();
|
igndbg << "AnimCnt: " << currentSkeleton->AnimationCount() << std::endl;
|
||||||
|
|
||||||
|
auto rootNode = currentSkeleton->RootNode()->Name();
|
||||||
|
|
||||||
|
currentRootNodeAnimation = currentSkeleton->Animation(0)->NodeAnimationByName(rootNode);
|
||||||
|
currentTranslationAlign = currentSkeleton->AlignTranslation(0, rootNode);
|
||||||
|
currentRotationAlign = currentSkeleton->AlignRotation(0, rootNode);
|
||||||
|
|
||||||
|
igndbg << "Translation: " << currentTranslationAlign << std::endl;
|
||||||
|
igndbg << "Rotation: " << currentRotationAlign << std::endl;
|
||||||
|
|
||||||
|
if (currentSkeleton != nullptr){
|
||||||
|
duration = currentSkeleton->Animation(0)->Length();
|
||||||
igndbg << "length: " << duration << " seconds." << std::endl;
|
igndbg << "length: " << duration << " seconds." << std::endl;
|
||||||
} else {
|
} else {
|
||||||
ignerr << "No skeleton found!" << std::endl;
|
ignerr << "No skeleton found!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
auto initialPose = currentRootNodeAnimation -> FrameAt(0).Pose();
|
||||||
|
auto poseComponent = _ecm.Component<components::Pose>(entity);
|
||||||
|
|
||||||
|
auto newPose = initialPose;
|
||||||
|
newPose.Pos().X(0);
|
||||||
|
newPose.Pos().Y(0);
|
||||||
|
*poseComponent = components::Pose(newPose);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ignerr << "No animation found!" << std::endl;
|
ignerr << "No animation found!" << std::endl;
|
||||||
}
|
}
|
||||||
@ -82,40 +103,26 @@ void ActorSystem::PreUpdate(const UpdateInfo &_info, EntityComponentManager &_ec
|
|||||||
case SETUP: {
|
case SETUP: {
|
||||||
igndbg << "Setting up actor plugin" << std::endl;
|
igndbg << "Setting up actor plugin" << std::endl;
|
||||||
|
|
||||||
auto actorComp = _ecm.Component<components::Actor>(entity);
|
auto actorComponent = _ecm.Component<components::Actor>(entity);
|
||||||
|
|
||||||
auto animationNameComp = _ecm.Component<components::AnimationName>(entity);
|
auto animationNameComponent = _ecm.Component<components::AnimationName>(entity);
|
||||||
if (nullptr == animationNameComp) {
|
if (nullptr == animationNameComponent) {
|
||||||
_ecm.CreateComponent(entity, components::AnimationName(actorComp->Data().AnimationByIndex(0)->Name()));
|
_ecm.CreateComponent(entity, components::AnimationName(actorComponent->Data().AnimationByIndex(0)->Name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto animTimeComp = _ecm.Component<components::AnimationTime>(entity);
|
auto animTimeComponent = _ecm.Component<components::AnimationTime>(entity);
|
||||||
if (nullptr == animTimeComp) {
|
if (nullptr == animTimeComponent) {
|
||||||
_ecm.CreateComponent(entity, components::AnimationTime());
|
_ecm.CreateComponent(entity, components::AnimationTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
ignition::math::Pose3d initialPose;
|
auto poseComponent = _ecm.Component<components::Pose>(entity);
|
||||||
auto poseComp = _ecm.Component<components::Pose>(entity);
|
if (nullptr == poseComponent) {
|
||||||
if (nullptr == poseComp) {
|
|
||||||
_ecm.CreateComponent(entity, components::Pose(ignition::math::Pose3d::Zero));
|
_ecm.CreateComponent(entity, components::Pose(ignition::math::Pose3d::Zero));
|
||||||
} else {
|
|
||||||
initialPose = poseComp->Data();
|
|
||||||
|
|
||||||
// We'll be setting the actor's X/Y pose with respect to the world. So we
|
|
||||||
// zero the current values.
|
|
||||||
auto newPose = initialPose;
|
|
||||||
newPose.Pos().X(0);
|
|
||||||
newPose.Pos().Y(0);
|
|
||||||
*poseComp = components::Pose(newPose);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto trajectoryPoseComponent = _ecm.Component<components::TrajectoryPose>(entity);
|
||||||
|
if (nullptr == trajectoryPoseComponent) {
|
||||||
auto trajectoryPoseComp = _ecm.Component<components::TrajectoryPose>(entity);
|
_ecm.CreateComponent(entity, components::TrajectoryPose(ignition::math::Pose3d::Zero));
|
||||||
if (nullptr == trajectoryPoseComp) {
|
|
||||||
// Leave Z to the pose component, control only 2D with Trajectory
|
|
||||||
//initialPose.Pos().Z(0);
|
|
||||||
_ecm.CreateComponent(entity, components::TrajectoryPose(initialPose));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currentState = ActorSystemState::IDLE;
|
currentState = ActorSystemState::IDLE;
|
||||||
@ -143,34 +150,113 @@ void ActorSystem::PreUpdate(const UpdateInfo &_info, EntityComponentManager &_ec
|
|||||||
*animationTimeComponent = components::AnimationTime(newTime);
|
*animationTimeComponent = components::AnimationTime(newTime);
|
||||||
_ecm.SetChanged(entity, components::AnimationTime::typeId, ComponentState::OneTimeChange);
|
_ecm.SetChanged(entity, components::AnimationTime::typeId, ComponentState::OneTimeChange);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
if(currentRootNodeAnimation == nullptr){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rootTransformation = currentRootNodeAnimation->FrameAt(newTimeSeconds,false);
|
||||||
|
math::Matrix4d totalTf = currentTranslationAlign * rootTransformation * currentRotationAlign;
|
||||||
|
|
||||||
|
auto translation = totalTf.Translation();
|
||||||
|
translation[0] = 0;
|
||||||
|
totalTf.SetTranslation(translation);
|
||||||
|
|
||||||
|
auto poseComp = _ecm.Component<components::Pose>(entity);
|
||||||
|
*poseComp = components::Pose (totalTf.Pose());
|
||||||
|
_ecm.SetChanged(entity, components::Pose::typeId, ComponentState::OneTimeChange);
|
||||||
|
*/
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MOVEMENT:{
|
case MOVEMENT:{
|
||||||
if (lastState == ActorSystemState::IDLE){
|
if (lastState == ActorSystemState::IDLE){
|
||||||
|
igndbg << "Starting Movement..." << std::endl;
|
||||||
switchAnimation(_ecm, movementTarget.animation_name);
|
switchAnimation(_ecm, movementTarget.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 initialPose = actorPose;
|
|
||||||
auto targetPose = movementTarget.target_position;
|
auto targetPose = movementTarget.target_position;
|
||||||
|
|
||||||
double distanceTraveled = (actorPose.Pos() - initialPose.Pos()).Length();
|
auto targetDirection = actorPose.Pos() - math::Vector3d(targetPose[0],targetPose[1],targetPose[2]);
|
||||||
|
|
||||||
auto animTimeComp = _ecm.Component<components::AnimationTime>(
|
if (targetDirection.Length()<0.05){
|
||||||
this->entity);
|
currentMovementGoalPtr->succeed(std::make_shared<action::Movement::Result>());
|
||||||
|
currentState = ActorSystemState::IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
auto animTime = animTimeComp->Data() +
|
auto animationTimeComponent = _ecm.Component<components::AnimationTime>(this->entity);
|
||||||
std::chrono::duration_cast<std::chrono::steady_clock::duration>(
|
auto oldTimeSeconds = std::chrono::duration<double>(animationTimeComponent->Data()).count();
|
||||||
std::chrono::duration<double>(
|
auto deltaTimeSeconds = std::chrono::duration<double>(_info.dt).count();
|
||||||
distanceTraveled *
|
auto newTimeSeconds = oldTimeSeconds + deltaTimeSeconds;
|
||||||
1
|
auto newTime = animationTimeComponent->Data() + _info.dt;
|
||||||
)
|
|
||||||
);
|
if(newTimeSeconds >= duration){
|
||||||
*animTimeComp = components::AnimationTime(animTime);
|
newTimeSeconds -= duration;
|
||||||
|
newTime = std::chrono::duration_cast<std::chrono::steady_clock::duration>(std::chrono::duration<double>(newTimeSeconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto targetYaw = atan2(targetDirection.Y(),targetDirection.X());
|
||||||
|
auto currentYaw = actorPose.Rot().Yaw();
|
||||||
|
|
||||||
|
auto angularDirection = fmod((targetYaw - currentYaw), 2*M_PI);
|
||||||
|
if (angularDirection>M_PI){
|
||||||
|
angularDirection-=M_PI;
|
||||||
|
}
|
||||||
|
if (angularDirection<=-M_PI){
|
||||||
|
angularDirection+=M_PI;
|
||||||
|
}
|
||||||
|
auto turnSpeed = 1.0;
|
||||||
|
|
||||||
|
if (angularDirection < 0){
|
||||||
|
turnSpeed = -turnSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(angularDirection) > 0.01){
|
||||||
|
actorPose.Rot().Euler(0,0,actorPose.Rot().Yaw()+(turnSpeed*deltaTimeSeconds));
|
||||||
|
*trajectoryPoseComp = components::TrajectoryPose(actorPose);
|
||||||
|
_ecm.SetChanged(entity, components::TrajectoryPose::typeId, ComponentState::OneTimeChange);
|
||||||
|
}else{
|
||||||
|
if (nullptr == currentRootNodeAnimation){
|
||||||
|
ignerr << "Current animation doesn't move root node, this is unsupported for movement animations." << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
double distance;
|
||||||
|
if (oldTimeSeconds<=newTimeSeconds){
|
||||||
|
auto oldPos = currentRootNodeAnimation->FrameAt(oldTimeSeconds).Pose().X();
|
||||||
|
auto newPos = currentRootNodeAnimation->FrameAt(newTimeSeconds).Pose().X();
|
||||||
|
distance = oldPos - newPos;
|
||||||
|
}else{
|
||||||
|
auto oldPos = currentRootNodeAnimation->FrameAt(oldTimeSeconds).Pose().X();
|
||||||
|
// \/
|
||||||
|
auto endPos = currentRootNodeAnimation->KeyFrame(currentRootNodeAnimation->FrameCount()-1).second.Pose().X();
|
||||||
|
// Big Distance
|
||||||
|
auto startPos = currentRootNodeAnimation->KeyFrame(0).second.Pose().X();
|
||||||
|
// \/
|
||||||
|
auto newPos = currentRootNodeAnimation->FrameAt(newTimeSeconds).Pose().X();
|
||||||
|
|
||||||
|
distance = (oldPos - endPos) + (startPos - newPos);
|
||||||
|
igndbg << (oldPos - endPos) << "|" << (startPos - newPos) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
actorPose.Pos() += targetDirection.Normalize() * distance;
|
||||||
|
actorPose.Rot().Euler(0,0,targetYaw);
|
||||||
|
*trajectoryPoseComp = components::TrajectoryPose(actorPose);
|
||||||
|
*animationTimeComponent = components::AnimationTime(newTime);
|
||||||
|
|
||||||
|
_ecm.SetChanged(entity, components::TrajectoryPose::typeId, ComponentState::OneTimeChange);
|
||||||
|
_ecm.SetChanged(entity, components::AnimationTime::typeId, ComponentState::OneTimeChange);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IDLE:
|
case IDLE:
|
||||||
|
if (lastState != currentState){
|
||||||
|
igndbg << "Now idling..." << std::endl;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lastState = currentState;
|
lastState = currentState;
|
||||||
@ -202,6 +288,8 @@ void ActorSystem::Configure(const Entity &_entity, const std::shared_ptr<const s
|
|||||||
|
|
||||||
node = rclcpp::Node::make_shared("moveService", topic);
|
node = rclcpp::Node::make_shared("moveService", topic);
|
||||||
|
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma ide diagnostic ignored "UnusedValue"
|
||||||
animationServer = rclcpp_action::create_server<action::Animation>(
|
animationServer = rclcpp_action::create_server<action::Animation>(
|
||||||
node,
|
node,
|
||||||
"animation",
|
"animation",
|
||||||
@ -216,7 +304,7 @@ void ActorSystem::Configure(const Entity &_entity, const std::shared_ptr<const s
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
[this](const AnimationServerGoalPtr PH1) {
|
[this](const AnimationServerGoalPtr& animationGoalPtr) {
|
||||||
if (this->currentState == ActorSystemState::IDLE) {
|
if (this->currentState == ActorSystemState::IDLE) {
|
||||||
return rclcpp_action::CancelResponse::REJECT;
|
return rclcpp_action::CancelResponse::REJECT;
|
||||||
}else{
|
}else{
|
||||||
@ -227,14 +315,15 @@ void ActorSystem::Configure(const Entity &_entity, const std::shared_ptr<const s
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
[this](const AnimationServerGoalPtr PH1) {
|
[this](const AnimationServerGoalPtr& animationGoalPtr) {
|
||||||
threadMutex.lock();
|
threadMutex.lock();
|
||||||
currentAnimationGoalPtr = PH1;
|
currentAnimationGoalPtr = animationGoalPtr;
|
||||||
currentState = ActorSystemState::ANIMATION;
|
currentState = ActorSystemState::ANIMATION;
|
||||||
threadMutex.unlock();
|
threadMutex.unlock();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
movementServer = rclcpp_action::create_server<action::Movement>(
|
movementServer = rclcpp_action::create_server<action::Movement>(
|
||||||
node,
|
node,
|
||||||
"movement",
|
"movement",
|
||||||
@ -249,7 +338,7 @@ void ActorSystem::Configure(const Entity &_entity, const std::shared_ptr<const s
|
|||||||
return rclcpp_action::GoalResponse::REJECT;
|
return rclcpp_action::GoalResponse::REJECT;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[this](const MovementServerGoalPtr goalUuid ){
|
[this](const MovementServerGoalPtr& movementGoalPtr ){
|
||||||
if (this->currentState == ActorSystemState::IDLE) {
|
if (this->currentState == ActorSystemState::IDLE) {
|
||||||
return rclcpp_action::CancelResponse::REJECT;
|
return rclcpp_action::CancelResponse::REJECT;
|
||||||
}else{
|
}else{
|
||||||
@ -259,13 +348,14 @@ void ActorSystem::Configure(const Entity &_entity, const std::shared_ptr<const s
|
|||||||
return rclcpp_action::CancelResponse::ACCEPT;
|
return rclcpp_action::CancelResponse::ACCEPT;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[this](const MovementServerGoalPtr goalUuid ){
|
[this](const MovementServerGoalPtr& movementGoalPtr ){
|
||||||
threadMutex.lock();
|
threadMutex.lock();
|
||||||
currentMovementGoalPtr = goalUuid;
|
currentMovementGoalPtr = movementGoalPtr;
|
||||||
currentState = ActorSystemState::MOVEMENT;
|
currentState = ActorSystemState::MOVEMENT;
|
||||||
threadMutex.unlock();
|
threadMutex.unlock();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
igndbg << "Spinning node..." << std::endl;
|
igndbg << "Spinning node..." << std::endl;
|
||||||
std::thread spinThread([this]() {
|
std::thread spinThread([this]() {
|
||||||
|
|||||||
@ -18,6 +18,8 @@
|
|||||||
#include <ign_actor_plugin_msgs/action/movement.hpp>
|
#include <ign_actor_plugin_msgs/action/movement.hpp>
|
||||||
#include <rclcpp_action/server_goal_handle.hpp>
|
#include <rclcpp_action/server_goal_handle.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <ignition/common/Skeleton.hh>
|
||||||
|
#include <ignition/common/NodeAnimation.hh>
|
||||||
|
|
||||||
using namespace ign_actor_plugin_msgs;
|
using namespace ign_actor_plugin_msgs;
|
||||||
using rclcpp_action::ServerGoalHandle;
|
using rclcpp_action::ServerGoalHandle;
|
||||||
@ -54,6 +56,9 @@ namespace ignition {
|
|||||||
double duration{};
|
double duration{};
|
||||||
Entity entity{kNullEntity};
|
Entity entity{kNullEntity};
|
||||||
std::mutex threadMutex;
|
std::mutex threadMutex;
|
||||||
|
std::shared_ptr<common::Skeleton> currentSkeleton;
|
||||||
|
common::NodeAnimation* currentRootNodeAnimation;
|
||||||
|
math::Matrix4<double> currentRotationAlign, currentTranslationAlign;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ActorSystem();
|
ActorSystem();
|
||||||
@ -66,7 +71,7 @@ namespace ignition {
|
|||||||
EntityComponentManager &_ecm) override;
|
EntityComponentManager &_ecm) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Configure(const ignition::gazebo::Entity &_entity,
|
void Configure(const ignition::gazebo::Entity &animationGoalPtr,
|
||||||
const std::shared_ptr<const sdf::Element> &_sdf,
|
const std::shared_ptr<const sdf::Element> &_sdf,
|
||||||
EntityComponentManager &_ecm,
|
EntityComponentManager &_ecm,
|
||||||
EventManager &/*_eventMgr*/) override;
|
EventManager &/*_eventMgr*/) override;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user