Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Empty file added .gitignore
Empty file.
69 changes: 69 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# toplevel CMakeLists.txt for a catkin workspace
# catkin/cmake/toplevel.cmake

cmake_minimum_required(VERSION 3.0.2)

project(Project)

set(CATKIN_TOPLEVEL TRUE)

# search for catkin within the workspace
set(_cmd "catkin_find_pkg" "catkin" "${CMAKE_SOURCE_DIR}")
execute_process(COMMAND ${_cmd}
RESULT_VARIABLE _res
OUTPUT_VARIABLE _out
ERROR_VARIABLE _err
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE
)
if(NOT _res EQUAL 0 AND NOT _res EQUAL 2)
# searching fot catkin resulted in an error
string(REPLACE ";" " " _cmd_str "${_cmd}")
message(FATAL_ERROR "Search for 'catkin' in workspace failed (${_cmd_str}): ${_err}")
endif()

# include catkin from workspace or via find_package()
if(_res EQUAL 0)
set(catkin_EXTRAS_DIR "${CMAKE_SOURCE_DIR}/${_out}/cmake")
# include all.cmake without add_subdirectory to let it operate in same scope
include(${catkin_EXTRAS_DIR}/all.cmake NO_POLICY_SCOPE)
add_subdirectory("${_out}")

else()
# use either CMAKE_PREFIX_PATH explicitly passed to CMake as a command line argument
# or CMAKE_PREFIX_PATH from the environment
if(NOT DEFINED CMAKE_PREFIX_PATH)
if(NOT "$ENV{CMAKE_PREFIX_PATH}" STREQUAL "")
if(NOT WIN32)
string(REPLACE ":" ";" CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH})
else()
set(CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH})
endif()
endif()
endif()

# list of catkin workspaces
set(catkin_search_path "")
foreach(path ${CMAKE_PREFIX_PATH})
if(EXISTS "${path}/.catkin")
list(FIND catkin_search_path ${path} _index)
if(_index EQUAL -1)
list(APPEND catkin_search_path ${path})
endif()
endif()
endforeach()

# search for catkin in all workspaces
set(CATKIN_TOPLEVEL_FIND_PACKAGE TRUE)
find_package(catkin QUIET
NO_POLICY_SCOPE
PATHS ${catkin_search_path}
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
unset(CATKIN_TOPLEVEL_FIND_PACKAGE)

if(NOT catkin_FOUND)
message(FATAL_ERROR "find_package(catkin) failed. catkin was neither found in the workspace nor in the CMAKE_PREFIX_PATH. One reason may be that no ROS setup.sh was sourced before.")
endif()
endif()

catkin_workspace()
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
# software_challenge
# software_challenge

## Usage:
1. Add package to your workspace, `cd` into your workspace, run `source ./devel/setup.bash`, `catkin_make`
2. Start the turtlesim and my_turtle nodes by running:
```
roslaunch software_training_assignment launcher.launch
```
3. To use the reset "moving_turtle" service run:
```
rosservice call /reset_moving_turtle
```
4. To get information about the distances between the "stationary_turtle" and "moving_turtle" run:
```
rostopic echo /turtle_distance
```
5. To use the "moving_turtle" action run:
```
rosrun software_training_assignment MoveTurtleActionTester _x:=2 _y:=5
```

Replace the x and y parameters to whatever you would like to move the "moving_turtle".
83 changes: 83 additions & 0 deletions software_training_assignment/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
cmake_minimum_required(VERSION 3.0.2)
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
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
turtlesim
std_msgs
message_generation
actionlib
actionlib_msgs
)

################################################
## Declare ROS messages, services and actions ##
################################################

## Generate messages in the 'msg' folder
add_message_files(
FILES
Distance.msg
)

## Generate services in the 'srv' folder
add_service_files(
FILES
ResetMovingTurtle.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
std_msgs
actionlib_msgs
)

###################################
## catkin specific configuration ##
###################################

catkin_package(
# INCLUDE_DIRS include
# LIBRARIES software_training_assignment
CATKIN_DEPENDS message_runtime actionlib_msgs
# DEPENDS system_lib
)

###########
## Build ##
###########

## Specify additional locations of header files
include_directories(
include
/src
${catkin_INCLUDE_DIRS}
)

set(SOURCE_FILES
src/main.cpp
src/Turtle.cpp
src/StationaryTurtle.cpp
src/MovingTurtle.cpp
src/DistancePublisher.cpp
)

add_executable(my_turtle ${SOURCE_FILES})
target_link_libraries(my_turtle ${catkin_LIBRARIES})
add_dependencies(my_turtle software_training_assignment_generate_messages_cpp)

