diff --git a/CMakeLists.txt b/CMakeLists.txt
index 072f313281ea11cf204a65841314be0d68b27ad0..b3b288fba595ab0d1f95aef76a0cd4502a9f0b03 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -70,4 +70,20 @@ target_link_libraries(grasp_service ${catkin_LIBRARIES} EnvironmentUtil GraspUti
 
 add_dependencies(grasp_service panda_grasping_generate_messages_cpp)
 
+#############
+## Testing ##
+#############
+
+## Add gtest based cpp test target and link libraries
+
+if(CATKIN_ENABLE_TESTING)
+    find_package(rostest REQUIRED)
+    add_rostest_gtest(tests_grasping test/grasping.test test/test.cpp)
+#    add_executable(tests_grasping test/test.cpp)
+    target_link_libraries(tests_grasping ${catkin_LIBRARIES})
+    add_dependencies(tests_grasping panda_grasping_generate_messages_cpp)
+    add_rostest_gtest(tests_side_grasping test/side_grasping.test test/grasp_from_side_test.cpp)
+    target_link_libraries(tests_side_grasping ${catkin_LIBRARIES} GraspUtil)
+    add_dependencies(tests_side_grasping panda_grasping_generate_messages_cpp)
+endif()
 
diff --git a/include/grasp_util.h b/include/grasp_util.h
index 66bdb7f373f7a92aaa51e3f2490c0ea6aa3eda33..4e778c010060038aae0a2ac6b8825b80237e3ab2 100644
--- a/include/grasp_util.h
+++ b/include/grasp_util.h
@@ -61,8 +61,51 @@ public:
      */
     geometry_msgs::Pose
     getPickFromAbovePose(geometry_msgs::Pose &object_to_pick_pose, geometry_msgs::Vector3 dimensions,
-                         geometry_msgs::Quaternion gripper_orientation,
-                         double reach = FRANKA_GRIPPER_FINGERTIP_SIZE / 2);
+                         geometry_msgs::Quaternion gripper_orientation, double reach = FRANKA_GRIPPER_FINGERTIP_SIZE / 2);
+
+    /**
+     * Generate a pick-pose for grasping an object from its back.
+     * @param object_pose_msg the object pose
+     * @param gripper_orientation_msg the target gripper orientation -> use a yaw of -M_PI_4 for an orientation orthogonal to the object
+     * @param object_orientation the objects orientation -> use (0,0,0,1) for axisymmetric orientation
+     * @param reach specifies how far the gripper reaches around the object (0 means the center of the finger tip is at the object's corner)
+     * @return the pick pose
+     */
+    geometry_msgs::Pose
+    getPickFromBack(geometry_msgs::Pose &object_pose_msg, geometry_msgs::Vector3 dimensions, geometry_msgs::Quaternion gripper_orientation_msg, double reach = FRANKA_GRIPPER_FINGERTIP_SIZE / 2);
+
+    /**
+     *
+     * Generate a pick-pose for grasping an object from its front.
+     * @param object_pose_msg the object pose
+     * @param gripper_orientation_msg the target gripper orientation -> use a yaw of -M_PI_4 for an orientation orthogonal to the object
+     * @param object_orientation the objects orientation -> use (0,0,0,1) for axisymmetric orientation
+     * @param reach specifies how far the gripper reaches around the object (0 means the center of the finger tip is at the object's corner)
+     * @return the pick pose
+     */
+    geometry_msgs::Pose
+    getPickFromFront(geometry_msgs::Pose &object_pose_msg, geometry_msgs::Vector3 dimensions, geometry_msgs::Quaternion gripper_orientation_msg, double reach = FRANKA_GRIPPER_FINGERTIP_SIZE / 2);
+    /**
+     * Generate a pick-pose for grasping an object from left.
+     * @param object_pose_msg the object pose
+     * @param gripper_orientation_msg the target gripper orientation -> use a yaw of -M_PI_4 for an orientation orthogonal to the object
+     * @param object_orientation the objects orientation -> use (0,0,0,1) for axisymmetric orientation
+     * @param reach specifies how far the gripper reaches around the object (0 means the center of the finger tip is at the object's corner)
+     * @return the pick pose
+     */
+    geometry_msgs::Pose
+    getPickFromLeft(geometry_msgs::Pose &object_pose_msg, geometry_msgs::Vector3 dimensions, geometry_msgs::Quaternion gripper_orientation_msg, double reach = FRANKA_GRIPPER_FINGERTIP_SIZE / 2);
+
+    /**
+     * Generate a pick-pose for grasping an object from right.
+     * @param object_pose_msg the object pose
+     * @param gripper_orientation_msg the target gripper orientation -> use a yaw of -M_PI_4 for an orientation orthogonal to the object
+     * @param object_orientation the objects orientation -> use (0,0,0,1) for axisymmetric orientation
+     * @param reach specifies how far the gripper reaches around the object (0 means the center of the finger tip is at the object's corner)
+     * @return the pick pose
+     */
+    geometry_msgs::Pose
+    getPickFromRight(geometry_msgs::Pose &object_pose_msg, geometry_msgs::Vector3 dimensions, geometry_msgs::Quaternion gripper_orientation_msg, double reach = FRANKA_GRIPPER_FINGERTIP_SIZE / 2);
 
     /**
      * Util method to pick an object from above.
@@ -79,17 +122,46 @@ public:
                        std::string object_to_pick_id, bool plan_only = false);
 
     /**
-     * Util method to place an object from above.
+     * Pick an object from the side based on pick-pose.
      * @param move_group an initialized MoveGroupInterface instance
-     * @param place_pose target place pose for the object
-     * @param close_amount total close amount (space between "forks")
-     * @param open_amount total opening amount (space between "forks")
-     * @param supporting_surface_id ID of surface where object is placed on (e.g. the table)
-     * @param object_to_place_id ID of the object to place
+     * @param pick_pose pick pose for the approach
+     * @param object_to_pick geometric description of the object
+     * @param open_amount intial opening amount of the gripper
+     *  @param supporting_surface_id ID of surface where object is placed on (e.g. the table)
+     * @param object_to_pick_id ID of the object to place
+     * @param plan_only
+     * @return true on success
+     */
+    bool pickFromSide(moveit::planning_interface::MoveGroupInterface &move_group, geometry_msgs::Pose &pick_pose,
+                            shape_msgs::SolidPrimitive &object_to_pick, geometry_msgs::Vector3 &approach_direction,
+                            double open_amount, std::string supporting_surface_id, std::string object_to_pick_id, bool plan_only = false);
+
+    /**
+     * Place an object from above.
+     * @param move_group an initialized MoveGroupInterface instance
+     * @param place_pose a pre place pose
+     * @param open_amount intial opening amount of the gripper
+     * @param supporting_surface_id ID of surface where object is place on (e.g. the table)
+     * @param object_to_pick_id ID of the object to place
+     * @param plan_only
+     * @return true on success
      */
     bool placeFromAbove(moveit::planning_interface::MoveGroupInterface &move_group, geometry_msgs::Pose &place_pose,
                         double open_amount, std::string supporting_surface_id, std::string object_to_place_id, bool plan_only = false);
 
