Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP][Feature] Implement map action for dynamic kick #50

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
26241ab
feat: add map_action and start method for dynamic kick
hiikariri Apr 17, 2024
699898a
fix: assign new joint value to the correct action
hiikariri Apr 18, 2024
9923f38
fix: use name based action start
hiikariri Apr 18, 2024
3ff4276
feat: add subscriber for ball.x and adapt dynamic kick based on the a…
hiikariri Apr 18, 2024
990adf6
fix: update subscriber using float64
hiikariri May 9, 2024
879c47d
Merge branch 'master' of github.com:ichiro-its/akushon into feature/i…
hiikariri May 9, 2024
ce65c97
Merge branch 'master' of github.com:ichiro-its/akushon into feature/i…
hiikariri May 29, 2024
91a4001
feat:: add config, fix start action
hiikariri Jun 7, 2024
cf7c60c
feat: add config, fix bug
hiikariri Jun 8, 2024
d00bd1e
Merge branch 'master' of github.com:ichiro-its/akushon into feature/i…
hiikariri Jun 23, 2024
49582d6
Merge branch 'master' of github.com:ichiro-its/akushon into feature/i…
hiikariri Jun 25, 2024
3305e40
Merge branch 'feature/implement-map-action-for-dynamic-kick' of githu…
hiikariri Jun 25, 2024
41379b2
fix: fix map action, fix start action
hiikariri Jun 25, 2024
36d11ed
feat: use prefix decrement, refactor start action, adjust config path…
hiikariri Jun 26, 2024
9af16ab
fix: use prefix decrement for better looping
hiikariri Jun 27, 2024
83b04b7
Merge branch 'master' of github.com:ichiro-its/akushon into feature/i…
hiikariri Jun 27, 2024
97d4415
fix: fix set config using jitsuyo
hiikariri Jun 27, 2024
a6e1eaf
fix: fix loop decrement
hiikariri Jul 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/akushon/action/model/action.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ class Action

void reset();

void map_action(const Action & source_action, const Action & target_action, int target_pose_index, float source_val, float source_min, float source_max);

bool time_based;
private:
std::string name;
Expand Down
10 changes: 10 additions & 0 deletions include/akushon/action/node/action_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ class ActionManager
Action get_action(std::string action_name) const;

void load_config(const std::string & path);
void set_config(const nlohmann::json & json);

Action load_action(const nlohmann::json & action_data, const std::string & action_name) const;

void start(std::string action_name, const Pose & initial_pose);
void start(std::string action_name, std::string target_action_name, const Pose & initial_pose, float ball_x, float right_map_x_min_, float right_map_x_max_, float left_map_x_min_, float left_map_x_max_, bool right);
void start(const Action & action, const Pose & initial_pose);
void brake();
void process(double time);
Expand All @@ -57,11 +59,19 @@ class ActionManager

std::vector<tachimawari::joint::Joint> get_joints() const;

bool using_dynamic_kick;
double right_map_x_min;
double right_map_x_max;
double left_map_x_min;
double left_map_x_max;

private:
std::map<std::string, Action> actions;

std::shared_ptr<Interpolator> interpolator;
bool is_running;
std::string config_name;
std::string action_dir;
};

} // namespace akushon
Expand Down
7 changes: 7 additions & 0 deletions include/akushon/action/node/action_node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
#include "akushon_interfaces/msg/status.hpp"
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/empty.hpp"
#include "std_msgs/msg/float64.hpp"
#include "tachimawari_interfaces/msg/current_joints.hpp"
#include "tachimawari_interfaces/msg/set_joints.hpp"
#include "keisan/keisan.hpp"

namespace akushon
{
Expand All @@ -45,6 +47,7 @@ class ActionNode
using RunAction = akushon_interfaces::msg::RunAction;
using SetJoints = tachimawari_interfaces::msg::SetJoints;
using Status = akushon_interfaces::msg::Status;
using Float64 = std_msgs::msg::Float64;

enum { READY, PLAYING };

Expand All @@ -54,6 +57,7 @@ class ActionNode
static std::string run_action_topic();
static std::string brake_action_topic();
static std::string status_topic();
static std::string ball_topic();

explicit ActionNode(
rclcpp::Node::SharedPtr node, std::shared_ptr<ActionManager> & action_manager);
Expand All @@ -68,6 +72,8 @@ class ActionNode
void publish_status();

Pose initial_pose;
double ball_pos;

rclcpp::Node::SharedPtr node;

std::shared_ptr<ActionManager> action_manager;
Expand All @@ -77,6 +83,7 @@ class ActionNode

rclcpp::Subscription<RunAction>::SharedPtr run_action_subscriber;
rclcpp::Subscription<Empty>::SharedPtr brake_action_subscriber;
rclcpp::Subscription<Float64>::SharedPtr ball_subscriber;
rclcpp::Publisher<Status>::SharedPtr status_publisher;
};