add_executable(MoveTurtleActionTester src/MoveTurtleActionTester.cpp)
target_link_libraries(MoveTurtleActionTester ${catkin_LIBRARIES})
add_dependencies(MoveTurtleActionTester software_training_assignment_generate_messages_cpp)
9 changes: 9 additions & 0 deletions software_training_assignment/action/MoveTurtle.action
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# goal definition
float32 x
float32 y
---
# result definition
duration time
---
# feedback
float32 distance
11 changes: 11 additions & 0 deletions software_training_assignment/launch/launcher.launch
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<launch>

<node name="turtlesim" pkg="turtlesim" type="turtlesim_node">
<rosparam param="background_r">128</rosparam>
<rosparam param="background_g">128</rosparam>
<rosparam param="background_b">0</rosparam>
</node>

<node name="my_turtle" pkg="software_training_assignment" type="my_turtle" output="screen" />

</launch>
4 changes: 4 additions & 0 deletions software_training_assignment/msg/Distance.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
float32 x
float32 y

float32 distance
22 changes: 22 additions & 0 deletions software_training_assignment/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0"?>
<package format="2">

<name>software_training_assignment</name>
<version>0.0.0</version>
<description>The software_training_assignment package</description>

<maintainer email="[email protected]">Sam Sandhu</maintainer>

<license>TODO</license>

<!-- Dependencies -->
<buildtool_depend>catkin</buildtool_depend>
<depend>roscpp</depend>
<depend>rospy</depend>
<depend>std_msgs</depend>
<depend>message_generation</depend>
<depend>actionlib</depend>
<depend>actionlib_msgs</depend>
<exec_depend>message_runtime</exec_depend>

</package>
28 changes: 28 additions & 0 deletions software_training_assignment/src/DistancePublisher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "DistancePublisher.h"

#include "software_training_assignment/Distance.h"

#include <cmath>

// ctor
DistancePublisher::DistancePublisher(ros::NodeHandle &n, Turtle* t1, Turtle* t2) : n_{n}, t1_{t1}, t2_{t2} {
// init ros distance publisher
dist_pub_ = n_.advertise<software_training_assignment::Distance>("turtle_distance", 1000);
}

void DistancePublisher::publish() {
turtlesim::Pose t1_Position = t1_->getPosition();
turtlesim::Pose t2_Position = t2_->getPosition();

// set message
software_training_assignment::Distance msg;
msg.x = t1_Position.x - t2_Position.x;
msg.y = t1_Position.y - t2_Position.y;
msg.distance = sqrt(pow(msg.x, 2) + pow(msg.y, 2));

ROS_INFO_STREAM(std::setprecision(2) << std::fixed << " distance: " << msg.x << " " << msg.y << " " << msg.distance);

// publish
dist_pub_.publish(msg);
ros::spinOnce();
}
25 changes: 25 additions & 0 deletions software_training_assignment/src/DistancePublisher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef DISTANCE_PUBLISHER_H
#define DISTANCE_PUBLISHER_H

#include "Turtle.h"

class DistancePublisher {
public:
// ctor
DistancePublisher(ros::NodeHandle &n, Turtle* t1, Turtle* t2);

// publishes distance
void publish();

private:
ros::NodeHandle n_;

// ros publisher
ros::Publisher dist_pub_;

// 2 Turtle's to compare
Turtle* t1_;
Turtle* t2_;
};

#endif
41 changes: 41 additions & 0 deletions software_training_assignment/src/MoveTurtleActionTester.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include "ros/ros.h"

#include <actionlib/client/simple_action_client.h>
#include <actionlib/client/terminal_state.h>

#include "software_training_assignment/MoveTurtleAction.h"

int main(int argc, char **argv) {

ros::init(argc, argv, "move_turtle_action_tester");

ros::NodeHandle n;

float x, y;
n.getParam("/move_turtle_action_tester/x", x);
n.getParam("/move_turtle_action_tester/y", y);

actionlib::SimpleActionClient<software_training_assignment::MoveTurtleAction> actionClient("move_turtle_action_server", true);

ROS_INFO("Waiting for action server to start.");
actionClient.waitForServer(); // will wait for infinite time

// send a goal to the action
ROS_INFO("Action server started, sending goal.");
software_training_assignment::MoveTurtleGoal goal;
goal.x = x;
goal.y = y;
actionClient.sendGoal(goal);

// wait for the action to return
bool finished_before_timeout = actionClient.waitForResult(ros::Duration(30.0));

if (finished_before_timeout) {
actionlib::SimpleClientGoalState state = actionClient.getState();
ROS_INFO("Action finished: %s", state.toString().c_str());
} else {
ROS_INFO("Action did not finish before the time out.");
}

return 0;
}
Loading