+    /**
+     * Place an object from side.
+     * @param move_group an initialized MoveGroupInterface instance
+     * @param place_pose a pre-place pose
+     * @param open_amount intial opening amount of the gripper
+     * @param supporting_surface_id ID of surface where object is place on (e.g. the table)
+     * @param object_to_pick_id ID of the object to place
+     * @param plan_only
+     * @return true on success
+     */
+    bool placeFromSide(moveit::planning_interface::MoveGroupInterface &move_group, geometry_msgs::Pose &place_pose,
+                        double open_amount, std::string supporting_surface_id, std::string object_to_place_id, bool plan_only = false);
+
     /**
      * Homes the gripper (in case it was abused before and is in an inconsistent state)
      * This method is blocking with a maximum runtime of ~30s
@@ -97,6 +169,22 @@ public:
      */
     static bool homeGripper();
 
+private:
+
+    /**
+     *
+     * @param object_to_pick_pose
+     * @param gripper_orientation
+     * @param approach_orientation
+     * @param y_distance_diff
+     * @param x_distance_diff
+     * @param object_orientation
+     * @param reach
+     * @return
+     */
+    geometry_msgs::Pose
+    getPickFromSidePose(geometry_msgs::Pose &object_to_pick_pose, geometry_msgs::Vector3 dimensions, geometry_msgs::Quaternion gripper_orientation,
+                        tf2::Quaternion approach_orientation, float y_distance_diff, float x_distance_diff, double reach = FRANKA_GRIPPER_FINGERTIP_SIZE / 2);
 };
 
 #endif //PANDA_GRASPING_GRASP_UTIL_H
