diff --git a/software_training_assignment/CMakeLists.txt b/software_training_assignment/CMakeLists.txt
new file mode 100644
index 0000000..d5021c7
--- /dev/null
+++ b/software_training_assignment/CMakeLists.txt
@@ -0,0 +1,223 @@
+cmake_minimum_required(VERSION 2.8.3)
+project(software_training_assignment)
+
+## Compile as C++11, supported in ROS Kinetic and newer
+# add_compile_options(-std=c++11)
+
+## Find catkin macros and libraries
+## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
+## is used, also find other catkin packages
+find_package(catkin REQUIRED COMPONENTS
+ roscpp
+ rospy
+ std_msgs
+ message_generation
+ actionlib_msgs
+ genmsg
+)
+
+## System dependencies are found with CMake's conventions
+#find_package(catkin REQUIRED COMPONENTS acionlib_msgs)
+
+
+## Uncomment this if the package has a setup.py. This macro ensures
+## modules and global scripts declared therein get installed
+## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
+# catkin_python_setup()
+
+################################################
+## Declare ROS messages, services and actions ##
+################################################
+
+## To declare and build messages, services or actions from within this
+## package, follow these steps:
+## * Let MSG_DEP_SET be the set of packages whose message types you use in
+## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
+## * In the file package.xml:
+## * add a build_depend tag for "message_generation"
+## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
+## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
+## but can be declared for certainty nonetheless:
+## * add a exec_depend tag for "message_runtime"
+## * In this file (CMakeLists.txt):
+## * add "message_generation" and every package in MSG_DEP_SET to
+## find_package(catkin REQUIRED COMPONENTS ...)
+## * add "message_runtime" and every package in MSG_DEP_SET to
+## catkin_package(CATKIN_DEPENDS ...)
+## * uncomment the add_*_files sections below as needed
+## and list every .msg/.srv/.action file to be processed
+## * uncomment the generate_messages entry below
+## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
+
+## Generate messages in the 'msg' folder
+add_message_files(
+ FILES
+ TurtleDistance.msg
+ )
+
+## Generate services in the 'srv' folder
+ add_service_files(
+ FILES
+ Spawn.srv
+ )
+
+## Generate actions in the 'action' folder
+ add_action_files(
+ FILES
+ MoveTurtle.action
+ )
+
+## Generate added messages and services with any dependencies listed here
+ generate_messages(
+ DEPENDENCIES actionlib_msgs std_msgs
+ )
+
+################################################
+## Declare ROS dynamic reconfigure parameters ##
+################################################
+
+## To declare and build dynamic reconfigure parameters within this
+## package, follow these steps:
+## * In the file package.xml:
+## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
+## * In this file (CMakeLists.txt):
+## * add "dynamic_reconfigure" to
+## find_package(catkin REQUIRED COMPONENTS ...)
+## * uncomment the "generate_dynamic_reconfigure_options" section below
+## and list every .cfg file to be processed
+
+## Generate dynamic reconfigure parameters in the 'cfg' folder
+# generate_dynamic_reconfigure_options(
+# cfg/DynReconf1.cfg
+# cfg/DynReconf2.cfg
+# )
+
+###################################
+## catkin specific configuration ##
+###################################
+## The catkin_package macro generates cmake config files for your package
+## Declare things to be passed to dependent projects
+## INCLUDE_DIRS: uncomment this if your package contains header files
+## LIBRARIES: libraries you create in this project that dependent projects also need
+## CATKIN_DEPENDS: catkin_packages dependent projects also need
+## DEPENDS: system dependencies of this project that dependent projects also need
+catkin_package(
+# INCLUDE_DIRS include
+# LIBRARIES software_training_assignment
+ CATKIN_DEPENDS roscpp rospy std_msgs actionlib_msgs
+# DEPENDS system_lib
+)
+
+###########
+## Build ##
+###########
+
+## Specify additional locations of header files
+## Your package locations should be listed before other locations
+include_directories(
+# include
+ ${catkin_INCLUDE_DIRS}
+)
+
+## Declare a C++ library
+# add_library(${PROJECT_NAME}
+# src/${PROJECT_NAME}/software_training_assignment.cpp
+# )
+
+## Add cmake target dependencies of the library
+## as an example, code may need to be generated before libraries
+## either from message generation or dynamic reconfigure
+# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
+
+## Declare a C++ executable
+## With catkin_make all packages are built within a single CMake context
+## The recommended prefix ensures that target names across packages don't collide
+# add_executable(${PROJECT_NAME}_node src/software_training_assignment_node.cpp)
+
+## Rename C++ executable without prefix
+## The above recommended prefix causes long target names, the following renames the
+## target back to the shorter version for ease of user use
+## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
+# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
+
+## Add cmake target dependencies of the executable
+## same as for the library above
+# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
+
+## Specify libraries to link a library or executable target against
+# target_link_libraries(${PROJECT_NAME}_node
+# ${catkin_LIBRARIES}
+# )
+
+#############
+## Install ##
+#############
+
+# all install targets should use catkin DESTINATION variables
+# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
+
+## Mark executable scripts (Python etc.) for installation
+## in contrast to setup.py, you can choose the destination
+# install(PROGRAMS
+# scripts/my_python_script
+# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
+# )
+
+## Mark executables for installation
+## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
+# install(TARGETS ${PROJECT_NAME}_node
+# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
+# )
+
+## Mark libraries for installation
+## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
+# install(TARGETS ${PROJECT_NAME}
+# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
+# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
+# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
+# )
+
+## Mark cpp header files for installation
+# install(DIRECTORY include/${PROJECT_NAME}/
+# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
+# FILES_MATCHING PATTERN "*.h"
+# PATTERN ".svn" EXCLUDE
+# )
+
+## Mark other files for installation (e.g. launch and bag files, etc.)
+# install(FILES
+# # myfile1
+# # myfile2
+# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
+# )
+
+#############
+## Testing ##
+#############
+
+## Add gtest based cpp test target and link libraries
+# catkin_add_gtest(${PROJECT_NAME}-test test/test_software_training_assignment.cpp)
+# if(TARGET ${PROJECT_NAME}-test)
+# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
+# endif()
+
+## Add folders to be run by python nosetests
+# catkin_add_nosetests(test)
+add_executable(turtle_tf_server src/turtle_tf_server.cpp)
+target_link_libraries(turtle_tf_server ${catkin_LIBRARIES})
+add_dependencies(turtle_tf_server software_training_assignment_gencpp)
+
+add_executable(turtle_tf_publisher src/turtle_tf_publisher.cpp)
+target_link_libraries(turtle_tf_publisher ${catkin_LIBRARIES})
+add_dependencies(turtle_tf_publisher software_training_assignment_gencpp)
+
+add_executable(turtle_tf_client src/turtle_tf_client.cpp)
+target_link_libraries(turtle_tf_client ${catkin_LIBRARIES})
+
+add_executable(turtle_tf_distance src/turtle_tf_distance.cpp)
+target_link_libraries(turtle_tf_distance ${catkin_LIBRARIES})
+add_dependencies(turtle_tf_distance software_training_assignment_gencpp)
+
+add_executable(turtle_tf_reset src/turtle_tf_reset.cpp)
+target_link_libraries(turtle_tf_reset ${catkin_LIBRARIES})
+add_dependencies(turtle_tf_reset software_training_assignment_gencpp)
diff --git a/software_training_assignment/action/MoveTurtle.action b/software_training_assignment/action/MoveTurtle.action
new file mode 100644
index 0000000..3488aa8
--- /dev/null
+++ b/software_training_assignment/action/MoveTurtle.action
@@ -0,0 +1,8 @@
+#goal definition
+float32 waypoint_x
+---
+#result definition
+float32 time
+---
+#feedback
+float32 distance_to_goal
diff --git a/software_training_assignment/actionlib_msgs/CMakeLists.txt b/software_training_assignment/actionlib_msgs/CMakeLists.txt
new file mode 100644
index 0000000..03c62c1
--- /dev/null
+++ b/software_training_assignment/actionlib_msgs/CMakeLists.txt
@@ -0,0 +1,202 @@
+cmake_minimum_required(VERSION 2.8.3)
+project(actionlib_msgs)
+
+## Compile as C++11, supported in ROS Kinetic and newer
+# add_compile_options(-std=c++11)
+
+## Find catkin macros and libraries
+## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
+## is used, also find other catkin packages
+find_package(catkin REQUIRED)
+
+## System dependencies are found with CMake's conventions
+# find_package(Boost REQUIRED COMPONENTS system)
+
+
+## Uncomment this if the package has a setup.py. This macro ensures
+## modules and global scripts declared therein get installed
+## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
+# catkin_python_setup()
+
+################################################
+## Declare ROS messages, services and actions ##
+################################################
+
+## To declare and build messages, services or actions from within this
+## package, follow these steps:
+## * Let MSG_DEP_SET be the set of packages whose message types you use in
+## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
+## * In the file package.xml:
+## * add a build_depend tag for "message_generation"
+## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
+## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
+## but can be declared for certainty nonetheless:
+## * add a exec_depend tag for "message_runtime"
+## * In this file (CMakeLists.txt):
+## * add "message_generation" and every package in MSG_DEP_SET to
+## find_package(catkin REQUIRED COMPONENTS ...)
+## * add "message_runtime" and every package in MSG_DEP_SET to
+## catkin_package(CATKIN_DEPENDS ...)
+## * uncomment the add_*_files sections below as needed
+## and list every .msg/.srv/.action file to be processed
+## * uncomment the generate_messages entry below
+## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
+
+## Generate messages in the 'msg' folder
+# add_message_files(
+# FILES
+# Message1.msg
+# Message2.msg
+# )
+
+## Generate services in the 'srv' folder
+# add_service_files(
+# FILES
+# Service1.srv
+# Service2.srv
+# )
+
+## Generate actions in the 'action' folder
+# add_action_files(
+# FILES
+# Action1.action
+# Action2.action
+# )
+
+## Generate added messages and services with any dependencies listed here
+# generate_messages(
+# DEPENDENCIES
+# std_msgs # Or other packages containing msgs
+# )
+
+################################################
+## Declare ROS dynamic reconfigure parameters ##
+################################################
+
+## To declare and build dynamic reconfigure parameters within this
+## package, follow these steps:
+## * In the file package.xml:
+## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
+## * In this file (CMakeLists.txt):
+## * add "dynamic_reconfigure" to
+## find_package(catkin REQUIRED COMPONENTS ...)
+## * uncomment the "generate_dynamic_reconfigure_options" section below
+## and list every .cfg file to be processed
+
+## Generate dynamic reconfigure parameters in the 'cfg' folder
+# generate_dynamic_reconfigure_options(
+# cfg/DynReconf1.cfg
+# cfg/DynReconf2.cfg
+# )
+
+###################################
+## catkin specific configuration ##
+###################################
+## The catkin_package macro generates cmake config files for your package
+## Declare things to be passed to dependent projects
+## INCLUDE_DIRS: uncomment this if your package contains header files
+## LIBRARIES: libraries you create in this project that dependent projects also need
+## CATKIN_DEPENDS: catkin_packages dependent projects also need
+## DEPENDS: system dependencies of this project that dependent projects also need
+catkin_package(
+# INCLUDE_DIRS include
+# LIBRARIES actionlib_msgs
+# CATKIN_DEPENDS other_catkin_pkg
+# DEPENDS system_lib
+)
+
+###########
+## Build ##
+###########
+
+## Specify additional locations of header files
+## Your package locations should be listed before other locations
+include_directories(
+# include
+# ${catkin_INCLUDE_DIRS}
+)
+
+## Declare a C++ library
+# add_library(${PROJECT_NAME}
+# src/${PROJECT_NAME}/actionlib_msgs.cpp
+# )
+
+## Add cmake target dependencies of the library
+## as an example, code may need to be generated before libraries
+## either from message generation or dynamic reconfigure
+# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
+
+## Declare a C++ executable
+## With catkin_make all packages are built within a single CMake context
+## The recommended prefix ensures that target names across packages don't collide
+# add_executable(${PROJECT_NAME}_node src/actionlib_msgs_node.cpp)
+
+## Rename C++ executable without prefix
+## The above recommended prefix causes long target names, the following renames the
+## target back to the shorter version for ease of user use
+## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
+# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
+
+## Add cmake target dependencies of the executable
+## same as for the library above
+# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
+
+## Specify libraries to link a library or executable target against
+# target_link_libraries(${PROJECT_NAME}_node
+# ${catkin_LIBRARIES}
+# )
+
+#############
+## Install ##
+#############
+
+# all install targets should use catkin DESTINATION variables
+# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
+
+## Mark executable scripts (Python etc.) for installation
+## in contrast to setup.py, you can choose the destination
+# install(PROGRAMS
+# scripts/my_python_script
+# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
+# )
+
+## Mark executables for installation
+## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
+# install(TARGETS ${PROJECT_NAME}_node
+# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
+# )
+
+## Mark libraries for installation
+## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
+# install(TARGETS ${PROJECT_NAME}
+# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
+# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
+# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
+# )
+
+## Mark cpp header files for installation
+# install(DIRECTORY include/${PROJECT_NAME}/
+# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
+# FILES_MATCHING PATTERN "*.h"
+# PATTERN ".svn" EXCLUDE
+# )
+
+## Mark other files for installation (e.g. launch and bag files, etc.)
+# install(FILES
+# # myfile1
+# # myfile2
+# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
+# )
+
+#############
+## Testing ##
+#############
+
+## Add gtest based cpp test target and link libraries
+# catkin_add_gtest(${PROJECT_NAME}-test test/test_actionlib_msgs.cpp)
+# if(TARGET ${PROJECT_NAME}-test)
+# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
+# endif()
+
+## Add folders to be run by python nosetests
+# catkin_add_nosetests(test)
diff --git a/software_training_assignment/actionlib_msgs/package.xml b/software_training_assignment/actionlib_msgs/package.xml
new file mode 100644
index 0000000..8511d2c
--- /dev/null
+++ b/software_training_assignment/actionlib_msgs/package.xml
@@ -0,0 +1,59 @@
+
+
+ actionlib_msgs
+ 0.0.0
+ The actionlib_msgs package
+
+
+
+
+ tieuchanlong
+
+
+
+
+
+ TODO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ catkin
+
+
+
+
+
+
+
+
diff --git a/software_training_assignment/launch/turtlemimic.launch b/software_training_assignment/launch/turtlemimic.launch
new file mode 100644
index 0000000..6bec1ae
--- /dev/null
+++ b/software_training_assignment/launch/turtlemimic.launch
@@ -0,0 +1,9 @@
+
+
+
+#
+
+#
+
+
+
diff --git a/software_training_assignment/msg/TurtleDistance.msg b/software_training_assignment/msg/TurtleDistance.msg
new file mode 100644
index 0000000..e86f579
--- /dev/null
+++ b/software_training_assignment/msg/TurtleDistance.msg
@@ -0,0 +1,3 @@
+float32 x_dist
+float32 y_dist
+float32 dist
diff --git a/software_training_assignment/package.xml b/software_training_assignment/package.xml
new file mode 100644
index 0000000..df289ff
--- /dev/null
+++ b/software_training_assignment/package.xml
@@ -0,0 +1,72 @@
+
+
+ software_training_assignment
+ 0.0.0
+ The software_training_assignment package
+
+
+
+
+ tieuchanlong
+
+
+
+
+
+ TODO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ catkin
+ roscpp
+ rospy
+ std_msgs
+ actionlib_msgs
+ message_generation
+ roscpp
+ rospy
+ std_msgs
+ roscpp
+ rospy
+ std_msgs
+ actionlib_msgs
+ message_runtime
+
+
+
+
+
+
+
+
diff --git a/software_training_assignment/src/action_server.cpp b/software_training_assignment/src/action_server.cpp
new file mode 100644
index 0000000..f1e5c61
--- /dev/null
+++ b/software_training_assignment/src/action_server.cpp
@@ -0,0 +1,53 @@
+#include "ros/ros.h"
+#include
+#include
+
+class MoveTurtleAction
+{
+ protected:
+ ros::NodeHandle nh_;
+ actionlib::SimpleActionServer as_;
+
+ std::string action_name_;
+
+ software_training_assignment::MoveTurtleFeedback feedback_;
+ software_training_assignment::MoveTurtleResult result_;
+
+ public:
+ MoveTurtleAction(std::string name): as_(nh_, name, boost::bind(&MoveTurtleAction::executeCB, this, _1), false), action_name_(name)
+ {
+ as_.start();
+ }
+
+ ~MoveTurtleAction(void)
+ {
+ }
+
+ void executeCB(const actionlib_tutorials::MoveTurtleGoalConstPtr &goal)
+ {
+ ros::Rate r(1);
+ bool success = true;
+
+ feedback_.distance_to_goal
+
+ // publish info to the console for the user
+ ROS_INFO("%s: Executing, creating turtle movement of order %i with seed %.2f", action_name_.c_str(), goal->order, feedback_.sequence[0], feedback_.distance_to_goal);
+
+ for (int i = 1;i<=goal->order; i++)
+ {
+ // check that preempt has not been requested by the client
+ if (as_.isPreemptRequested() || !ros::ok())
+ {
+ ROS_INFO("%s: Preempted", action_name_.c_str());
+ // set the action state to preempted
+ as_.setPreempted();
+ success = false;
+ break;
+ }
+
+ as_.publishFeedback(feedback_);
+ // this sleep is not necessary, the sequence is computed at 1 Hz for demonstration purposes
+ r.sleep();
+ }
+ }
+}
diff --git a/software_training_assignment/src/turtle_tf_client.cpp b/software_training_assignment/src/turtle_tf_client.cpp
new file mode 100644
index 0000000..d8de26e
--- /dev/null
+++ b/software_training_assignment/src/turtle_tf_client.cpp
@@ -0,0 +1,30 @@
+#include "ros/ros.h"
+#include "turtlesim/Spawn.h"
+#include
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv, "turtle_tf_client");
+ if (argc != 3)
+ {
+ ROS_INFO("spawn turtle at X Y");
+ return 1;
+ }
+
+ ros::NodeHandle n;
+ ros::ServiceClient client = n.serviceClient("spawn");
+ turtlesim::Spawn srv;
+ if (client.call(srv))
+ {
+ ROS_INFO("Spawn a turtle name: %s", srv.response.name.c_str());
+ }
+ else
+ {
+ ROS_ERROR("Failed to call spawn");
+ return 1;
+ }
+
+ return 0;
+}
+
+
diff --git a/software_training_assignment/src/turtle_tf_distance.cpp b/software_training_assignment/src/turtle_tf_distance.cpp
new file mode 100644
index 0000000..1e18913
--- /dev/null
+++ b/software_training_assignment/src/turtle_tf_distance.cpp
@@ -0,0 +1,55 @@
+#include "ros/ros.h"
+#include "geometry_msgs/Twist.h"
+#include "turtlesim/Pose.h"
+#include "software_training_assignment/TurtleDistance.h"
+#include "turtlesim/Spawn.h"
+
+#include
+#include
+
+using software_training_assignment::TurtleDistance;
+
+void poseCallback(const turtlesim::Pose::ConstPtr& pose_message,turtlesim::Pose *pos_data)
+{
+ pos_data->x = pose_message->x;
+ pos_data->y = pose_message->y;
+ //ROS_INFO("Initial pos: %.2f", pose_message->x);
+}
+
+void PubPosition(turtlesim::Pose turtle1, turtlesim::Pose turtle2, ros::Publisher dist_pub)
+{
+ TurtleDistance result;
+ result.x_dist = abs(turtle1.x - turtle2.x);
+ result.y_dist = abs(turtle1.y - turtle2.y);
+ result.dist = sqrt(pow(abs(turtle1.x - turtle2.x),2) + pow(abs(turtle1.y - turtle2.y),2));
+ ROS_INFO("x: %.2f y: %.2f dist: %.2f", result.x_dist, result.y_dist, result.dist);
+ dist_pub.publish(result);
+}
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv, "turtle_tf_distance");
+ ros::NodeHandle n;
+
+ ros::Rate loop_rate(10);
+
+ int count = 0;
+ srand(time(NULL));
+ turtlesim::Pose stationary_msgs;
+ turtlesim::Pose moving_msgs;
+
+ ros::Subscriber stationary_turtle_subscriber = n.subscribe("stationary_turtle/pose", 100, boost::bind(&poseCallback, _1, &stationary_msgs));
+ ros::Subscriber moving_turtle_subscriber = n.subscribe("moving_turtle/pose", 100, boost::bind(&poseCallback, _1, &moving_msgs));
+
+ ros::Publisher dist_publisher = n.advertise("turtle_distance", 10);
+
+ while (ros::ok())
+ {
+ PubPosition(stationary_msgs, moving_msgs, dist_publisher);
+
+ ros::spinOnce();
+ loop_rate.sleep();
+ }
+ ros::spin();
+ return 0;
+}
diff --git a/software_training_assignment/src/turtle_tf_listener.cpp b/software_training_assignment/src/turtle_tf_listener.cpp
new file mode 100644
index 0000000..5ed8ada
--- /dev/null
+++ b/software_training_assignment/src/turtle_tf_listener.cpp
@@ -0,0 +1,39 @@
+#include
+#include
+#include
+#include
+
+int main(int argc, char** argv){
+ ros::init(argc, argv, "my_tf_listener");
+
+ ros::NodeHandle node;
+
+ ros::service::waitForService("spawn");
+ ros::ServiceClient add_turtle = node.serviceClient("spawn");
+ turtlesim::Spawn srv;
+ add_turtle.call(srv);
+
+ ros::Publisher turtle_vel = node.advertise("stationary_turtle/command_velocity", 10);
+
+ tf::TransformListener listener;
+
+ ros::Rate rate(10.0);
+ while (node.ok()){
+ tf::StampedTransform transform;
+ try{
+ listener.lookupTransform("/stationary_turtle", ros::Time(0), transform);
+ }
+ catch (tf::TransformException ex){
+ ROS_ERROR("%s",ex.what());
+ ros::Duration(1.0).sleep();
+ }
+
+ turtlesim::Velocity vel_msg;
+ vel_msg.angular = 4.0 * atan2(transform.getOrigin().y(), transform.getOrigin().x());
+ vel_msg.linear = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) + pow(transform.getOrigin().y(), 2));
+ turtle_vel.publish(vel_msg);
+
+ rate.sleep();
+ }
+ return 0;
+};
diff --git a/software_training_assignment/src/turtle_tf_publisher.cpp b/software_training_assignment/src/turtle_tf_publisher.cpp
new file mode 100644
index 0000000..d88996e
--- /dev/null
+++ b/software_training_assignment/src/turtle_tf_publisher.cpp
@@ -0,0 +1,80 @@
+#include "ros/ros.h"
+#include "geometry_msgs/Twist.h"
+#include "turtlesim/Pose.h"
+#include "sensor_msgs/Joy.h"
+#include "turtlesim/Spawn.h"
+#include
+#include
+
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv, "turtle_tf_server");
+ ros::NodeHandle n;
+
+
+ ros::Publisher velocity_publisher = n.advertise("turtle1/cmd_vel", 1000);
+ ros::Publisher angle_publisher = n.advertise("turtle1/pose", 1000);
+ ros::Rate loop_rate(1);
+
+ int count = 0;
+ srand(time(NULL));
+ turtlesim::Pose vel_msgs;
+ geometry_msgs::Twist ang_msgs;
+
+ double t0 = ros::Time::now().toSec();
+ double angle = atan(20/5) + 3.1415;
+ double dist = sqrt(20*20 + 5*5);
+
+ while(ros::ok())
+ {
+ //vel_msgs.orientation.x = 5;
+ //vel_msgs.orientation.y = 20;
+ //vel_msgs.orientation.z = 2.09;
+
+ ang_msgs.angular.z = 1;
+
+ double t1 = ros::Time::now().toSec();
+ double current_angle = t1 - t0;
+
+ ROS_INFO("Random positon linear: %.2f", vel_msgs.theta);
+
+ if (current_angle >= angle)
+ {
+ ROS_INFO("Turtle reaches angle!!");
+ break;
+ }
+
+ velocity_publisher.publish(ang_msgs);
+ angle_publisher.publish(vel_msgs);
+ ros::spinOnce();
+ loop_rate.sleep();
+ count++;
+ }
+
+ t0 = ros::Time::now().toSec();
+
+ while(ros::ok())
+ {
+ ang_msgs.linear.x = 1;
+ ang_msgs.angular.z = 0;
+
+ double t1 = ros::Time::now().toSec();
+ double current_dist = t1 - t0;
+
+ if (current_dist >= dist)
+ {
+ ROS_INFO("Turtle reaches destination!!");
+ break;
+ }
+
+ velocity_publisher.publish(ang_msgs);
+ angle_publisher.publish(vel_msgs);
+ ros::spinOnce();
+ loop_rate.sleep();
+ count++;
+ }
+
+
+ return 0;
+}
diff --git a/software_training_assignment/src/turtle_tf_reset.cpp b/software_training_assignment/src/turtle_tf_reset.cpp
new file mode 100644
index 0000000..f52f143
--- /dev/null
+++ b/software_training_assignment/src/turtle_tf_reset.cpp
@@ -0,0 +1,31 @@
+#include "ros/ros.h"
+#include "geometry_msgs/Twist.h"
+#include "geometry_msgs/Pose.h"
+#include "sensor_msgs/Joy.h"
+#include "std_srvs/Empty.h"
+#include
+
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv, "turtle_tf_reset");
+ ros::NodeHandle n;
+
+
+ ros::ServiceClient moving_turtle = n.serviceClient("reset");
+ std_srvs::Empty srv;
+
+ if (moving_turtle.call(srv))
+ {
+ ROS_INFO("Moving turtle is reset!");
+ }
+ else ROS_INFO("The moving turtle has not been reset!");
+
+
+ //ROS_INFO("The turtle name and pos is: %f %f %s", srv.request.x, srv.request.y, srv.request.name.c_str());
+
+ ros::spinOnce();
+
+
+ return 0;
+}
diff --git a/software_training_assignment/src/turtle_tf_server.cpp b/software_training_assignment/src/turtle_tf_server.cpp
new file mode 100644
index 0000000..d4a0878
--- /dev/null
+++ b/software_training_assignment/src/turtle_tf_server.cpp
@@ -0,0 +1,43 @@
+#include "ros/ros.h"
+#include "geometry_msgs/Twist.h"
+#include "geometry_msgs/Pose.h"
+#include "sensor_msgs/Joy.h"
+#include "turtlesim/Spawn.h"
+#include
+
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv, "turtle_tf_server");
+ ros::NodeHandle n;
+
+
+ ros::ServiceClient stationary_turtle = n.serviceClient("spawn");
+ turtlesim::Spawn srv;
+ turtlesim::Spawn srv1;
+
+ srv.request.x = 5;
+ srv.request.y = 5;
+ srv.request.theta = 0;
+ srv.request.name = "stationary_turtle";
+
+ srv1.request.x = 25;
+ srv1.request.y = 10;
+ srv1.request.theta = 0;
+ srv1.request.name = "moving_turtle";
+
+ if (stationary_turtle.call(srv))
+ {
+ ROS_INFO("Turtle is spawned!");
+ }
+ else ROS_INFO("The turtle has not been spawned!");
+
+ stationary_turtle.call(srv1);
+
+ //ROS_INFO("The turtle name and pos is: %f %f %s", srv.request.x, srv.request.y, srv.request.name.c_str());
+
+ ros::spinOnce();
+
+
+ return 0;
+}
diff --git a/software_training_assignment/srv/Spawn.srv b/software_training_assignment/srv/Spawn.srv
new file mode 100644
index 0000000..5f473fd
--- /dev/null
+++ b/software_training_assignment/srv/Spawn.srv
@@ -0,0 +1,6 @@
+float32 x
+float32 y
+float32 theta
+string name # Optional. A unique name will be created and returned if this is empty
+---
+string name
\ No newline at end of file