Expand Down
2 changes: 2 additions & 0 deletions include/akushon/config/utils/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ class Config

std::string get_config() const;
void save_config(const std::string & actions_data);
void clear_directory(const std::string& directory_path);

private:
std::string path;
std::string action_dir;
};

} // namespace akushon
Expand Down
46 changes: 45 additions & 1 deletion src/akushon/action/model/action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <vector>

#include "akushon/action/model/action.hpp"

#include "rclcpp/rclcpp.hpp"
#include "akushon/action/model/pose.hpp"

namespace akushon
Expand Down Expand Up @@ -110,4 +110,48 @@ void Action::reset()
poses.clear();
}

void Action::map_action(const Action & source_action, const Action & target_action, int target_pose_index, float source_val, float source_min, float source_max)
{
std::vector<tachimawari::joint::Joint> src_joints = source_action.get_pose(target_pose_index).get_joints();
std::vector<tachimawari::joint::Joint> target_joints = target_action.get_pose(target_pose_index).get_joints();
for (int joint = 0; joint < int(src_joints.size()); joint++)
threeal marked this conversation as resolved.
Show resolved Hide resolved
threeal marked this conversation as resolved.
Show resolved Hide resolved
{
int joint_id = src_joints.at(joint).get_id();
float target_min = src_joints.at(joint).get_position_value();
float target_max = target_joints.at(joint).get_position_value();
float new_joint_value = keisan::map(source_val, source_min, source_max, target_min, target_max);
new_joint_value = keisan::curve(new_joint_value, target_min, target_max, float(2.0));
new_joint_value = keisan::clamp(new_joint_value, target_min, target_max);
target_joints[joint].set_position_value(int(std::round(new_joint_value)));
RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Joint %d: %f -> %d", joint_id, target_min, int(std::round(new_joint_value)));
RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Cek value in target joints %d: %f -> %d", target_joints[joint].get_id(), target_max, target_joints[joint].get_position_value());
}
Pose new_pose(target_action.get_pose(target_pose_index).get_name());
new_pose.set_pause(source_action.get_pose(target_pose_index).get_pause());
new_pose.set_speed(source_action.get_pose(target_pose_index).get_speed());
new_pose.action_time = source_action.get_pose(target_pose_index).action_time;
new_pose.set_joints(target_joints);

RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Cek new pose name %s", new_pose.get_name().c_str());
RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Cek new pose pause %f", new_pose.get_pause());
RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Cek new pose speed %f", new_pose.get_speed());
RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Cek new pose joints size %ld", new_pose.get_joints().size());
for (int joint = 0; joint < int(new_pose.get_joints().size()); joint++)
threeal marked this conversation as resolved.
Show resolved Hide resolved
{
RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Cek new pose joints %d: %d", new_pose.get_joints().at(joint).get_id(), new_pose.get_joints().at(joint).get_position_value());
}

this->delete_pose(target_pose_index);
this->set_pose(target_pose_index, new_pose);

RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Cek changed pose name %s", this->get_pose(target_pose_index).get_name().c_str());
RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Cek changed pose pause %f", this->get_pose(target_pose_index).get_pause());
RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Cek changed pose speed %f", this->get_pose(target_pose_index).get_speed());
RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Cek changed pose joints size %ld", this->get_pose(target_pose_index).get_joints().size());
for (int joint = 0; joint < int(this->get_pose(target_pose_index).get_joints().size()); joint++)
threeal marked this conversation as resolved.
Show resolved Hide resolved
{
RCLCPP_INFO(rclcpp::get_logger("Map Action"), "Cek changed pose joints %d: %d", this->get_pose(target_pose_index).get_joints().at(joint).get_id(), this->get_pose(target_pose_index).get_joints().at(joint).get_position_value());
}
}

} // namespace akushon
80 changes: 77 additions & 3 deletions src/akushon/action/node/action_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace akushon
{

ActionManager::ActionManager()
: actions({}), is_running(false)
: actions({}), is_running(false), config_name("dynamic_kick.json"), action_dir("actions/")
{
interpolator = std::make_shared<Interpolator>(std::vector<Action>(), Pose(""));
}
Expand All @@ -67,11 +67,24 @@ Action ActionManager::get_action(std::string action_name) const

void ActionManager::load_config(const std::string & path)
{
for (const auto & entry : std::filesystem::directory_iterator(path)) {
try {
std::ifstream file(path + config_name);
nlohmann::json data = nlohmann::json::parse(file);

set_config(data);

file.close();
} catch (nlohmann::json::parse_error & ex) {
std::cerr << "failed to load action: " << config_name << std::endl;
std::cerr << "parse error at byte " << ex.byte << std::endl;
throw ex;
}

for (const auto & entry : std::filesystem::directory_iterator(path + action_dir)) {
std::string name = "";
std::string file_name = entry.path();
std::string extension_json = ".json";
for (int i = path.length(); i < file_name.length() - extension_json.length(); i++) {
for (int i = (path + action_dir).length(); i < file_name.length() - extension_json.length(); i++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto:

Suggested change
for (int i = (path + action_dir).length(); i < file_name.length() - extension_json.length(); i++) {
for (int i = (path + action_dir).length(); i < file_name.length() - extension_json.length(); ++i) {

name += file_name[i];
}

Expand All @@ -90,6 +103,25 @@ void ActionManager::load_config(const std::string & path)
}
}

void ActionManager::set_config(const nlohmann::json & json)
{
for (auto &[key, val] : json.items()) {
if (key == "dynamic_kick") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use nlohmann::json::find instead of for-looping the items.

try {
val.at("right_map_x_min").get_to(right_map_x_min);
val.at("right_map_x_max").get_to(right_map_x_max);
val.at("left_map_x_min").get_to(left_map_x_min);
val.at("left_map_x_max").get_to(left_map_x_max);
val.at("using_dynamic_kick").get_to(using_dynamic_kick);
} catch (nlohmann::json::parse_error & ex) {
std::cerr << "error key: " << key << std::endl;
std::cerr << "parse error at byte " << ex.byte << std::endl;
throw ex;
}
}
}
}

Action ActionManager::load_action(
const nlohmann::json & action_data,
const std::string & action_name) const
Expand Down Expand Up @@ -160,6 +192,48 @@ void ActionManager::start(std::string action_name, const Pose & initial_pose)
is_running = true;
}

void ActionManager::start(std::string action_name, std::string target_action_name, const Pose & initial_pose, float ball_x, float right_map_x_min_, float right_map_x_max_, float left_map_x_min_, float left_map_x_max_, bool right)
{
std::vector<Action> target_actions;

while (true) {
auto action = actions.at(action_name);
const auto & target_action = actions.at(target_action_name);
int pose_count = action.get_pose_count();
for (int pose_index = 0; pose_index < pose_count; pose_index++) {
threeal marked this conversation as resolved.
Show resolved Hide resolved
if (right)
{
RCLCPP_INFO(rclcpp::get_logger("DEBUG ACTION MANAGER"), "Start Mapping!");
action.map_action(action, target_action, pose_index, ball_x, right_map_x_min_, right_map_x_max_);
} else {
RCLCPP_INFO(rclcpp::get_logger("DEBUG ACTION MANAGER"), "Start Mapping!");
action.map_action(action, target_action, pose_index, ball_x, left_map_x_min_, left_map_x_max_);
}
}
threeal marked this conversation as resolved.
Show resolved Hide resolved

RCLCPP_INFO(rclcpp::get_logger("DEBUG ACTION MANAGER"), "New Action Count: %d", action.get_pose_count());
for (const auto& the_action : target_actions) {
RCLCPP_INFO(rclcpp::get_logger("DEBUG ACTION MANAGER"), "Action Vector: %s", the_action.get_name().c_str());
}
target_actions.push_back(action);

if (action.get_next_action() != "") {
std::string next_action_name = action.get_next_action();

if (actions.find(next_action_name) != actions.end()) {
action_name = next_action_name;
} else {
break;
}
} else {
break;
}
}

interpolator = std::make_shared<Interpolator>(target_actions, initial_pose);
is_running = true;
}

void ActionManager::start(const Action & action, const Pose & initial_pose)
{
std::vector<Action> target_actions {action};
Expand Down
34 changes: 33 additions & 1 deletion src/akushon/action/node/action_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ std::string ActionNode::brake_action_topic() {return get_node_prefix() + "/brake

std::string ActionNode::status_topic() {return get_node_prefix() + "/status";}

std::string ActionNode::ball_topic() {return get_node_prefix() + "/ball";}

ActionNode::ActionNode(
rclcpp::Node::SharedPtr node, std::shared_ptr<ActionManager> & action_manager)
: node(node), action_manager(action_manager), initial_pose(Pose("initial_pose"))
Expand Down Expand Up @@ -88,14 +90,44 @@ ActionNode::ActionNode(
brake_action_subscriber = node->create_subscription<Empty>(
brake_action_topic(), 10,
[this](std::shared_ptr<Empty> message) {this->action_manager->brake();});

ball_subscriber = node->create_subscription<Float64>(
ball_topic(), 10, [this](const std::shared_ptr<Float64> message) {
ball_pos = message->data;
});
}

bool ActionNode::start(const std::string & action_name)
{
Pose pose = this->initial_pose;

if (!pose.get_joints().empty()) {
action_manager->start(action_name, pose);
if (action_name == akushon::ActionName::LEFT_KICK_WIDE || action_name == akushon::ActionName::RIGHT_KICK_WIDE)
{
std::size_t pos = action_name.find("_wide");
std::string source_action;
bool right = false;

if (pos != std::string::npos) {
source_action = action_name.substr(0, pos);
} else {
source_action = action_name;
}
threeal marked this conversation as resolved.
Show resolved Hide resolved

if (source_action == "right_kick") {
right = true;
}

RCLCPP_INFO(rclcpp::get_logger("Action Node"), "Start WIDE_KICK, source %s, target %s\n", source_action.c_str(), action_name.c_str());
if (action_manager->using_dynamic_kick)
action_manager->start(source_action, action_name, pose, ball_pos, action_manager->right_map_x_min, action_manager->right_map_x_max, action_manager->left_map_x_min, action_manager->left_map_x_max, right);
threeal marked this conversation as resolved.
Show resolved Hide resolved
else
action_manager->start(action_name, pose);
}
else {
RCLCPP_INFO(rclcpp::get_logger("Action Node"), "NOT WIDE KICK\n");
action_manager->start(action_name, pose);
}
} else {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/akushon/config/node/config_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ ConfigNode::ConfigNode(rclcpp::Node::SharedPtr node, const std::string & path,
response->status = "SAVED";
}
);
config_grpc.Run(5060, path, node, action_manager);
config_grpc.Run(5050, path, node, action_manager);
RCLCPP_INFO(rclcpp::get_logger("GrpcServers"), "grpc running");
}

Expand Down
20 changes: 11 additions & 9 deletions src/akushon/config/utils/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ namespace akushon
{

Config::Config(const std::string & path)
: path(path)
: path(path), action_dir("actions/")
{
}

std::string Config::get_config() const
{
nlohmann::json actions_list;
std::cout << "[ ACTIONS LIST ] : " << std::endl;
for (const auto & action_file : std::filesystem::directory_iterator(path)) {
for (const auto & action_file : std::filesystem::directory_iterator(path + action_dir)) {
std::string file_name = action_file.path();

std::string action_name = "";
Expand Down Expand Up @@ -74,13 +74,15 @@ std::string Config::get_config() const

void Config::save_config(const std::string & actions_data)
{
nlohmann::json actions_list = nlohmann::json::parse(actions_data);
for (const auto & [key, val] : actions_list.items()) {
std::locale loc;
std::string action_name = key;
std::replace(action_name.begin(), action_name.end(), ' ', '_');
std::string file_name = path + action_name + ".json";
std::ofstream file;
try {
clear_directory(path + action_dir);
nlohmann::json actions_list = nlohmann::json::parse(actions_data);
for (const auto & [key, val] : actions_list.items()) {
std::locale loc;
threeal marked this conversation as resolved.
Show resolved Hide resolved
std::string action_name = key;
std::replace(action_name.begin(), action_name.end(), ' ', '_');
std::string file_name = path + action_dir + action_name + ".json";
std::ofstream file;

if (!jitsuyo::save_config(path, action_name + ".json", val)) {
std::cerr << "Failed to save " << file_name << std::endl;
Expand Down
Loading