diff --git a/src/grasping/environment_util.cpp b/src/grasping/environment_util.cpp
index 54766834b5e4fb2a625ddabc44a907940babeea2..6d8af3d85f7d18691629029c1c537c3379662ceb 100644
--- a/src/grasping/environment_util.cpp
+++ b/src/grasping/environment_util.cpp
@@ -24,10 +24,11 @@ void EnvironmentUtil::constructPlate(std::vector<moveit_msgs::CollisionObject> &
     plate.primitive_poses[0].position.x = 0;
     plate.primitive_poses[0].position.y = 0;
     plate.primitive_poses[0].position.z = -0.1;
+    plate.primitive_poses[0].orientation.w = 1;
 
     plate.operation = plate.ADD;
 
-    collision_objects.push_back(plate);
+//    collision_objects.push_back(plate);
 }
 
 void EnvironmentUtil::constructSupport(std::vector<moveit_msgs::CollisionObject> &collision_objects, std::string id,
@@ -50,6 +51,7 @@ void EnvironmentUtil::constructSupport(std::vector<moveit_msgs::CollisionObject>
     pick_support.primitive_poses[0].position.x = object_to_pick_pose.position.x;
     pick_support.primitive_poses[0].position.y = object_to_pick_pose.position.y;
     pick_support.primitive_poses[0].position.z = (object_to_pick_pose.position.z - (object_z_dimension / 2) - 0.02);
+    pick_support.primitive_poses[0].orientation.w = 1; // TODO align to object
 
     pick_support.operation = pick_support.ADD;
 
diff --git a/src/grasping/grasp_service.cpp b/src/grasping/grasp_service.cpp
index 7e27a2a4de28d4004599d4bd1a48a57efdc080fe..752d8eb1abcbaffe84196cb15220416aab7c2c1e 100644
--- a/src/grasping/grasp_service.cpp
+++ b/src/grasping/grasp_service.cpp
@@ -40,8 +40,6 @@ bool pickObject(panda_grasping::PickObject::Request &req,
 
     if (!grasping_state::object_picked) {
 
-        grasping_state::object_picked = true;
-
         EnvironmentUtil env_util;
         GraspUtil grasp_util;
 
@@ -79,6 +77,7 @@ bool pickObject(panda_grasping::PickObject::Request &req,
             return false;
         }
 
+        grasping_state::object_picked = true;
         res.success = true;
         return true;
     }
diff --git a/src/grasping/grasp_util.cpp b/src/grasping/grasp_util.cpp
index b89d05d4c7a49a20168f8ec3e5da4becd9aab221..89c857a2c3e1f6660b2be39392e56ca63c9981b1 100644
--- a/src/grasping/grasp_util.cpp
+++ b/src/grasping/grasp_util.cpp
@@ -31,6 +31,101 @@ void GraspUtil::setupClosedGripper(trajectory_msgs::JointTrajectory &posture, do
     posture.points[0].time_from_start = ros::Duration(0.5);
 }
 
+geometry_msgs::Pose
+GraspUtil::getPickFromBack(geometry_msgs::Pose &object_pose_msg, geometry_msgs::Vector3 dimensions, geometry_msgs::Quaternion gripper_orientation_msg, double reach){
+
+    double approach_roll, approach_pitch, approach_yaw;
+    approach_roll =  -M_PI_2;
+    approach_pitch = -M_PI_4;
+    approach_yaw =   -M_PI_4;
+    tf2::Quaternion approach_orientation;
+    approach_orientation.setRPY(approach_roll, approach_pitch, approach_yaw);
+
+    return getPickFromSidePose(object_pose_msg, dimensions, gripper_orientation_msg,
+            approach_orientation, 0, -0.1, reach);
+}
+
+geometry_msgs::Pose
+GraspUtil::getPickFromFront(geometry_msgs::Pose &object_pose_msg, geometry_msgs::Vector3 dimensions, geometry_msgs::Quaternion gripper_orientation_msg, double reach){
+
+    double approach_roll, approach_pitch, approach_yaw;
+    approach_roll =  M_PI_2;
+    approach_pitch = -M_PI_4 - M_PI_2;
+    approach_yaw =   -M_PI_4;
+    tf2::Quaternion approach_orientation;
+    approach_orientation.setRPY(approach_roll, approach_pitch, approach_yaw);
+
+    return getPickFromSidePose(object_pose_msg, dimensions, gripper_orientation_msg,
+                               approach_orientation, 0, 0.1, reach);
+}
+
+geometry_msgs::Pose
+GraspUtil::getPickFromLeft(geometry_msgs::Pose &object_pose_msg, geometry_msgs::Vector3 dimensions, geometry_msgs::Quaternion gripper_orientation_msg, double reach){
+
+    double approach_roll, approach_pitch, approach_yaw;
+    approach_roll =  M_PI_2;
+    approach_pitch = -M_PI_4 - M_PI_2;
+    approach_yaw =   -M_PI_4 - M_PI_2;
+    tf2::Quaternion approach_orientation;
+    approach_orientation.setRPY(approach_roll, approach_pitch, approach_yaw);
+
+    return getPickFromSidePose(object_pose_msg, dimensions, gripper_orientation_msg,
+                               approach_orientation, -0.1, 0, reach);
+}
+
+geometry_msgs::Pose
+GraspUtil::getPickFromRight(geometry_msgs::Pose &object_pose_msg, geometry_msgs::Vector3 dimensions, geometry_msgs::Quaternion gripper_orientation_msg, double reach){
+
+    double approach_roll, approach_pitch, approach_yaw;
+    approach_roll =  -M_PI_2;
+    approach_pitch = -M_PI_4;
+    approach_yaw =   -M_PI_4 - M_PI_2;
+    tf2::Quaternion approach_orientation;
+    approach_orientation.setRPY(approach_roll, approach_pitch, approach_yaw);
+
+    return getPickFromSidePose(object_pose_msg, dimensions, gripper_orientation_msg,
+                               approach_orientation, 0.1, 0, reach);
+}
+
+geometry_msgs::Pose
+GraspUtil::getPickFromSidePose(geometry_msgs::Pose &object_pose_msg, geometry_msgs::Vector3 dimensions, geometry_msgs::Quaternion gripper_orientation_msg,
+                    tf2::Quaternion approach_orientation, float y_distance_diff, float x_distance_diff, double reach){
+
+    // object orientation
+    tf2::Quaternion object_orientation;
+    tf2::fromMsg(object_pose_msg.orientation, object_orientation);
+
+    // gripper orientation
+    tf2::Quaternion gripper_orientation;
+    tf2::fromMsg(gripper_orientation_msg, gripper_orientation);
+    tf2::Quaternion orientation = object_orientation * gripper_orientation * approach_orientation;
+
+    geometry_msgs::Pose target_pose;
+    target_pose.orientation = tf2::toMsg(orientation);
+    target_pose.position.x = object_pose_msg.position.x + x_distance_diff;
+    target_pose.position.y = object_pose_msg.position.y + y_distance_diff;
+
+    if(x_distance_diff > 0){
+        target_pose.position.x = object_pose_msg.position.x + (0.5 * dimensions.x) + FRANKA_GRIPPER_DISTANCE - reach;
+    }
+
+    if(x_distance_diff < 0){
+        target_pose.position.x = object_pose_msg.position.x - (0.5 * dimensions.x) - FRANKA_GRIPPER_DISTANCE + reach;
+    }
+
+    if(y_distance_diff > 0){
+        target_pose.position.y = object_pose_msg.position.y + (0.5 * dimensions.y) + FRANKA_GRIPPER_DISTANCE - reach;
+    }
+
+    if(y_distance_diff < 0){
+        target_pose.position.y = object_pose_msg.position.y - (0.5 * dimensions.y) - FRANKA_GRIPPER_DISTANCE + reach;
+    }
+
+    target_pose.position.z = object_pose_msg.position.z;
+
+    return target_pose;
+}
+
 geometry_msgs::Pose
 GraspUtil::getPickFromAbovePose(geometry_msgs::Pose &object_pose_msg, geometry_msgs::Vector3 dimensions,
                                 geometry_msgs::Quaternion gripper_orientation_msg, double reach) {
@@ -75,6 +170,69 @@ GraspUtil::getPickFromAbovePose(geometry_msgs::Pose &object_pose_msg, geometry_m
     return target_pose;
 }
 
+bool
+GraspUtil::pickFromSide(moveit::planning_interface::MoveGroupInterface &move_group, geometry_msgs::Pose &pick_pose,
+                        shape_msgs::SolidPrimitive &object_to_pick, geometry_msgs::Vector3 &approach_direction,
+                         double open_amount, std::string supporting_surface_id, std::string object_to_pick_id, bool plan_only) {
+
+    std::vector<moveit_msgs::Grasp> grasps;
+    grasps.resize(1);
+    grasps[0].grasp_pose.header.frame_id = "panda_link0";
+    grasps[0].grasp_pose.pose = pick_pose;
+
+    geometry_msgs::Vector3Stamped stamped_approach_dir;
+    stamped_approach_dir.vector = approach_direction;
+
+    // Setup pre-grasp approach
+    grasps[0].pre_grasp_approach.direction.header.frame_id = "panda_link0";
+    grasps[0].pre_grasp_approach.direction = stamped_approach_dir;
+    grasps[0].pre_grasp_approach.min_distance = 0.095;
+    grasps[0].pre_grasp_approach.desired_distance = 0.115;
+
+    // Setup post-grasp retreat
+    grasps[0].post_grasp_retreat.direction.header.frame_id = "panda_link0";
+    grasps[0].post_grasp_retreat.direction.vector.z = 1.0;
+    grasps[0].post_grasp_retreat.min_distance = 0.1;
+    grasps[0].post_grasp_retreat.desired_distance = 0.25;
+
+    setupOpenGripper(grasps[0].pre_grasp_posture, open_amount);
+
+    if(object_to_pick.type == shape_msgs::SolidPrimitive::CYLINDER){
+
+        if(object_to_pick.dimensions[1] >= 0.08){
+            ROS_ERROR("Could not grasp: Cylinder object to big.");
+            return false;
+        }
+
+        setupClosedGripper(grasps[0].grasp_posture, object_to_pick.dimensions[1]);
+    }else{
+        if (object_to_pick.dimensions[0] <= 0.08) {
+            setupClosedGripper(grasps[0].grasp_posture, object_to_pick.dimensions[0]);
+        }
+
+        if (object_to_pick.dimensions[0] > 0.08 && object_to_pick.dimensions[1] <= 0.08) {
+            setupClosedGripper(grasps[0].grasp_posture, object_to_pick.dimensions[1]);
+        }
+
+        if (object_to_pick.dimensions[0] > 0.08 && object_to_pick.dimensions[1] > 0.08) {
+            ROS_ERROR("Could not grasp: Object to big (in any dimension).");
+            return false;
+        }
+    }
+
+    move_group.setSupportSurfaceName(supporting_surface_id);
+
+    moveit_msgs::MoveItErrorCodes miec = move_group.pick(object_to_pick_id, grasps, plan_only);
+
+    if (miec.val == miec.SUCCESS) {
+        return true;
+    }
+
+    ROS_ERROR_STREAM("Error while executing pick task. MoveItErrorCode: " << miec.val);
+
+    return false;
+}
+
 bool
 GraspUtil::pickFromAbove(moveit::planning_interface::MoveGroupInterface &move_group, geometry_msgs::Pose &pick_pose,
                          geometry_msgs::Vector3 dimensions,
@@ -125,6 +283,40 @@ GraspUtil::pickFromAbove(moveit::planning_interface::MoveGroupInterface &move_gr
     ROS_ERROR_STREAM("Error while executing pick task. MoveItErrorCode: " << miec.val);
     return false;
 }
+bool
+GraspUtil::placeFromSide(moveit::planning_interface::MoveGroupInterface &move_group, geometry_msgs::Pose &place_pose,
+                   double open_amount, std::string supporting_surface_id, std::string object_to_place_id, bool plan_only){
+
+    std::vector<moveit_msgs::PlaceLocation> place_location;
+    place_location.resize(1);
+
+    place_location[0].place_pose.header.frame_id = "panda_link0";
+    place_location[0].place_pose.pose.orientation.w = 1;
+    place_location[0].place_pose.pose.position = place_pose.position;
+    place_location[0].place_pose.pose.position.z = place_location[0].place_pose.pose.position.z;
+
+    place_location[0].pre_place_approach.direction.header.frame_id = "panda_link0";
+    place_location[0].pre_place_approach.direction.vector.z = -1.0;
+    place_location[0].pre_place_approach.min_distance = 0.095;
+    place_location[0].pre_place_approach.desired_distance = 0.115;
+
+    place_location[0].post_place_retreat.direction.header.frame_id = "panda_link0";
+    place_location[0].post_place_retreat.direction.vector.z = 1.0;
+    place_location[0].post_place_retreat.min_distance = 0.1;
+    place_location[0].post_place_retreat.desired_distance = 0.25;
+
+    setupOpenGripper(place_location[0].post_place_posture, open_amount);
+    move_group.setSupportSurfaceName(supporting_surface_id);
+
+    moveit_msgs::MoveItErrorCodes miec = move_group.place(object_to_place_id, place_location, plan_only);
+
+    if (miec.val == miec.SUCCESS) {
+        return true;
+    }
+
+    ROS_ERROR_STREAM("Error while executing place task. MoveItErrorCode: " << miec.val);
+    return false;
+}
 
 bool
 GraspUtil::placeFromAbove(moveit::planning_interface::MoveGroupInterface &move_group, geometry_msgs::Pose &place_pose,
diff --git a/test/grasp_from_side_test.cpp b/test/grasp_from_side_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aff90ba38fdc76900ae8de0bf645183daa8b3794
--- /dev/null
+++ b/test/grasp_from_side_test.cpp
@@ -0,0 +1,271 @@
+#include "ros/ros.h"
+
+#include "tf2_geometry_msgs/tf2_geometry_msgs.h"
+#include "tf2/LinearMath/Quaternion.h"
+#include "tf2/LinearMath/Vector3.h"
+
+#include <moveit/planning_scene_interface/planning_scene_interface.h>
+#include <moveit/move_group_interface/move_group_interface.h>
+
+#include <gtest/gtest.h>
+#include <grasp_util.h>
+
+/**
+ * Testing grasping from side.
+ */
+class Grasping : public ::testing::Test {
+
+protected:
+
+    GraspUtil grasp_util;
+
+    geometry_msgs::Pose pick_table_pose;
+    geometry_msgs::Pose place_table_pose;
+    geometry_msgs::Pose obj_pose;
+    geometry_msgs::Pose place_pose;
+
+    tf2::Quaternion gripper_orientation;
+    tf2::Quaternion place_orientation;
+
+    geometry_msgs::Vector3 dimensions;
+
+    void SetUp() override {
+
+        ros::NodeHandle n("panda_grasping");
+
+        gripper_orientation.setRPY(0, 0, -M_PI_4);
+        place_pose.position.z = 0.4 + 0.05; // table height + object height / 2 + buffer
+        place_orientation.setRPY(0, 0, M_PI / 2);
+        dimensions.x = 0.05;
+        dimensions.y = 0.05;
+        dimensions.z = 0.1;
+
+        CleanupScene();
+    }
+
+    static void CleanupScene() {
+        moveit::planning_interface::PlanningSceneInterface planning_scene_interface;
+
+        for (auto p : planning_scene_interface.getObjects()) {
+            p.second.operation = moveit_msgs::CollisionObject::REMOVE;
+            planning_scene_interface.applyCollisionObject(p.second);
+        }
+        ASSERT_EQ(planning_scene_interface.getObjects().size(), 0);
+        ASSERT_EQ(planning_scene_interface.getAttachedObjects().size(), 0);
+    }
+
+    void doTest(geometry_msgs::Pose &pick_pose, geometry_msgs::Pose &pick_table_pose, geometry_msgs::Pose &place_table_pose,
+            geometry_msgs::Pose &obj_pose, geometry_msgs::Pose &place_pose, geometry_msgs::Vector3 &approach_direction){
+
+        moveit::planning_interface::PlanningSceneInterface planning_scene_interface;
+        moveit::planning_interface::MoveGroupInterface group("panda_arm");
+
+        std::vector<moveit_msgs::CollisionObject> collision_objects;
+        collision_objects.resize(3);
+
+        collision_objects[0].id = "table1";
+        collision_objects[0].header.frame_id = "panda_link0";
+
+        collision_objects[0].primitives.resize(1);
+        collision_objects[0].primitives[0].type = collision_objects[0].primitives[0].BOX;
+        collision_objects[0].primitives[0].dimensions.resize(3);
+        collision_objects[0].primitives[0].dimensions[0] = 0.2;
+        collision_objects[0].primitives[0].dimensions[1] = 0.2;
+        collision_objects[0].primitives[0].dimensions[2] = 0.4;
+        collision_objects[0].primitive_poses.resize(1);
+        collision_objects[0].primitive_poses[0] = pick_table_pose;
+        collision_objects[0].operation = collision_objects[0].ADD;
+
+        collision_objects[1].id = "table2";
+        collision_objects[1].header.frame_id = "panda_link0";
+
+        collision_objects[1].primitives.resize(1);
+        collision_objects[1].primitives[0].type = collision_objects[1].primitives[0].BOX;
+        collision_objects[1].primitives[0].dimensions.resize(3);
+        collision_objects[1].primitives[0].dimensions[0] = 0.2;
+        collision_objects[1].primitives[0].dimensions[1] = 0.2;
+        collision_objects[1].primitives[0].dimensions[2] = 0.4;
+        collision_objects[1].primitive_poses.resize(1);
+        collision_objects[1].primitive_poses[0] = place_table_pose;
+        collision_objects[1].operation = collision_objects[1].ADD;
+
+        collision_objects[2].header.frame_id = "panda_link0";
+        collision_objects[2].id = "object";
+
+        collision_objects[2].primitives.resize(1);
+        collision_objects[2].primitives[0].type = collision_objects[1].primitives[0].BOX;
+        collision_objects[2].primitives[0].dimensions.resize(3);
+        collision_objects[2].primitives[0].dimensions[0] = dimensions.x;
+        collision_objects[2].primitives[0].dimensions[1] = dimensions.y;
+        collision_objects[2].primitives[0].dimensions[2] = dimensions.z;
+        collision_objects[2].primitive_poses.resize(1);
+        collision_objects[2].primitive_poses[0] = obj_pose;
+        collision_objects[2].operation = collision_objects[2].ADD;
+
+        planning_scene_interface.applyCollisionObjects(collision_objects);
+
+        pickAndPlace(pick_pose, planning_scene_interface, group, place_pose, approach_direction);
+    }
+
+    void pickAndPlace(geometry_msgs::Pose &pick_pose, moveit::planning_interface::PlanningSceneInterface &planning_scene_interface,
+            moveit::planning_interface::MoveGroupInterface &group, geometry_msgs::Pose &place_pose, geometry_msgs::Vector3 &approach_direction) {
+
+        shape_msgs::SolidPrimitive object;
+        object.type = shape_msgs::SolidPrimitive::CYLINDER;
+        object.dimensions.resize(2);
+        object.dimensions[0] = dimensions.x;
+        object.dimensions[1] = dimensions.y;
+
+        GraspUtil grasp_util;
+
+
+        ros::WallDuration(1.0).sleep();
+
+        ASSERT_TRUE(grasp_util.pickFromSide(group, pick_pose, object, approach_direction,0.06, "table1", "object"));
+
+        ros::WallDuration(1.0).sleep();
+
+        ASSERT_TRUE(grasp_util.placeFromSide(group, place_pose, 0.06, "table2", "object", false));
+    }
+};
+
+/**
+ * test from -x grasp
+*/
+TEST_F(Grasping, SIDE_GRASPING_1) {
+
+    pick_table_pose.position.x = 0.5;
+    pick_table_pose.position.y = -0.5;
+    pick_table_pose.position.z = 0.2;
+    pick_table_pose.orientation.w = 1.0;
+
+    place_table_pose.position.x = 0;
+    place_table_pose.position.y = 0.5;
+    place_table_pose.position.z = 0.2;
+    place_table_pose.orientation.w = 1.0;
+
+    obj_pose.position.x = 0.5;
+    obj_pose.position.y = -0.5;
+    obj_pose.position.z = 0.45;
+    obj_pose.orientation.w = 1.0;
+
+
+    place_pose.orientation = tf2::toMsg(place_orientation);
+    place_pose.position.x = place_table_pose.position.x;
+    place_pose.position.y = place_table_pose.position.y;
+
+    geometry_msgs::Vector3 approach_direction;
+    approach_direction.x = 1;
+
+    geometry_msgs::Pose pick_pose = grasp_util.getPickFromBack(obj_pose, dimensions, tf2::toMsg(gripper_orientation));
+    doTest(pick_pose, pick_table_pose, place_table_pose, obj_pose, place_pose, approach_direction);
+}
+
+/**
+ * test from +x grasp
+*/
+TEST_F(Grasping, SIDE_GRASPING_2) {
+
+    pick_table_pose.position.x = -0.5;
+    pick_table_pose.position.y = -0.5;
+    pick_table_pose.position.z = 0.2;
+    pick_table_pose.orientation.w = 1.0;
+
+    place_table_pose.position.x = 0;
+    place_table_pose.position.y = 0.5;
+    place_table_pose.position.z = 0.2;
+    place_table_pose.orientation.w = 1.0;
+
+    obj_pose.position.x = -0.5;
+    obj_pose.position.y = -0.5;
+    obj_pose.position.z = 0.45;
+    obj_pose.orientation.w = 1.0;
+
+    place_pose.orientation = tf2::toMsg(place_orientation);
+    place_pose.position.x = place_table_pose.position.x;
+    place_pose.position.y = place_table_pose.position.y;
+
+    geometry_msgs::Vector3 approach_direction;
+    approach_direction.x = -1;
+
+    geometry_msgs::Pose pick_pose = grasp_util.getPickFromFront(obj_pose, dimensions, tf2::toMsg(gripper_orientation));
+    doTest(pick_pose, pick_table_pose, place_table_pose, obj_pose, place_pose, approach_direction);
+}
+
+/**
+ * test from -y grasp
+*/
+TEST_F(Grasping, SIDE_GRASPING_3) {
+
+    pick_table_pose.position.x = 0.5;
+    pick_table_pose.position.y = 0.5;
+    pick_table_pose.position.z = 0.2;
+    pick_table_pose.orientation.w = 1.0;
+
+    place_table_pose.position.x = -0.5;
+    place_table_pose.position.y = 0;
+    place_table_pose.position.z = 0.2;
+    place_table_pose.orientation.w = 1.0;
+
+    obj_pose.position.x = 0.5;
+    obj_pose.position.y = 0.5;
+    obj_pose.position.z = 0.45;
+    obj_pose.orientation.w = 1.0;
+
+    place_pose.orientation = tf2::toMsg(place_orientation);
+    place_pose.position.x = place_table_pose.position.x;
+    place_pose.position.y = place_table_pose.position.y;
+
+    geometry_msgs::Vector3 approach_direction;
+    approach_direction.y = +1;
+
+    geometry_msgs::Pose pick_pose = grasp_util.getPickFromLeft(obj_pose, dimensions, tf2::toMsg(gripper_orientation));
+    doTest(pick_pose, pick_table_pose, place_table_pose, obj_pose, place_pose, approach_direction);
+}
+
+/**
+ * test from +y grasp
+ */
+TEST_F(Grasping, SIDE_GRASPING_4) {
+
+    pick_table_pose.position.x = 0.5;
+    pick_table_pose.position.y = -0.5;
+    pick_table_pose.position.z = 0.2;
+    pick_table_pose.orientation.w = 1.0;
+
+    place_table_pose.position.x = -0.5;
+    place_table_pose.position.y = 0;
+    place_table_pose.position.z = 0.2;
+    place_table_pose.orientation.w = 1.0;
+
+    obj_pose.position.x = 0.5;
+    obj_pose.position.y = -0.5;
+    obj_pose.position.z = 0.45;
+    obj_pose.orientation.w = 1.0;
+
+    place_pose.orientation = tf2::toMsg(place_orientation);
+    place_pose.position.x = place_table_pose.position.x;
+    place_pose.position.y = place_table_pose.position.y;
+
+    geometry_msgs::Vector3 approach_direction;
+    approach_direction.y = -1;
+
+    geometry_msgs::Pose pick_pose = grasp_util.getPickFromRight(obj_pose, dimensions, tf2::toMsg(gripper_orientation));
+    doTest(pick_pose, pick_table_pose, place_table_pose, obj_pose, place_pose, approach_direction);
+}
+
+int main(int argc, char **argv) {
+    testing::InitGoogleTest(&argc, argv);
+    ros::init(argc, argv, "tests_side_grasping");
+    ros::NodeHandle n("panda_grasping");
+
+    ros::AsyncSpinner spinner(4);
+    spinner.start();
+
+    ROS_INFO_NAMED("constraint_planner", ">>>>>>>>>>>>>>>> WAITING FOR ROBOT INIT <<<<<<<<<<<<<<<");
+    ros::Duration(3.0).sleep();
+    ROS_INFO_NAMED("constraint_planner", ">>>>>>>>>>>>>>>>> STARTING TEST AFTER INIT <<<<<<<<<<<<<<<<");
+
+
+    return RUN_ALL_TESTS();
+}
diff --git a/test/grasping.test b/test/grasping.test
new file mode 100644
index 0000000000000000000000000000000000000000..5765d69f50606ef7e5bc2165852b9177ca2aced9
--- /dev/null
+++ b/test/grasping.test
@@ -0,0 +1,14 @@
+<launch>
+    <include file="$(find panda_simulation)/launch/simulation.launch">
+        <arg name="slow_simulation" value="false" />
+    </include>
+
+    <node name="$(anon rviz)" pkg="rviz" type="rviz" respawn="false"
+          args="-d $(find panda_grasping)/test/plan_visualizer.rviz" output="screen">
+        <rosparam command="load" file="$(find panda_moveit_config)/config/kinematics.yaml"/>
+    </node>
+
+    <node pkg="panda_grasping" type="grasp_service" name="grasp_service" output="screen" respawn="true"/>
+
+    <test test-name="tests_grasping" pkg="panda_grasping" type="tests_grasping" time-limit="3600.0"/>
+</launch>
\ No newline at end of file
diff --git a/test/plan_visualizer.rviz b/test/plan_visualizer.rviz
new file mode 100644
index 0000000000000000000000000000000000000000..2f631356378c3b3dc72a04abff35b9b9d5f1893f
--- /dev/null
+++ b/test/plan_visualizer.rviz
@@ -0,0 +1,286 @@
+Panels:
+  []
+Preferences:
+  PromptSaveOnExit: true
+Toolbars:
+  toolButtonStyle: 2
+Visualization Manager:
+  Class: ""
+  Displays:
+    - Alpha: 0.5
+      Cell Size: 1
+      Class: rviz/Grid
+      Color: 160; 160; 164
+      Enabled: true
+      Line Style:
+        Line Width: 0.029999999329447746
+        Value: Lines
+      Name: Grid
+      Normal Cell Count: 0
+      Offset:
+        X: 0
+        Y: 0
+        Z: 0
+      Plane: XY
+      Plane Cell Count: 10
+      Reference Frame: <Fixed Frame>
+      Value: true
+    - Acceleration_Scaling_Factor: 1
+      Class: moveit_rviz_plugin/MotionPlanning
+      Enabled: true
+      Move Group Namespace: ""
+      MoveIt_Allow_Approximate_IK: false
+      MoveIt_Allow_External_Program: false
+      MoveIt_Allow_Replanning: false
+      MoveIt_Allow_Sensor_Positioning: false
+      MoveIt_Goal_Tolerance: 0
+      MoveIt_Planning_Attempts: 10
+      MoveIt_Planning_Time: 5
+      MoveIt_Use_Cartesian_Path: false
+      MoveIt_Use_Constraint_Aware_IK: true
+      MoveIt_Warehouse_Host: 127.0.0.1
+      MoveIt_Warehouse_Port: 33829
+      MoveIt_Workspace:
+        Center:
+          X: 0
+          Y: 0
+          Z: 0
+        Size:
+          X: 2
+          Y: 2
+          Z: 2
+      Name: MotionPlanning
+      Planned Path:
+        Color Enabled: false
+        Interrupt Display: false
+        Links:
+          All Links Enabled: true
+          Expand Joint Details: false
+          Expand Link Details: false
+          Expand Tree: false
+          Link Tree Style: Links in Alphabetic Order
+          panda_hand:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_leftfinger:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link0:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link1:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link2:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link3:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link4:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link5:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link6:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link7:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link8:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+          panda_rightfinger:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          world:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+        Loop Animation: true
+        Robot Alpha: 0.5
+        Robot Color: 150; 50; 150
+        Show Robot Collision: false
+        Show Robot Visual: true
+        Show Trail: false
+        State Display Time: 0.05 s
+        Trail Step Size: 1
+        Trajectory Topic: move_group/display_planned_path
+      Planning Metrics:
+        Payload: 1
+        Show Joint Torques: false
+        Show Manipulability: false
+        Show Manipulability Index: false
+        Show Weight Limit: false
+        TextHeight: 0.07999999821186066
+      Planning Request:
+        Colliding Link Color: 255; 0; 0
+        Goal State Alpha: 1
+        Goal State Color: 250; 128; 0
+        Interactive Marker Size: 0
+        Joint Violation Color: 255; 0; 255
+        Planning Group: panda_arm
+        Query Goal State: false
+        Query Start State: false
+        Show Workspace: false
+        Start State Alpha: 1
+        Start State Color: 0; 255; 0
+      Planning Scene Topic: move_group/monitored_planning_scene
+      Robot Description: robot_description
+      Scene Geometry:
+        Scene Alpha: 0.8999999761581421
+        Scene Color: 50; 230; 50
+        Scene Display Time: 0.20000000298023224
+        Show Scene Geometry: true
+        Voxel Coloring: Z-Axis
+        Voxel Rendering: Occupied Voxels
+      Scene Robot:
+        Attached Body Color: 150; 50; 150
+        Links:
+          All Links Enabled: true
+          Expand Joint Details: false
+          Expand Link Details: false
+          Expand Tree: false
+          Link Tree Style: Links in Alphabetic Order
+          panda_hand:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_leftfinger:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link0:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link1:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link2:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link3:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link4:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link5:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link6:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link7:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          panda_link8:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+          panda_rightfinger:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+            Value: true
+          world:
+            Alpha: 1
+            Show Axes: false
+            Show Trail: false
+        Robot Alpha: 0.5
+        Show Robot Collision: false
+        Show Robot Visual: false
+      Value: true
+      Velocity_Scaling_Factor: 1
+  Enabled: true
+  Global Options:
+    Background Color: 48; 48; 48
+    Default Light: true
+    Fixed Frame: panda_link0
+    Frame Rate: 30
+  Name: root
+  Tools:
+    - Class: rviz/Interact
+      Hide Inactive Objects: true
+    - Class: rviz/MoveCamera
+    - Class: rviz/Select
+    - Class: rviz_visual_tools/KeyTool
+  Value: true
+  Views:
+    Current:
+      Class: rviz/XYOrbit
+      Distance: 2.9803097248077393
+      Enable Stereo Rendering:
+        Stereo Eye Separation: 0.05999999865889549
+        Stereo Focal Distance: 1
+        Swap Stereo Eyes: false
+        Value: false
+      Focal Point:
+        X: 1.0864897966384888
+        Y: 0.3387787342071533
+        Z: 2.2351798634190345e-7
+      Focal Shape Fixed Size: true
+      Focal Shape Size: 0.05000000074505806
+      Invert Z Axis: false
+      Name: Current View
+      Near Clip Distance: 0.009999999776482582
+      Pitch: 0.270203560590744
+      Target Frame: panda_link0
+      Value: XYOrbit (rviz)
+      Yaw: 0.42677485942840576
+    Saved: ~
+Window Geometry:
+  Height: 1404
+  Hide Left Dock: false
+  Hide Right Dock: false
+  MotionPlanning:
+    collapsed: false
+  MotionPlanning - Trajectory Slider:
+    collapsed: false
+  QMainWindow State: 000000ff00000000fd00000002000000000000013b000004e1fc0200000003fb0000001c004d006f00740069006f006e0050006c0061006e006e0069006e00670000000080000003640000017200fffffffb0000000800480065006c00700100000334000000e10000000000000000fb0000000a00560069006500770073000000003b000004e1000000000000000000000003000004fe0000003ffc0100000001fb00000044004d006f00740069006f006e0050006c0061006e006e0069006e00670020002d0020005400720061006a006500630074006f0072007900200053006c00690064006500720100000000000004fe0000010000ffffff000004fe000004e100000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
+  Width: 1278
+  X: 0
+  Y: 18
diff --git a/test/side_grasping.test b/test/side_grasping.test
new file mode 100644
index 0000000000000000000000000000000000000000..78444dedfb2f922ab9678e701639f327d69812d9
--- /dev/null
+++ b/test/side_grasping.test
@@ -0,0 +1,6 @@
+<launch>
+    <include file="$(find panda_simulation)/launch/simulation.launch"/>
+    <include file="$(find panda_moveit_config)/launch/moveit_rviz.launch" />
+
+    <test test-name="tests_side_grasping" pkg="panda_grasping" type="tests_side_grasping" time-limit="3600.0"/>
+</launch>
diff --git a/test/test.cpp b/test/test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..185ea255f8b1f22361657f0486eb9be61c84435f
--- /dev/null
+++ b/test/test.cpp
@@ -0,0 +1,182 @@
+//
+// Created by Johannes Mey on 22.11.20.
+//
+
+#include "ros/ros.h"
+
+#include "tf2_geometry_msgs/tf2_geometry_msgs.h"
+#include "tf2/LinearMath/Quaternion.h"
+#include "tf2/LinearMath/Vector3.h"
+
+#include <moveit/planning_scene_interface/planning_scene_interface.h>
+#include <moveit/move_group_interface/move_group_interface.h>
+
+#include "panda_grasping/PickObject.h"
+#include "panda_grasping/PlaceObject.h"
+
+#include <gtest/gtest.h>
+
+class Grasping : public ::testing::Test {
+protected:
+
+    void SetUp() override {
+        ros::NodeHandle n("panda_grasping");
+        pickClient = n.serviceClient<panda_grasping::PickObject>("PickObjectService");
+        placeClient = n.serviceClient<panda_grasping::PlaceObject>("PlaceObjectService");
+
+        // clean up scene
+        CleanupScene();
+    }
+
+
+    static void CleanupScene() {
+        moveit::planning_interface::PlanningSceneInterface planning_scene_interface;
+
+        for (auto p : planning_scene_interface.getObjects()) {
+            p.second.operation = moveit_msgs::CollisionObject::REMOVE;
+            planning_scene_interface.applyCollisionObject(p.second);
+        }
+        ASSERT_EQ(planning_scene_interface.getObjects().size(), 0);
+        ASSERT_EQ(planning_scene_interface.getAttachedObjects().size(), 0);
+    }
+
+    // void TearDown() override {}
+
+    ros::ServiceClient pickClient;
+    ros::ServiceClient placeClient;
+
+    std::vector<tf2::Vector3> objects{
+            tf2::Vector3(0.01, 0.1, 0.1),
+            tf2::Vector3(0.05, 0.1, 0.1),
+            tf2::Vector3(0.005, 0.1, 0.1)
+    };
+
+    std::vector<tf2::Vector3> points{
+            tf2::Vector3(0.5, 0.3, 0.2),
+            tf2::Vector3(-0.5, -0.3, 0.3),
+            tf2::Vector3(0.5, 0.3, 0.1),
+            tf2::Vector3(0.4, 0.5, 0.4),
+
+    };
+
+    tf2::Vector3 nullLocation{-0.4, 0.5, 0};
+
+    std::vector<double> angles{
+            M_PI_2,
+            1,
+            -M_PI_4
+    };
+
+    void pickAndPlace(tf2::Vector3 size, tf2::Vector3 from, double fromAngle, tf2::Vector3 to, double toAngle) {
+        // wait a little while
+        ros::Duration(0.5).sleep();
+        ROS_INFO_STREAM("starting test");
+        tf2::Quaternion orientation;
+        {
+            orientation.setRPY(0, 0, fromAngle);
+
+            panda_grasping::PickObject pickObjectSrv;
+            pickObjectSrv.request.dimensions = tf2::toMsg(size);
+            tf2::toMsg(from, pickObjectSrv.request.pose.position);
+            pickObjectSrv.request.pose.orientation = tf2::toMsg(orientation);
+
+            ROS_INFO_STREAM("starting to pick");
+
+            ASSERT_TRUE(pickClient.exists());
+            ASSERT_TRUE(pickClient.call(pickObjectSrv));
+        }
+        {
+            orientation.setRPY(0, 0, toAngle);
+
+            panda_grasping::PlaceObject placeObjectSrv;
+            placeObjectSrv.request.dimensions = tf2::toMsg(size);
+            tf2::toMsg(to, placeObjectSrv.request.pose.position);
+            placeObjectSrv.request.pose.orientation = tf2::toMsg(orientation);
+
+            ROS_INFO_STREAM("starting to place");
+
+            ASSERT_TRUE(placeClient.exists());
+            ASSERT_TRUE(placeClient.call(placeObjectSrv));
+
+
+            ROS_INFO_STREAM("pick and place finished");
+        }
+    }
+};
+
+
+TEST_F(Grasping, Grasping_WithoutRotation_Object_0_FromTo_01) {
+    auto object = objects[0];
+    pickAndPlace(object, points[0], 0, points[1], 0);
+}
+
+TEST_F(Grasping, Grasping_WithoutRotation_Object_0_FromTo_Null1) {
+    auto object = objects[0];
+    pickAndPlace(object, nullLocation, 0, points[1], 0);
+}
+
+TEST_F(Grasping, Grasping_WithoutRotation_Object_1_FromTo_01) {
+    auto object = objects[1];
+    pickAndPlace(object, points[0], 0, points[1], 0);
+}
+
+TEST_F(Grasping, Grasping_WithoutRotation_Object_2_FromTo_01) {
+    auto object = objects[2];
+    pickAndPlace(object, points[0], 0, points[1], 0);
+}
+
+TEST_F(Grasping, Grasping_WithoutRotation_Object_0_FromTo_1Null) {
+    auto object = objects[0];
+    pickAndPlace(object, points[1], 0, nullLocation, 0);
+}
+
+TEST_F(Grasping, Grasping_WithoutRotation_Object_0_FromTo_01_23) {
+    auto object = objects[0];
+    pickAndPlace(object, points[0], 0, points[1], 0);
+    CleanupScene();
+    pickAndPlace(object, points[2], 0, points[3], 0);
+}
+
+TEST_F(Grasping, Grasping_WithoutRotation_Object_0_FromTo_01_12) {
+    auto object = objects[0];
+    pickAndPlace(object, points[0], 0, points[1], 0);
+    CleanupScene();
+    pickAndPlace(object, points[1], 0, points[2], 0);
+}
+
+TEST_F(Grasping, GraspingWithRotation_Object_0_Rotations_00) {
+    auto object = objects[0];
+    auto fromAngle = angles[0];
+    auto toAngle = angles[0];
+
+    pickAndPlace(object, points[0], fromAngle, points[1], toAngle);
+}
+
+TEST_F(Grasping, GraspingWithRotation_Object_0_Rotations_01) {
+    auto object = objects[0];
+    auto fromAngle = angles[0];
+    auto toAngle = angles[1];
+
+    pickAndPlace(object, points[0], fromAngle, points[1], toAngle);
+}
+
+TEST_F(Grasping, GraspingWithRotation_Object_0_Rotations_12) {
+    auto object = objects[0];
+    auto fromAngle = angles[1];
+    auto toAngle = angles[2];
+
+    pickAndPlace(object, points[0], fromAngle, points[1], toAngle);
+}
+
+int main(int argc, char **argv) {
+    testing::InitGoogleTest(&argc, argv);
+    ros::init(argc, argv, "grasping_test");
+    ros::NodeHandle n("panda_grasping");
+
+    ROS_INFO_NAMED("constraint_planner", ">>>>>>>>>>>>>>>> WAITING FOR ROBOT INIT <<<<<<<<<<<<<<<");
+    ros::Duration(3.0).sleep();
+    ROS_INFO_NAMED("constraint_planner", ">>>>>>>>>>>>>>>>> STARTING TEST AFTER INIT <<<<<<<<<<<<<<<<");
+
+
+    return RUN_ALL_TESTS();
+}