diff --git a/CoLo-AT/localization_algos/__pycache__/ekf_gs_ci.cpython-36.pyc b/CoLo-AT/localization_algos/__pycache__/ekf_gs_ci.cpython-36.pyc index 69150a44fca989b0b0e3843b3ddad2a91f1f44f4..9cd47b95990e6f1502abf27e71ccb08da1441c47 100644 Binary files a/CoLo-AT/localization_algos/__pycache__/ekf_gs_ci.cpython-36.pyc and b/CoLo-AT/localization_algos/__pycache__/ekf_gs_ci.cpython-36.pyc differ diff --git a/CoLo-AT/localization_algos/under_developing_algos/ekf_gs_ci2.py b/CoLo-AT/localization_algos/ekf_gs_ci2.py similarity index 100% rename from CoLo-AT/localization_algos/under_developing_algos/ekf_gs_ci2.py rename to CoLo-AT/localization_algos/ekf_gs_ci2.py diff --git a/CoLo-AT/localization_algos/ekf_gs_ci.py b/CoLo-AT/localization_algos/under_developing_algos/ekf_gs_ci.py similarity index 99% rename from CoLo-AT/localization_algos/ekf_gs_ci.py rename to CoLo-AT/localization_algos/under_developing_algos/ekf_gs_ci.py index 9933159ce6137d758867cd75bdd29519b9234ff9..d726d6b1885a780efe2f692dc6e556d8b8228a82 100644 --- a/CoLo-AT/localization_algos/ekf_gs_ci.py +++ b/CoLo-AT/localization_algos/under_developing_algos/ekf_gs_ci.py @@ -85,7 +85,7 @@ class EKF_GS_CI(ekf_algo_framework): return [s, orinetations, sigma_s] - ''' + def relative_obser_update(self, robot_data, sensor_data): #when robot i observes robot j @@ -127,8 +127,7 @@ class EKF_GS_CI(ekf_algo_framework): sigma_s = sigma_s - kalman_gain*H*sigma_s return [s, orinetations, sigma_s] - ''' - ''' + def communication(self, robot_data, sensor_data): [s, orinetations, sigma_s, index] = robot_data @@ -145,4 +144,3 @@ class EKF_GS_CI(ekf_algo_framework): sigma_s = sig_inv.getI() return [s, orinetations, sigma_s] - ''' \ No newline at end of file diff --git a/CoLo-AT/robots/__pycache__/robot_system.cpython-36.pyc b/CoLo-AT/robots/__pycache__/robot_system.cpython-36.pyc index f804a9e8365eebc5c47729bdfb6824eaa49232ac..7aadf383202797e3ccda9258a470de1557b1c484 100644 Binary files a/CoLo-AT/robots/__pycache__/robot_system.cpython-36.pyc and b/CoLo-AT/robots/__pycache__/robot_system.cpython-36.pyc differ diff --git a/CoLo-AT/robots/robot_system.py b/CoLo-AT/robots/robot_system.py index d1c9daf6b4dba9726b07a2ce830730088dcd7c8e..14d20e3f029026353b72040a69145796622dcc26 100644 --- a/CoLo-AT/robots/robot_system.py +++ b/CoLo-AT/robots/robot_system.py @@ -75,17 +75,17 @@ class RobotSystem: if rsp_type == 'odometry': #propogation update update_type = 'propagation' v = message_data['velocity'] + a_v = message_data ['angular velocity'] #sigma_odo = np.matrix([[5.075*v, 0], [0, 0.1]]) #with respect to velocity and orientation for utias datasets sigma_odo = np.matrix([[0.01, 0], [0, 0.5]]) #with respect to velocity and orientation sensor_covariance = sigma_odo - #delta_t = message_data['time'] - self.prev_prop_times[robot_index] delta_t = message_data['delta_t'] - ''' - if delta_t <= 0: + + if delta_t <0: print('current time: ', message_data['time'] ) print('prev_prop_time: ', self.prev_prop_times[robot_index]) raise Exception("Error incorrect delta_t!") - ''' + sensor_input = [delta_t, v, message_data['orientation']] self.prev_prop_times[robot_index] = message_data['time'] diff --git a/CoLo-AT/test_simulation.py b/CoLo-AT/test_simulation.py index a990e7d84b25084961e612d7ebc9c0fb8ac2a97a..97c4c37388a5056df0276c6eea66605f3e943709 100644 --- a/CoLo-AT/test_simulation.py +++ b/CoLo-AT/test_simulation.py @@ -24,7 +24,7 @@ from simple_ekf import Simple_EKF from ekf_ls_bda import EKF_LS_BDA from ekf_ls_ci import EKF_LS_CI from ekf_gs_bound import EKF_GS_BOUND -from ekf_gs_ci import EKF_GS_CI +from ekf_gs_ci2 import EKF_GS_CI2 dataset_path = '/home/william/UTIAS-dataset/MRCLAM_Dataset3/' @@ -37,10 +37,10 @@ start_time, starting_states, dataset_data, time_arr = testing_dataset.load_MRCLA freqs0 = [[10, 10, 10],[1, 1, 1],[0.5, 0.5, 0.5]] freqs1 = [[10, 10, 10],[4, 4, 4],[0.5, 0.5, 0.5]] -loc_algo = Centralized_EKF('algo') +loc_algo = EKF_GS_CI2('algo') robot = RobotSystem('robot', dataset_labels, loc_algo, distr_sys = False) -sim = SimulationManager('sim Centralized_EKF') +sim = SimulationManager('sim EKF_GS_CI2') state_recorder = StatesRecorder('recorder',dataset_labels) sim.sim_process_schedule(dataset_labels, testing_dataset, robot, state_recorder, freqs0, simple_plot = True) #sim.sim_process_naive(dataset_labels, testing_dataset, robot, state_recorder, simple_plot = True) diff --git a/CoLo-PE/Other ROS packages/create_autonomy-indigo-devel.zip b/CoLo-PE/Other ROS packages/create_autonomy-indigo-devel.zip new file mode 100644 index 0000000000000000000000000000000000000000..f6b3cb351a421da8814cae7ff000c1a560c969f7 Binary files /dev/null and b/CoLo-PE/Other ROS packages/create_autonomy-indigo-devel.zip differ diff --git a/CoLo-PE/Other ROS packages/fiducials-kinetic-devel.zip b/CoLo-PE/Other ROS packages/fiducials-kinetic-devel.zip new file mode 100644 index 0000000000000000000000000000000000000000..7cc27167cd342d70a6e3040e530195f1386c1899 Binary files /dev/null and b/CoLo-PE/Other ROS packages/fiducials-kinetic-devel.zip differ diff --git a/CoLo-PE/README.md b/CoLo-PE/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/CoLo-PE/aruco_marker_finder.launch b/CoLo-PE/aruco_marker_finder.launch new file mode 100644 index 0000000000000000000000000000000000000000..04a7173a2b720b1755b3bf69880cd45f100aecb8 --- /dev/null +++ b/CoLo-PE/aruco_marker_finder.launch @@ -0,0 +1,23 @@ +<launch> + +<arg name="markerId" default="701"/> +<arg name="markerSize" default="0.05"/> <!-- in meter --> +<arg name="eye" default="left"/> +<arg name="marker_frame" default="marker_frame"/> +<arg name="ref_frame" default=""/> <!-- leave empty and the pose will be published wrt param parent_name --> +<arg name="corner_refinement" default="LINES" /> <!-- NONE, HARRIS, LINES, SUBPIX --> + + +<node pkg="aruco_ros" type="single" name="aruco_single"> +<remap from="/camera_info" to="/usb_cam/camera_info" /> +<remap from="/image" to="/usb_cam/image_raw" /> +<param name="image_is_rectified" value="True"/> +<param name="marker_size" value="$(arg markerSize)"/> +<param name="marker_id" value="$(arg markerId)"/> +<param name="reference_frame" value="$(arg ref_frame)"/> <!-- frame in which the marker pose will be refered --> +<param name="camera_frame" value="base_link"/> +<param name="marker_frame" value="$(arg marker_frame)" /> +<param name="corner_refinement" value="$(arg corner_refinement)" /> +</node> + +</launch> diff --git a/CoLo-PE/aruco_markers_detect.launch b/CoLo-PE/aruco_markers_detect.launch new file mode 100644 index 0000000000000000000000000000000000000000..2389eeb98f9991951aebceb9854e284bdd6723af --- /dev/null +++ b/CoLo-PE/aruco_markers_detect.launch @@ -0,0 +1,21 @@ +<!-- Run the aruco_detect node --> +<launch> + <!-- namespace for camera input --> + <arg name="camera" default="/usb_cam"/> + <arg name="image" default="image"/> + <arg name="transport" default="raw"/> + <arg name="fiducial_len" default="0.14"/> + <arg name="dictionary" default="7"/> + <arg name="do_pose_estimation" default="true"/> + + <node pkg="aruco_detect" name="aruco_detect" + type="aruco_detect" output="screen" respawn="false"> + <param name="image_transport" value="$(arg transport)"/> + <param name="publish_images" value="true" /> + <param name="fiducial_len" value="$(arg fiducial_len)"/> + <param name="dictionary" value="$(arg dictionary)"/> + <param name="do_pose_estimation" value="$(arg do_pose_estimation)"/> + <remap from="/camera" to="/usb_cam/image_raw" /> + <remap from="/camera_info" to="$(arg camera)/camera_info"/> + </node> +</launch> diff --git a/CoLo-PE/aruco_record/CMakeLists.txt b/CoLo-PE/aruco_record/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..7b488f425cee4f04818fdbc85b039a9a8a9814ba --- /dev/null +++ b/CoLo-PE/aruco_record/CMakeLists.txt @@ -0,0 +1,204 @@ +cmake_minimum_required(VERSION 2.8.3) +project(aruco_record) + +## 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 + fiducial_msgs + roscpp + rospy +) + +## 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 +# fiducial_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 aruco_record +# CATKIN_DEPENDS fiducial_msgs roscpp rospy +# 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}/aruco_record.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/aruco_record_node.cpp) + +add_executable(meas_record src/measurement_record.cpp) +target_link_libraries(meas_record ${catkin_LIBRARIES}) +add_dependencies(meas_record aruco_record_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 and/or libraries for installation +# install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_PACKAGE_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_aruco_record.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/CoLo-PE/aruco_record/package.xml b/CoLo-PE/aruco_record/package.xml new file mode 100644 index 0000000000000000000000000000000000000000..04db1a85f2a9f0b8736cb21ea89b1038c511bba1 --- /dev/null +++ b/CoLo-PE/aruco_record/package.xml @@ -0,0 +1,61 @@ +<?xml version="1.0"?> +<package format="2"> + <name>aruco_record</name> + <version>0.0.0</version> + <description>The aruco_record package</description> + + <maintainer email="billyskc@g.ucla.edu">Shengkang 'William' Chen</maintainer> + + <license>BSD</license> + + + <!-- Url tags are optional, but multiple are allowed, one per tag --> + <!-- Optional attribute type can be: website, bugtracker, or repository --> + <!-- Example: --> + <!-- <url type="website">http://wiki.ros.org/aruco_record</url> --> + + + <!-- Author tags are optional, multiple are allowed, one per tag --> + <!-- Authors do not have to be maintainers, but could be --> + <!-- Example: --> + <!-- <author email="jane.doe@example.com">Jane Doe</author> --> + <author email="billyskc@g.ucla.edu">Shengkang 'William' Chen</author> + + <!-- The *depend tags are used to specify dependencies --> + <!-- Dependencies can be catkin packages or system dependencies --> + <!-- Examples: --> + <!-- Use depend as a shortcut for packages that are both build and exec dependencies --> + <!-- <depend>roscpp</depend> --> + <!-- Note that this is equivalent to the following: --> + <!-- <build_depend>roscpp</build_depend> --> + <!-- <exec_depend>roscpp</exec_depend> --> + <!-- Use build_depend for packages you need at compile time: --> + <!-- <build_depend>message_generation</build_depend> --> + <!-- Use build_export_depend for packages you need in order to build against this package: --> + <!-- <build_export_depend>message_generation</build_export_depend> --> + <!-- Use buildtool_depend for build tool packages: --> + <!-- <buildtool_depend>catkin</buildtool_depend> --> + <!-- Use exec_depend for packages you need at runtime: --> + <!-- <exec_depend>message_runtime</exec_depend> --> + <!-- Use test_depend for packages you need only for testing: --> + <!-- <test_depend>gtest</test_depend> --> + <!-- Use doc_depend for packages you need only for building documentation: --> + <!-- <doc_depend>doxygen</doc_depend> --> + <buildtool_depend>catkin</buildtool_depend> + <build_depend>fiducial_msgs</build_depend> + <build_depend>roscpp</build_depend> + <build_depend>rospy</build_depend> + <build_export_depend>fiducial_msgs</build_export_depend> + <build_export_depend>roscpp</build_export_depend> + <build_export_depend>rospy</build_export_depend> + <exec_depend>fiducial_msgs</exec_depend> + <exec_depend>roscpp</exec_depend> + <exec_depend>rospy</exec_depend> + + + <!-- The export tag contains other, unspecified, tags --> + <export> + <!-- Other tools can request additional information be placed here --> + + </export> +</package> diff --git a/CoLo-PE/aruco_record/src/measurement_record.cpp b/CoLo-PE/aruco_record/src/measurement_record.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fec37de8ad38de3762e92484f2c95e1bf99257d8 --- /dev/null +++ b/CoLo-PE/aruco_record/src/measurement_record.cpp @@ -0,0 +1,80 @@ +#include "ros/ros.h" +#include "std_msgs/String.h" +#include <math.h> +#include "fiducial_msgs/FiducialTransform.h" +#include "fiducial_msgs/FiducialTransformArray.h" +#include <iomanip> + +#include <iostream> +#include <fstream> + +using namespace std; +#define PI 3.14159265 + +class ArucoRecorder{ + private: + ros::Subscriber * pose_sub; + void record_data(const fiducial_msgs::FiducialTransformArray::ConstPtr& msg); + public: + ArucoRecorder(ros::NodeHandle &nh); + ~ArucoRecorder() + { + cout << "Destructor called" <<endl; + } +}; + + +void ArucoRecorder::record_data(const fiducial_msgs::FiducialTransformArray::ConstPtr& msg) +{ + ofstream meas_file; + ofstream odo_file, gt_file; + meas_file.open("/home/lemur-robot2/catkin_ws/ros_colo_dataset/Robot2_Measurement_x.dat", ofstream::app); + for (int i=0; i<msg->transforms.size(); i++) { + const fiducial_msgs::FiducialTransform &ft = msg->transforms[i]; + + int id = ft.fiducial_id; + float x_pos = ft.transform.translation.x; + float y_pos = ft.transform.translation.y; + float z_pos = ft.transform.translation.z; + + float range = sqrt(pow(x_pos, 2) + pow(z_pos, 2)); + float bearing = atan2(z_pos, x_pos)-PI/2; + + ROS_INFO("##Object ID: [%d]##", id); + ROS_INFO("Range: [%f]", range); + ROS_INFO("Bearing: [%f]", bearing); + ROS_INFO("***************"); + + meas_file << fixed << setprecision(4) << ros::Time::now() << "\t" << id << "\t\t" << range << "\t\t" << bearing << "\n"; + + } + meas_file.close(); + odo_file.close(); + gt_file.close(); +} + + +ArucoRecorder::ArucoRecorder(ros::NodeHandle & nh){ + ROS_INFO("Aruco Record Started"); + ofstream meas_file; + ofstream odo_file, gt_file; + meas_file.open("/home/lemur-robot2/catkin_ws/ros_colo_dataset/Robot2_Measurement_x.dat"); + meas_file << "# time [sec]" << "\t\t" << "object id" << "\t" << "range [m]" << "\t" << "bearing [rad]" << "\n"; + meas_file.close(); + + pose_sub = new ros::Subscriber(nh.subscribe<fiducial_msgs::FiducialTransformArray>("/fiducial_transforms_throttle", 1, &ArucoRecorder::record_data, this)); +} + + +int main(int argc, char **argv) +{ + ros::init(argc, argv, "meas_record"); + ros::NodeHandle nh("~"); + + ArucoRecorder * node = new ArucoRecorder(nh); + + ros::spin(); + + return 0; +} + diff --git a/CoLo-PE/aruco_sensing.sh b/CoLo-PE/aruco_sensing.sh new file mode 100644 index 0000000000000000000000000000000000000000..cef3536396af29706ff8e5104bf992cc8b56b463 --- /dev/null +++ b/CoLo-PE/aruco_sensing.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +cd $HOME/catkin_ws +xterm -hold -e "roscore" & +xterm -hold -e "roslaunch usb_cam_stream_publisher.launch" & +sleep 5 +xterm -hold -e "roslaunch aruco_markers_detect.launch" & +sleep 3 +xterm -hold -e "rosrun image_view image_view image:=/fiducial_images" & +xterm -hold -e "rostopic echo /fiducial_transforms" & +sleep 2 +xterm -hold -e "rosrun topic_tools throttle messages /fiducial_transforms 5.0" & +xterm -hold -e "rostopic hz fiducial_transforms_throttle" + +cd $HOME/ + +exit 0 + +<<COMMENT + For the throttle frequencies: + Issues: throttle rates lower than expected(default rate = 30Hz) + Expected rate [Hz]: Real rate [Hz]: + 40 ~30 + 30 19.5~20 + 20 ~15 + 15 ~10.5 + 10 ~8.4 + 8 ~7.5 + 4 ~3.75 + 1 0.98 + +COMMENT diff --git a/CoLo-PE/cal_1080p.yml b/CoLo-PE/cal_1080p.yml new file mode 100644 index 0000000000000000000000000000000000000000..b53f2f7d6e1a89aff8e303d161a36273a679e370 --- /dev/null +++ b/CoLo-PE/cal_1080p.yml @@ -0,0 +1,20 @@ +image_width: 1920 +image_height: 1080 +camera_name: narrow_stereo +camera_matrix: + rows: 3 + cols: 3 + data: [1465.728433, 0.000000, 960.661035, 0.000000, 1476.926252, 525.618322, 0.000000, 0.000000, 1.000000] +distortion_model: plumb_bob +distortion_coefficients: + rows: 1 + cols: 5 + data: [0.037891, -0.079731, -0.006196, -0.000102, 0.000000] +rectification_matrix: + rows: 3 + cols: 3 + data: [1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000] +projection_matrix: + rows: 3 + cols: 4 + data: [1469.868652, 0.000000, 960.479293, 0.000000, 0.000000, 1484.509399, 520.966236, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000] diff --git a/CoLo-PE/cal_480p.yml b/CoLo-PE/cal_480p.yml new file mode 100644 index 0000000000000000000000000000000000000000..3f496ad8e28df9c50551a61cd4ec75ffca7beae4 --- /dev/null +++ b/CoLo-PE/cal_480p.yml @@ -0,0 +1,20 @@ +image_width: 640 +image_height: 480 +camera_name: narrow_stereo +camera_matrix: + rows: 3 + cols: 3 + data: [654.029002, 0, 318.310629, 0, 651.6204770000001, 210.721894, 0, 0, 1] +distortion_model: plumb_bob +distortion_coefficients: + rows: 1 + cols: 5 + data: [-0.006783, -0.178923, 0.000926, 0.007013999999999999, 0] +rectification_matrix: + rows: 3 + cols: 3 + data: [1, 0, 0, 0, 1, 0, 0, 0, 1] +projection_matrix: + rows: 3 + cols: 4 + data: [645.730774, 0, 321.784936, 0, 0, 649.168945, 210.480637, 0, 0, 0, 1, 0] diff --git a/CoLo-PE/cal_720p.yml b/CoLo-PE/cal_720p.yml new file mode 100644 index 0000000000000000000000000000000000000000..4f6b000196e50507f600f411f3d5640ef8f7e533 --- /dev/null +++ b/CoLo-PE/cal_720p.yml @@ -0,0 +1,20 @@ +image_width: 1280 +image_height: 720 +camera_name: narrow_stereo +camera_matrix: + rows: 3 + cols: 3 + data: [1030.629874, 0.000000, 656.550843, 0.000000, 1039.786278, 377.591933, 0.000000, 0.000000, 1.000000] +distortion_model: plumb_bob +distortion_coefficients: + rows: 1 + cols: 5 + data: [0.035110, -0.042717, 0.001123, -0.000234, 0.000000] +rectification_matrix: + rows: 3 + cols: 3 + data: [1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000] +projection_matrix: + rows: 3 + cols: 4 + data: [1038.616211, 0.000000, 656.304259, 0.000000, 0.000000, 1047.470825, 378.341316, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000] diff --git a/CoLo-PE/get_sensor_variances.py b/CoLo-PE/get_sensor_variances.py new file mode 100644 index 0000000000000000000000000000000000000000..620e9bcf2047e07039198b25c9e1559af240a7d1 --- /dev/null +++ b/CoLo-PE/get_sensor_variances.py @@ -0,0 +1,261 @@ +# -*- coding: utf-8 -*- + +import numpy as np +import sys +import getpass +from math import atan2, sqrt, pi +import statistics + + +def find_nearest_time_idx(l, value): + if len(l) != 0: + array = np.asarray(l) + idx = (np.abs(array-value)).argmin() + return idx + else: + return None + +def find_next_time_idx(array, start_idx, value): + i = start_idx + try: + array[i] + except IndexError: + i = -1 + return i + while array[i] < value: + i = i+1 + try: + array[i] + except IndexError: + i = -1 + break + return i + +class DatasetAnalyzer: + + def __init__(self, name): + self.name = name + + def create_landmark_map(self): + ### Build landmark map ### + self.landmark_map = {} + path=self.dataset_path + "Landmark_Groundtruth.dat" + landmark_file=open(path,'r+'); + s = landmark_file.readline() + while(s): + if(s[0]!='#'): + landmark_location = [float(s.split( )[1]), float(s.split( )[2])] + self.landmark_map.update({int(s.split( )[0]): landmark_location}) + s = landmark_file.readline() + landmark_file.close() + print(self.landmark_map) + #print "lm ", self.landmark_map, " lm" + return self.landmark_map + + + def getting_sensor_variances(self, dataset_path, dataset_labels, duration): + self.dataset_path = dataset_path + print("Absolute datapath: ") + print(self.dataset_path) + self.dataset_labels = dataset_labels + self.create_landmark_map() + + self.num_robots = len(self.dataset_labels) + self.diff_range_data = [[] for i in range(self.num_robots)] + self.diff_bearing_data = [[] for i in range(self.num_robots)] + self.diff_vel_data = [[] for i in range(self.num_robots)] + self.diff_a_v_data = [[] for i in range(self.num_robots)] + self.groundtruth_data = [[] for i in range(self.num_robots)] + + #self.groundtruth_time= [[] for i in range(self.num_robots)] + self.time_arr = {'odometry': [[] for i in range(self.num_robots)], 'measurement': [[] for i in range(self.num_robots)], 'groundtruth': [[] for i in range(self.num_robots)]} + + #initialization for MRCLAMDatasets: put files into dictionaries: + self.duration = duration # some more time to avoid index error + self.start_time_arr = [] + #finding the starting time: + for i, label in enumerate(self.dataset_labels): + robot_num = str(label) + groundtruth_path = self.dataset_path+"Robot"+robot_num+"_Groundtruth.dat" + with open(groundtruth_path,'r+') as groundtruth_file: + for line in groundtruth_file: + if str(line.split()[0]) != '#': + time = float(line.split()[0]) + self.start_time_arr.append(time) + break + self.start_time = max(self.start_time_arr) + self.end_time = self.start_time + self.duration + print('Staring time: ', self.start_time) + #finding starting states: + self.starting_states = {} + for i, label in enumerate(self.dataset_labels): + robot_num = str(label) + groundtruth_path = self.dataset_path+"Robot"+robot_num+"_Groundtruth.dat" + with open(groundtruth_path,'r+') as groundtruth_file: + for line in groundtruth_file: + if line[0] != '#' and float(line.split()[0]) >= self.start_time: + time = round(float(line.split()[0]), 3) + x_pos = float(line.split()[1]) + y_pos = float(line.split()[2]) + orientation = float(line.split()[3]) + self.starting_states[label] = [time, x_pos, y_pos, orientation] + break + + + for i, label in enumerate(self.dataset_labels): + robot_num = str(label) + + groundtruth_path = self.dataset_path+"Robot"+robot_num+"_Groundtruth.dat" + with open(groundtruth_path,'r+') as groundtruth_file: + for line in groundtruth_file: + if line[0] != '#' and (self.end_time >= float(line.split()[0]) >= self.start_time): + time = round(float(line.split()[0]), 3) + x_pos = float(line.split()[1]) + y_pos = float(line.split()[2]) + orientation = float(line.split()[3]) + groundtruth_info = {'time':time, 'x_pos':x_pos, 'y_pos':y_pos, 'orientation':orientation} + self.groundtruth_data[i].append(groundtruth_info) + self.time_arr['groundtruth'][i].append(time) + + + meas_path = self.dataset_path+"Robot"+robot_num+"_Measurement_x.dat" + with open(meas_path,'r+') as measure_file: + for line in measure_file: + if line[0] != '#' and (self.end_time>= float(line.split()[0]) >= self.start_time): + time = round(float(line.split()[0]), 3) + subject_ID = int(line.split()[1]) + measurment_range = float(line.split()[2]) + bearing = float(line.split()[3]) + + g_idx = find_nearest_time_idx(self.time_arr['groundtruth'][i],time) + gt_x = self.groundtruth_data[i][g_idx]['x_pos'] + gt_y = self.groundtruth_data[i][g_idx]['y_pos'] + orientation = self.groundtruth_data[i][g_idx]['orientation'] + landmark_loc = self.landmark_map.get(subject_ID) + if landmark_loc != None: + [lx, ly] = landmark_loc + range_hat = sqrt((lx-gt_x)*(lx-gt_x)+(ly-gt_y)*(ly-gt_y)) + bearing_hat = (atan2((ly-gt_y), (lx-gt_x))-orientation)%pi + if abs(bearing_hat-pi) < abs(bearing_hat): + bearing_hat = bearing_hat-pi + + diff_bearing = bearing - bearing_hat + diff_range = measurment_range- range_hat + self.diff_range_data[i].append(diff_range) + self.diff_bearing_data[i].append(diff_bearing) + self.time_arr['measurement'][i].append(time) + + + odo_path = self.dataset_path+"Robot"+robot_num+"_Odometry.dat" + with open(odo_path,'r+') as odometry_file: + lines = odometry_file.readlines() + for line_idx in range(0, len(lines)): + line = lines[line_idx] + if line[0] != '#' and (self.end_time >= float(line.split()[0]) >= self.start_time): + t = float(line.split()[0]) + time = round(float(line.split()[0]), 3) + g_idx = find_nearest_time_idx(self.time_arr['groundtruth'][i],time) + velocity = float(line.split()[1]) + a_v = float(line.split()[2]) + orientation = self.groundtruth_data[i][g_idx]['orientation'] + try: + next_line = lines[line_idx+1] + next_time = float(next_line.split()[0]) + delta_t = next_time - time + except IndexError: + delta_t = 0 + if delta_t < 0: + sys.exit('incorrect delta_t: '+ str(delta_t)) + + gt_t = self.groundtruth_data[i][g_idx]['time'] + gt_x = self.groundtruth_data[i][g_idx]['x_pos'] + gt_y = self.groundtruth_data[i][g_idx]['y_pos'] + + try: + gt_t_next = self.groundtruth_data[i][g_idx+5]['time'] + gt_x_next = self.groundtruth_data[i][g_idx+5]['x_pos'] + gt_y_next = self.groundtruth_data[i][g_idx+5]['y_pos'] + distance = sqrt((gt_x_next-gt_x)*(gt_x_next-gt_x)+(gt_y_next-gt_y)*(gt_y_next-gt_y)) + change_bearing = (atan2((gt_y_next-gt_y), (gt_x_next-gt_x))-orientation)%pi + if abs(change_bearing-pi) < abs(change_bearing): + change_bearing = change_bearing-pi + duration = gt_t_next - gt_t + + except IndexError: + gt_t_prev = self.groundtruth_data[i][g_idx-5]['time'] + gt_x_prev = self.groundtruth_data[i][g_idx-5]['x_pos'] + gt_y_prev = self.groundtruth_data[i][g_idx-5]['y_pos'] + distance = sqrt((gt_x_prev-gt_x)*(gt_x_prev-gt_x)+(gt_y_prev-gt_y)*(gt_y_prev-gt_y)) + change_bearing = (atan2((gt_y-gt_y_prev), (gt_x-gt_x_prev))-orientation)%pi + if abs(change_bearing-pi) < abs(change_bearing): + change_bearing = change_bearing-pi + duration = gt_t - gt_t_prev + diff_vel = velocity - distance/duration + + try: + gt_t_next = self.groundtruth_data[i][g_idx+15]['time'] + gt_x_next = self.groundtruth_data[i][g_idx+15]['x_pos'] + gt_y_next = self.groundtruth_data[i][g_idx+15]['y_pos'] + distance = sqrt((gt_x_next-gt_x)*(gt_x_next-gt_x)+(gt_y_next-gt_y)*(gt_y_next-gt_y)) + change_bearing = (atan2((gt_y_next-gt_y), (gt_x_next-gt_x))-orientation)%pi + if abs(change_bearing-pi) < abs(change_bearing): + change_bearing = change_bearing-pi + duration = gt_t_next - gt_t + + except IndexError: + gt_t_prev = self.groundtruth_data[i][g_idx-15]['time'] + gt_x_prev = self.groundtruth_data[i][g_idx-15]['x_pos'] + gt_y_prev = self.groundtruth_data[i][g_idx-15]['y_pos'] + distance = sqrt((gt_x_prev-gt_x)*(gt_x_prev-gt_x)+(gt_y_prev-gt_y)*(gt_y_prev-gt_y)) + change_bearing = (atan2((gt_y-gt_y_prev), (gt_x-gt_x_prev))-orientation)%pi + if abs(change_bearing-pi) < abs(change_bearing): + change_bearing = change_bearing-pi + duration = gt_t - gt_t_prev + + diff_a_v = a_v - change_bearing/duration + self.diff_vel_data[i].append(diff_vel) + self.diff_a_v_data[i].append(diff_a_v) + + + self.time_arr['odometry'][i].append(time) + + + range_vars = [] + bearing_vars = [] + velocity_vars = [] + angular_vel_vars = [] + for i, label in enumerate(self.dataset_labels): + print("*****************") + print('robot label: ', label) + print('range mean: ', statistics.mean(self.diff_range_data[i])) + range_var = statistics.variance(self.diff_range_data[i]) + range_vars.append(range_var) + print('range variance: ', range_var) + + print('bearing mean:', statistics.mean(self.diff_bearing_data[i])) + bearing_var = statistics.variance(self.diff_bearing_data[i]) + bearing_vars.append(bearing_var) + print('bearing variance: ', bearing_var) + + print('velocity mean: ', statistics.mean(self.diff_vel_data[i])) + velocity_var = statistics.variance(self.diff_vel_data[i]) + velocity_vars.append(velocity_var) + print('velocity variance: ', velocity_var) + + print('angular velocity mean:', statistics.mean(self.diff_a_v_data[i])) + angular_vel_var = statistics.variance(self.diff_a_v_data[i]) + angular_vel_vars.append(angular_vel_var) + print('angular velocity variance: ', angular_vel_var) + + print("*******Sensor Variances**********") + print("range \t\t bearing \t\t velocity \t\t angular velocity ") + print(statistics.mean(bearing_vars), statistics.mean(range_vars), statistics.mean(velocity_vars), statistics.mean(angular_vel_vars)) + return statistics.mean(bearing_vars), statistics.mean(range_vars), statistics.mean(velocity_vars), statistics.mean(angular_vel_vars) + + +compname = getpass.getuser() +dataset_path = "/home/"+ compname +"/full_tests/full_test_v3_2/" +dataset_labels = [1,2,3] +duration = 200 # duration for the simulation in sec +dataset = DatasetAnalyzer('DatasetAnalyzer') +dataset.getting_sensor_variances(dataset_path, dataset_labels, duration) \ No newline at end of file diff --git a/CoLo-PE/meas_transform.py b/CoLo-PE/meas_transform.py new file mode 100644 index 0000000000000000000000000000000000000000..44d96109108e67031654e78b9a50f4336f655bb8 --- /dev/null +++ b/CoLo-PE/meas_transform.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Thu Aug 23 15:45:39 2018 + +@author: william +""" + +import getpass +import math + +compname = getpass.getuser() + +dataset_path = "/home/"+ compname +"/full_tests/full_test_v3_6/" + +def meas_to_meas_x(robot_label): + meas_x_file_name = "Robot"+str(robot_label)+"_Measurement_x.dat" + print(meas_x_file_name) + f = open(dataset_path+meas_x_file_name, "w+") + f.write("# Time [sec] \t\t object id \t\t range [m] \t\t bearing [rad]\n") + robot_r = 0.16 #distance between label and the center of the robot + l = 0.1 #distance between cam and the center of the robot + + lable_dict = {} + path=dataset_path + "robot_labels.dat" + robot_labels=open(path,'r+'); + s = robot_labels.readline() + while(s): + if(s[0]!='#'): + lable_dict.update({s.split( )[0]: s.split( )[1]}) + s = robot_labels.readline() + robot_labels.close() + + meas_file_name = "Robot"+str(robot_label)+"_Measurement.dat" + with open(dataset_path+meas_file_name,'r+') as measure_file: + for line in measure_file: + if line[0] != '#': + subject_ID = line.split()[1] + range_cam = float(line.split()[2]) + bearing = float(line.split()[3]) + robot_id = lable_dict.get(subject_ID) + if robot_id != None: + subject_ID = robot_id + range_cam = range_cam+robot_r + + phi = math.atan2((range_cam*math.sin(bearing)), (range_cam*math.cos(bearing)+l)) + if phi != 0: + r_cen = range_cam*math.sin(bearing)/math.sin(phi) + f.write(line.split()[0] + '\t' + subject_ID + '\t\t\t' + str(r_cen) + '\t\t\t'+ str(phi) +'\n') + + f.close() + +for robot_label in [1,2,3]: + meas_to_meas_x(robot_label) \ No newline at end of file diff --git a/CoLo-PE/read_csv.py b/CoLo-PE/read_csv.py new file mode 100644 index 0000000000000000000000000000000000000000..1ca0d5bb44b2174e24ccd1cf9621d855a3d6d9c1 --- /dev/null +++ b/CoLo-PE/read_csv.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Thu Aug 23 14:36:28 2018 + +@author: william +""" + +import getpass +import csv +from datetime import datetime +import math + +compname = getpass.getuser() +datapath = "/home/"+ compname +"/full_tests/full_test_v3_6/" + + + +def generate_robot_gt_file(robot_label): + gt_file_name = "Robot"+ str(robot_label) + "_Groundtruth.dat" + print(gt_file_name) + f_r = open(datapath+gt_file_name, "w+") + f_r.write("# Time [sec] \t\t\t x [m] \t\t y [m] \t\t orientation [rad]\n") + + input_data = list(csv.reader(open(datapath+"gt.csv", "r+"))) + num_rows = len(input_data) + start_time = input_data[0][9] + + print("Experiment start time: ", start_time) + dt_obj = datetime.strptime(start_time, "%Y-%m-%d %I.%M.%S.%f %p") + time_tuple = dt_obj.timetuple() + timestamp = dt_obj.timestamp() + print(repr(timestamp)) + + col_idx = 2 + while input_data[3][col_idx] != '': + if input_data[3][col_idx] == 'irobot'+str(robot_label): + break + col_idx+=1 + + row_idx = 7 + + while row_idx < num_rows: + cur_time = input_data[row_idx][1] + x = input_data[row_idx][col_idx+3] + tmp = input_data[row_idx][col_idx+5] #z-positon(csv) -> y-position(dat) + y_rot = input_data[row_idx][col_idx] + if x!='': + y = float(tmp)*-1 + x = float(x) + if float(cur_time) >= 10: + pitch = math.radians(float(y_rot)) + f_r.write(str(float(cur_time)+timestamp) + '\t\t' + str(x) + '\t\t' + str(y) + '\t\t'+ str(pitch) + '\n') + + row_idx+=1 + + f_r.close() + +def generate_landmarks_gt_file(landmark_names, landmarks_dict): + gt_file_name = "Landmark_Groundtruth.dat" + print(gt_file_name) + f_r = open(datapath+gt_file_name, "w+") + f_r.write("# Landmark_tags [sec] \t x [m] \t y [m] \n") + + input_data = list(csv.reader(open(datapath+"gt.csv", "r+"))) + num_rows = len(input_data) + + for landmark_name in landmark_names: + col_idx = 2 + while input_data[3][col_idx] != '': + if input_data[3][col_idx] == landmark_name: + break + col_idx+=1 + + row_idx = 7 + + while row_idx < num_rows: + cur_time = input_data[row_idx][1] + x = input_data[row_idx][col_idx+3] + tmp = input_data[row_idx][col_idx+5] #z-positon(csv) -> y-position(dat) + if x!='' and float(cur_time) >= 10: + tags = landmarks_dict.get(landmark_name) + for tag_id in tags: + y = float(tmp)*-1 + x = float(x) + print(str(landmark_name)+"\t"+str(tag_id) + "\t" + str(x) + "\t" + str(y)) + f_r.write(str(tag_id) + "\t" + str(x) + "\t" + str(y) + '\n') + + break + row_idx+=1 + + f_r.close() + + + +for robot_label in [1,2,3]: + generate_robot_gt_file(robot_label) + pass + +landmark_names = ["landmark0", "landmark1", "landmark2", "landmark3", "landmark4", "landmark5", "landmark6", "landmark7"] +landmarks_dict = {"landmark0": [113, 114, 115, 116], "landmark1":[103, 104, 105, 106], "landmark2":[107], "landmark3":[110], "landmark4":[109], "landmark5":[108], "landmark6":[120],"landmark7":[124]} +generate_landmarks_gt_file(landmark_names, landmarks_dict) \ No newline at end of file diff --git a/CoLo-PE/robot_controls/CMakeLists.txt b/CoLo-PE/robot_controls/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..8ccc0b4d2ca97f91785a520d2ee41f261fa32c46 --- /dev/null +++ b/CoLo-PE/robot_controls/CMakeLists.txt @@ -0,0 +1,199 @@ +cmake_minimum_required(VERSION 2.8.3) +project(robot_controls) + +## 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 + rospy + sensor_msgs + std_msgs +) + +## 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 +# ca_msgs# sensor_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 robot_controls +# CATKIN_DEPENDS ca_msgs rospy sensor_msgs std_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}/robot_controls.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/robot_controls_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 and/or libraries for installation +# install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_PACKAGE_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_robot_controls.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/CoLo-PE/robot_controls/controls.py b/CoLo-PE/robot_controls/controls.py new file mode 100644 index 0000000000000000000000000000000000000000..6af60f8636487944e5de62cdbead4624270f7c63 --- /dev/null +++ b/CoLo-PE/robot_controls/controls.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python +from __future__ import print_function + +import rospy +import sys, termios, tty +import time +import random +from math import radians, degrees +from ca_msgs.msg import Bumper +import getpass +from geometry_msgs.msg import Twist + +movement_bindings = { + 'i':(1,0,0,0), + 'o':(1,0,0,-1), + 'j':(0,0,0,1), + 'l':(0,0,0,-1), + 'u':(1,0,0,1), + ',':(-1,0,0,0), + '.':(-1,0,0,1), + 'm':(-1,0,0,-1), + } + +welcomemsg = ''' +Welcome! +If you wish to access autonomous control of the robot, then enter one. +If you wish to access manual control, enter two. +If you wish to leave, enter break. +''' +automsg = ''' +If you want the robot to move in a square, type square. +If you want to see the robot move randomly, type random. +If you want to leave, type break. +''' +manualmsg = ''' +The controls are like so, and all are lowercase. +u i o +j l +m , . +''' + +class main(object): + def __init__(self): + self.lin = rospy.get_param('~linVel', .1) + self.ang = rospy.get_param('~angVel', 1.0) + self.compname = getpass.getuser() + self.f = open("/home/"+ self.compname +"/catkin_ws/ros_colo_dataset/command_vel.dat", "w+") + self.twist = Twist() + + def twist_msgs(self, lin_vel, ang_vel): + linear = ang_vel + angular = lin_vel + rtime = time.time() + self.f.write(str(rtime) + '\t\t' +str(linear) + '\t\t' + str(angular) + '\n') + + def publisher(self): + pub = rospy.Publisher("cmd_vel", Twist, queue_size = 30) + return pub + + def listener(self): + rospy.Subscriber("Bumper", Bumper, self.callback) + + def key(self): + fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(fd) + tty.setraw(sys.stdin.fileno()) + ch = sys.stdin.read(1) + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + return ch + + def movements(self, key, linear, angular): + x = movement_bindings[key][0] + y = movement_bindings[key][1] + z = movement_bindings[key][2] + th = movement_bindings[key][3] + + self.twist.linear.x = x*linear; self.twist.linear.y = y*linear; self.twist.linear.z = z*linear; + self.twist.angular.x = 0; self.twist.angular.y = 0; self.twist.angular.z = th*angular + pub = self.publisher() + pub.publish(self.twist) + self.twist_msgs(self.twist.linear.x, self.twist.angular.z) + + def callback(self, data): + pass + + def square(self): + sides = 4 + turns = 55 + forwards = 100 + for s in range(sides): + for t in range(turns): + self.movements('j', self.lin, 1.5) + time.sleep(.1) + for f in range(forwards): + self.movements('i', self.lin, self.ang) + time.sleep(.1) + + + def random(self, start, endTime): + while True: + keylist = ['u','i','o','u','i','o','j','l'] + rankey = random.choice(keylist) + + if rankey in ['j','l']: + ranint = random.randint(2,30) + else: + ranint = random.randint(15,25) + i = 0 + while i < ranint: + movements(rankey, self.lin, self.ang) + time.sleep(.1) + i += 1 + if time.time() > start + endTime: + break + + def manual(self): + print(manualmsg) + while True: + k = self.key() + if k in movement_bindings.keys(): + self.movements(k, self.lin, self.ang) + if k == "b": + break + +if __name__ =="__main__": + m = main() + rospy.init_node('controls') + m.publisher() + m.square() + rospy.spin() + + '''while True: + input1 = raw_input(welcomemsg + "\n") + + if input1 == "one": + input2 = raw_input("\n"+automsg+"\n") + + if input2 == "square": + m.square() + + if input2 == "random": + start = time.time() + endTime = 15 + m.random(start, endTime) + + if input2 == "break": + break + + if input1 == "two": + m.manual() + + if input1 == "break": + break''' diff --git a/CoLo-PE/robot_controls/create2_motion_control.py b/CoLo-PE/robot_controls/create2_motion_control.py new file mode 100644 index 0000000000000000000000000000000000000000..8f7b06674b530050e19075a6aa420a8d1d9774d0 --- /dev/null +++ b/CoLo-PE/robot_controls/create2_motion_control.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python +# license removed for brevity +import numpy as np +import rospy +import sys, termios, tty +import random +from math import radians, degrees +from ca_msgs.msg import Bumper +import getpass +import time +from geometry_msgs.msg import Twist + + +class create2_motion_controller(object): + """ + docstring for create2_motion_controller + + note: improve evasion to be smarter + make manual (optional) + + + """ + def __init__(self): + self.control_pub = rospy.Publisher("cmd_vel", Twist, queue_size = 30) + self.state_sub = rospy.Subscriber("bumper", Bumper, self.robot_motion) #original_freq = 10hz + self.rate = rospy.Rate(10) + self.eva = False + #not sure for get_param + #self.lin = rospy.get_param('~linVel', .2) + #self.ang = rospy.get_param('~angVel', 1.0) + self.lin = 0.1 + self.ang = 0.4 + self.evasion_time = 0 + self.end_node = time.time() + (60 * 5) + self.compname = getpass.getuser() + self.f = open("/home/"+ self.compname +"/catkin_ws/ros_colo_dataset/Robot1_Odometry_c"+str(time.time())+".dat", "w+") + self.f.write("# Time [sec] \t Velocity [m/s] \t Angular Velocity [rad/s] \n") + self.movement_bindings = { + 'i':(1,0,0,0), + 'o':(1,0,0,-1), + 'j':(0,0,0,1), + 'l':(0,0,0,-1), + 'u':(1,0,0,1), + ',':(-1,0,0,0), + '.':(-1,0,0,1), + 'm':(-1,0,0,-1), + } + self.twist = Twist() + + def twist_msgs(self, lin_vel, ang_vel): + rtime = time.time() + self.f.write(str(rtime) + '\t\t' +str(lin_vel) + '\t\t' + str(ang_vel) + '\n') + print(str(rtime) + '\t\t' +str(lin_vel) + '\t\t' + str(ang_vel) + '\n') + + def movements(self, key, linear, angular): + x = self.movement_bindings[key][0] + y = self.movement_bindings[key][1] + z = self.movement_bindings[key][2] + th = self.movement_bindings[key][3] + twist = Twist() + twist.linear.x = x*linear; twist.linear.y = y*linear; twist.linear.z = z*linear; + twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = th*angular + self.control_pub.publish(twist) + + def smooth_movements(self, linear_vel, angular_vel): + + ''' + control_input = [linear_vel, angular_vel] + self.twist.linear.x = 0 # [pos: forward velocity + self.twist.linear.y = 0 # no effects + self.twist.linear.z = 0 # no effects + self.twist.angular.x = 0 # no effects + self.twist.angular.y = 0 # no effects + self.twist.angular.z = 0.5 # angular velocity pos: counter-clock + ''' + if 0.2 > linear_vel > 0: + self.twist.linear.x = linear_vel + elif linear_vel <= 0: + self.twist.linear.x = 0 + else: + self.twist.linear.x = 0.2 + + if 0.1 > angular_vel > -0.1: + self.twist.angular.z = angular_vel + elif angular_vel > 0.1: + self.twist.angular.z = 0.1 + else: + self.twist.angular.z = -0.1 + + self.twist.linear.x = 0.1 + self.twist.angular.z = 0 + + + self.twist_msgs(self.twist.linear.x, self.twist.angular.z) + self.control_pub.publish(self.twist) + + + def manual_control(self, manual_input): + pass + + def backoff(self, barriers): + print("backoff") + linear_vel = self.twist.linear.x + angular_vel = self.twist.angular.z + + linear_vel = (linear_vel-0.1)/2 + angular_vel = (angular_vel - 0.2)/2 + + self.twist.linear.x = linear_vel + self.twist.angular.z = angular_vel + print("back 0: ", self.twist) + self.control_pub.publish(self.twist) + self.twist_msgs(self.twist.linear.x, self.twist.angular.z) + + ''' + linear_vel = -0.1 + if barriers[0]: # barrier on the left: + angular_vel = -0.2 + elif barriers[1]: + angular_vel = -0.1 + elif barriers[2]: + angular_vel = 0.2 + self.twist.linear.x = linear_vel + self.twist.angular.z = angular_vel + print("back 1: ", self.twist) + self.control_pub.publish(self.twist) + self.twist_msgs(self.twist.linear.x, self.twist.angular.z) + ''' + def evasion(self, barriers): + print("evasion") + linear_vel = -0.1 + angular_vel = -0.2 + self.twist.linear.x = linear_vel + self.twist.angular.z = angular_vel + print("back 0: ", self.twist) + self.control_pub.publish(self.twist) + self.twist_msgs(self.twist.linear.x, self.twist.angular.z) + + def random_movement(self): + print("Movement") + delta_vel = random.uniform(-0.02, 0.02) + delta_ang_vel = random.uniform(-0.07, 0.07) + self.smooth_movements(self.twist.linear.x+delta_vel, self.twist.angular.z+delta_ang_vel) + + def robot_motion(self, data): + if time.time() > self.end_node: + exit() + lef = data.is_light_left + lefron = data.is_light_front_left + lefcen = data.is_light_center_left + rigcen = data.is_light_center_right + rigfron = data.is_light_front_right + rig = data.is_light_right + + bumper_l = data.is_left_pressed + bumper_r = data.is_right_pressed + + left_barrier = bumper_l | lefron + front_barrier = lefcen | rigcen + right_barrier = rigfron | bumper_r + barriers = [left_barrier, front_barrier, right_barrier] + #disabled rig and lef + barriers_detected = lefron | lefcen | rigcen | rigfron | bumper_l | bumper_r + if barriers_detected: + self.backoff(barriers) + self.evasion_time = time.time()+3 + elif self.evasion_time >= time.time(): + self.evasion(barriers) + else: + self.random_movement() + +if __name__ == '__main__': + rospy.init_node('create2_motion_controller', anonymous=True) + c = create2_motion_controller() + c.rate.sleep() + rospy.spin() diff --git a/CoLo-PE/robot_controls/odometry_record.py b/CoLo-PE/robot_controls/odometry_record.py new file mode 100644 index 0000000000000000000000000000000000000000..b404af49f39a18f4543f90246b9aa6fef3d5f993 --- /dev/null +++ b/CoLo-PE/robot_controls/odometry_record.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +import rospy +import getpass +from sensor_msgs.msg import JointState +import time +import math + + +def ang_vel(lvel, rvel): + w = 0.0 + if ((lvel - rvel) != 0): + v1 = float(lvel) + v2 = float(rvel) + r1 = (v1 * .25)/(v2-v1) + w = v1/r1 + return w + +def callback(data): + t_sec = data.header.stamp.secs + t_nsec = data.header.stamp.nsecs + lvel = data.velocity[0] + rvel = data.velocity[1] + v = (lvel + rvel)/2 + w = ang_vel(lvel, rvel) + first = f.read(1) + print(str(t_sec) + '.' + str(t_nsec) + '\t\t' + str(v) +'\t\t'+ str(w) + '\t\t' + str(lvel) + '\t\t' + str(rvel) + '\n') + f.write(str(t_sec) + '.' + str(t_nsec) + '\t\t' + str(v) + '\t\t' + str(w) + '\t\t' + str(lvel) +'\t\t'+ str(rvel) +'\n') + #time.sleep(2/60) + +def listener(): + rospy.init_node('listenprint', anonymous=True) + rospy.Subscriber("joint_states", JointState, callback) + rospy.spin() + +if __name__== '__main__': + compname = getpass.getuser() + f = open("/home/"+ compname +"/catkin_ws/ros_colo_dataset/Robot1_Odometry.dat", "w+") + f.write("# Time [sec] \t\t\t Velocity [m/s] \t\t Angular Velocity [rad/s]\t\tLeft Wheel Velocity\t\tRIght Wheel Velocity\n") + listener() + diff --git a/CoLo-PE/robot_controls/package.xml b/CoLo-PE/robot_controls/package.xml new file mode 100644 index 0000000000000000000000000000000000000000..1c0050b52f460754a21b042fb39326fe10673d07 --- /dev/null +++ b/CoLo-PE/robot_controls/package.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<package format="2"> + <name>robot_controls</name> + <version>0.1.0</version> + <description>The robot_controls package</description> + + <maintainer email="you@yourdomain.tld">Your Name</maintainer> + <license>BSD</license> + <url type="website">http://wiki.ros.org/robot_controls</url> + <author email="you@yourdomain.tld">Jane Doe</author> + + <buildtool_depend>catkin</buildtool_depend> + + <exec_depend>sensor_msgs</exec_depend> + <exec_depend>std_msgs</exec_depend> + <exec_depend>rospy</exec_depend> + <exec_depend>geometry_msgs</exec_depend> + <exec_depend>ca_msgs</exec_depend> + +</package> diff --git a/CoLo-PE/robot_controls/publish.py b/CoLo-PE/robot_controls/publish.py new file mode 100644 index 0000000000000000000000000000000000000000..a277c17e268fc59940941ffd53e52ca4d0c7099e --- /dev/null +++ b/CoLo-PE/robot_controls/publish.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +import rospy +import getpass +from sensor_msgs.msg import JointState +import time +import math + +def velocity(lvel, rvel): + w = 0.0 + if ((lvel - rvel) != 0): + v1 = float(lvel) + v2 = float(rvel) + r1 = (v2 * .24)/(v2-v1) + w = v2/r1 + return w + +def callback(data): + t_sec = data.header.stamp.secs + t_nsec = data.header.stamp.nsecs + lvel = data.velocity[0] + rvel = data.velocity[1] + v = (lvel + rvel)/2 + w = velocity(lvel, rvel) + first = f.read(1) + f.write(str(t_sec) + '.' + str(t_nsec) + '\t\t' + str(v) +'\t\t\t'+ str(w) +'\n') + time.sleep(2/60) + +def listener(): + rospy.init_node('listenprint', anonymous=True) + rospy.Subscriber("joint_states", JointState, callback) + rospy.spin() + +if __name__== '__main__': + compname = getpass.getuser() + f = open("/home/"+ compname +"/catkin_ws/src/robot_controls/moveData.dat", "w+") + f.write("Time(seconds)\t\t\tVelocity(m/s)\t\tAngular Velocity(ra/s)\n") + listener() diff --git a/CoLo-PE/robot_full_run.sh b/CoLo-PE/robot_full_run.sh new file mode 100644 index 0000000000000000000000000000000000000000..99d1c89cedbcebe0fc686ed38983142dad733913 --- /dev/null +++ b/CoLo-PE/robot_full_run.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +cd $HOME/catkin_ws +xterm -hold -e "roslaunch usb_cam_stream_publisher.launch" & +sleep 5 +xterm -hold -e "roslaunch aruco_markers_detect.launch" & +sleep 3 +xterm -hold -e "rosrun image_view image_view image:=/fiducial_images" & +xterm -hold -e "rostopic echo /fiducial_transforms" & +sleep 2 +xterm -hold -e "rosrun topic_tools throttle messages /fiducial_transforms 5.0" & +xterm -hold -e "rostopic hz fiducial_transforms_throttle" & +sleep 1 +xterm -hold -e "rosrun aruco_record meas_record" & +sleep 1 +xterm -hold -e "roslaunch ca_driver create_2.launch" & +sleep 2 +xterm -hold -e "rosrun robot_controls create2_motion_control.py" + +cd $HOME/ + +exit 0 + +<<COMMENT + For the throttle frequencies: + Issues: throttle rates lower than expected(default rate = 30Hz) + Expected rate [Hz]: Real rate [Hz]: + 40 ~30 + 30 19.5~20 + 20 ~15 + 15 ~10.5 + 10 ~8.4 + 8 ~7.5 + 4 ~3.75 + 1 0.98 + +COMMENT diff --git a/CoLo-PE/usb_cam_stream_publisher.launch b/CoLo-PE/usb_cam_stream_publisher.launch new file mode 100644 index 0000000000000000000000000000000000000000..b11a9a74d7bdfdc046fd2deae8f6dffa32d4e110 --- /dev/null +++ b/CoLo-PE/usb_cam_stream_publisher.launch @@ -0,0 +1,30 @@ +<!-- +Example of run: +roslaunch usb_cam_stream_publisher.launch video_device:=/dev/video0 image_width:=640 image_height:=480 +--> + +<launch> +<arg name="video_device" default="/dev/video0" /> +<arg name="image_width" default="1280" /> +<arg name="image_height" default="720" /> +<arg name="framerate" default="20" /> +<arg name = "contrast" default="100"/> +<arg name="image_topic_name" default="/usb_cam/image_raw" /> +<arg name="camera_info_topic_name" default="/usb_cam/camera_info" /> + + +<node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" > +<param name="video_device" value="$(arg video_device)" /> +<param name="image_width" value="$(arg image_width)" /> +<param name="image_height" value="$(arg image_height)"/> +<param name="pixel_format" value="mjpeg" /> +<param name="io_method" value="mmap"/> + +<!-- update these line accroding to your setting, here are some examples:--> +<!-- <param name="camera_info_url" value="package://your_cameras/info/camera.yaml"/> --> +<param name="camera_info_url" value="file:///home/lemur-robot2/catkin_ws/cal_720p.yml"/> +<!-- <param name="camera_info_url" value="file://${ROS_HOME}/camera_info/head_camera.yaml"/> --> +<remap from="/usb_cam/camera_info" to="$(arg camera_info_topic_name)"/> +<remap from="/usb_cam/image_raw" to="$(arg image_topic_name)"/> +</node> +</launch>