├── README.md
├── racecar
├── ssh.sh
├── map
│ ├── test.pgm
│ ├── mymap.pgm
│ ├── test.yaml
│ ├── test1.pgm
│ ├── test1.yaml
│ └── mymap.yaml
├── udev
│ ├── README
│ ├── car.rules
│ ├── encoder.rules
│ ├── laser.rules
│ ├── racecar_init.sh
│ └── imu.rules
├── save_map.sh
├── src
│ ├── lib
│ │ └── libracecar_controller.a
│ ├── PID.h
│ ├── car_controller.hpp
│ ├── ESC_calibration.py
│ ├── racecar_joy.py
│ └── racecar_teleop.py
├── launch
│ ├── teleop_joy.launch
│ ├── rviz.launch
│ ├── car.launch
│ ├── includes
│ │ ├── car_tf.launch.xml
│ │ ├── rplidar.launch.xml
│ │ ├── ls01g.launch.xml
│ │ ├── rf2o.launch.xml
│ │ ├── default_mapping.launch.xml
│ │ └── amcl.launch.xml
│ ├── ls01g_lidar.launch
│ ├── ls01b_lidar.launch
│ ├── Run_car.launch
│ ├── amcl_nav_no_control.launch
│ ├── Run_gmapping.launch
│ ├── amcl_nav.launch
│ └── amcl_nav copy.launch
├── cfg
│ └── imu.cfg
├── param
│ ├── move_base_params.yaml
│ ├── base_global_planner_params.yaml
│ ├── dwa_local_planner_params.yaml
│ ├── local_costmap_params.yaml
│ └── global_costmap_params.yaml
├── racecar_rviz.sh
├── README.md
├── package.xml
└── rviz
│ └── test_laser.rviz
├── imu_tool
├── rviz_imu_plugin
│ ├── rosdoc.yaml
│ ├── rviz_imu_plugin.png
│ ├── plugin_description.xml
│ ├── package.xml
│ ├── CMakeLists.txt
│ ├── CHANGELOG.rst
│ └── src
│ │ ├── imu_axes_visual.h
│ │ ├── imu_acc_visual.h
│ │ ├── imu_orientation_visual.h
│ │ ├── imu_axes_visual.cpp
│ │ ├── imu_acc_visual.cpp
│ │ └── imu_display.h
├── imu_filter_madgwick
│ ├── sample
│ │ ├── ardrone_imu.bag
│ │ ├── sparkfun_razor.bag
│ │ └── phidgets_imu_upside_down.bag
│ ├── include
│ │ └── imu_filter_madgwick
│ │ │ ├── world_frame.h
│ │ │ ├── imu_filter_nodelet.h
│ │ │ ├── stateless_orientation.h
│ │ │ ├── imu_filter.h
│ │ │ └── imu_filter_ros.h
│ ├── imu_filter_nodelet.xml
│ ├── cfg
│ │ └── ImuFilterMadgwick.cfg
│ ├── src
│ │ ├── imu_filter_node.cpp
│ │ ├── imu_filter_nodelet.cpp
│ │ └── stateless_orientation.cpp
│ ├── package.xml
│ ├── CMakeLists.txt
│ └── test
│ │ ├── test_helpers.h
│ │ ├── madgwick_test.cpp
│ │ └── stateless_orientation_test.cpp
├── .travis.yml
├── .gitignore
├── imu_complementary_filter
│ ├── launch
│ │ ├── complementary_filter.launch
│ │ └── complementary_filter.l
│ ├── package.xml
│ ├── CMakeLists.txt
│ ├── src
│ │ └── complementary_filter_node.cpp
│ ├── CHANGELOG.rst
│ └── include
│ │ └── imu_complementary_filter
│ │ └── complementary_filter_ros.h
├── Dockerfile-kinetic
└── README.md
├── ROS_noetic
└── rviz显示.png
├── serial_imu
├── src
│ ├── packet.c
│ ├── sub_spec.cpp
│ ├── packet.h
│ ├── imu_data_decode.h
│ ├── sub_0x91.cpp
│ ├── imu_data_decode.c
│ ├── sub_0x62.cpp
│ └── serial_imu.cpp
├── msg
│ ├── Imu_0x91_msg.msg
│ ├── Imu_0x62_msg.msg
│ └── Imu_data_package.msg
└── package.xml
├── racecar_driver
├── lib
│ └── libracecar_driver.a
├── README
├── include
│ └── racecar_driver.h
├── src
│ └── racecar.cpp
└── package.xml
├── imu_launch
├── launch
│ ├── imu_rviz.launch
│ ├── imu_0x91_msg.launch
│ ├── imu_0x62_msg.launch
│ ├── imu_spec_msg.launch
│ ├── imu_display_3d.launch
│ └── imu_msg.launch
└── package.xml
├── encoder_driver
├── launch
│ └── wheel_odom.launch
├── README.md
├── CMakeLists.txt
├── package.xml
└── src
│ ├── Encoder_vel.py
│ └── imu_encoder_mix.cpp
└── multi_goal
├── README.md
└── src
├── test.csv
├── getpoints.py
└── goal_loop.py
/README.md:
--------------------------------------------------------------------------------
1 | # racecar
2 | 全国智能驾驶大赛暨全国大学生智能汽车竞赛室外专项赛 国家二等奖程序
3 |
--------------------------------------------------------------------------------
/racecar/ssh.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ssh sz@192.168.5.101
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/rosdoc.yaml:
--------------------------------------------------------------------------------
1 | - builder: sphinx
2 | sphinx_root_dir: src/doc
3 |
--------------------------------------------------------------------------------
/racecar/map/test.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/racecar/map/test.pgm
--------------------------------------------------------------------------------
/racecar/udev/README:
--------------------------------------------------------------------------------
1 | #添加Racecar的USB设备,使用如下指令:
2 | sudo bash racecar_init.sh
3 | 然后重启电脑
4 |
--------------------------------------------------------------------------------
/ROS_noetic/rviz显示.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/ROS_noetic/rviz显示.png
--------------------------------------------------------------------------------
/racecar/map/mymap.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/racecar/map/mymap.pgm
--------------------------------------------------------------------------------
/racecar/map/test.yaml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/racecar/map/test.yaml
--------------------------------------------------------------------------------
/racecar/map/test1.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/racecar/map/test1.pgm
--------------------------------------------------------------------------------
/serial_imu/src/packet.c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/serial_imu/src/packet.c
--------------------------------------------------------------------------------
/serial_imu/msg/Imu_0x91_msg.msg:
--------------------------------------------------------------------------------
1 | #90 91 data_package
2 | Header header
3 | Imu_data_package imu_data
4 |
5 |
--------------------------------------------------------------------------------
/racecar/save_map.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | rosrun map_server map_saver -f ~/ROS-Autocar/src/racecar/map/mymap
4 |
--------------------------------------------------------------------------------
/racecar/src/lib/libracecar_controller.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/racecar/src/lib/libracecar_controller.a
--------------------------------------------------------------------------------
/racecar_driver/lib/libracecar_driver.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/racecar_driver/lib/libracecar_driver.a
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/rviz_imu_plugin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/imu_tool/rviz_imu_plugin/rviz_imu_plugin.png
--------------------------------------------------------------------------------
/racecar/udev/car.rules:
--------------------------------------------------------------------------------
1 | # set the udev rule , make the device_port be fixed by arduino
2 | #
3 | KERNELS=="2-4:1.0", MODE:="666", SYMLINK+="car"
4 |
5 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/sample/ardrone_imu.bag:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/imu_tool/imu_filter_madgwick/sample/ardrone_imu.bag
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/sample/sparkfun_razor.bag:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/imu_tool/imu_filter_madgwick/sample/sparkfun_razor.bag
--------------------------------------------------------------------------------
/racecar/udev/encoder.rules:
--------------------------------------------------------------------------------
1 | # set the udev rule , make the device_port be fixed by arduino
2 | #
3 | KERNELS=="2-6:1.0", MODE:="666", SYMLINK+="encoder"
4 |
5 |
--------------------------------------------------------------------------------
/serial_imu/msg/Imu_0x62_msg.msg:
--------------------------------------------------------------------------------
1 | # 0x62 data_package
2 | Header header
3 | uint8 tag
4 | uint8 gw_id
5 | uint8 node_num
6 | Imu_data_package[16] node_data
7 |
8 |
--------------------------------------------------------------------------------
/imu_launch/launch/imu_rviz.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/sample/phidgets_imu_upside_down.bag:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiaNing-Z/racecar/HEAD/imu_tool/imu_filter_madgwick/sample/phidgets_imu_upside_down.bag
--------------------------------------------------------------------------------
/racecar/map/test1.yaml:
--------------------------------------------------------------------------------
1 | image: test1.pgm
2 | resolution: 0.050000
3 | origin: [-100.000000, -100.000000, 0.000000]
4 | negate: 0
5 | occupied_thresh: 0.65
6 | free_thresh: 0.196
7 |
8 |
--------------------------------------------------------------------------------
/racecar/udev/laser.rules:
--------------------------------------------------------------------------------
1 | # set the udev rule , make the device_port be fixed by ls-lidar
2 | #
3 | KERNEL=="ttyUSB*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001",MODE:="0666", SYMLINK+="laser"
4 |
5 |
--------------------------------------------------------------------------------
/imu_launch/launch/imu_0x91_msg.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/imu_launch/launch/imu_0x62_msg.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/imu_launch/launch/imu_spec_msg.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/racecar/map/mymap.yaml:
--------------------------------------------------------------------------------
1 | image: /home/racecar/racecar/src/racecar/map/mymap.pgm
2 | resolution: 0.050000
3 | origin: [-100.000000, -100.000000, 0.000000]
4 | negate: 0
5 | occupied_thresh: 0.65
6 | free_thresh: 0.196
7 |
8 |
--------------------------------------------------------------------------------
/imu_launch/launch/imu_display_3d.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/imu_launch/launch/imu_msg.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/racecar/udev/racecar_init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | sudo cp ./car.rules /etc/udev/rules.d
3 | sudo cp ./laser.rules /etc/udev/rules.d
4 | sudo cp ./imu.rules /etc/udev/rules.d
5 | sudo cp ./encoder.rules /etc/udev/rules.d
6 | #
7 | exit 0
8 |
--------------------------------------------------------------------------------
/encoder_driver/launch/wheel_odom.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/racecar/launch/teleop_joy.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/include/imu_filter_madgwick/world_frame.h:
--------------------------------------------------------------------------------
1 | #ifndef IMU_FILTER_MADGWICK_WORLD_FRAME_H_
2 | #define IMU_FILTER_MADGWICK_WORLD_FRAME_H_
3 |
4 | namespace WorldFrame {
5 | enum WorldFrame { ENU, NED, NWU };
6 | }
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/racecar/launch/rviz.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/racecar/udev/imu.rules:
--------------------------------------------------------------------------------
1 | # set the udev rule , make the device_port be fixed by hi226
2 | #
3 | KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE:="666", SYMLINK+="imu"
4 |
5 | # set the udev rule , make the device_port be fixed by sanchi_imu
6 | #
7 |
8 |
--------------------------------------------------------------------------------
/racecar/cfg/imu.cfg:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | PACKAGE = "racecar"
3 |
4 | from dynamic_reconfigure.parameter_generator_catkin import *
5 |
6 | gen = ParameterGenerator()
7 | gen.add("yaw_calibration", double_t, 0, "Yaw Calibration", 0, -10, 10)
8 |
9 | exit(gen.generate(PACKAGE, "racecar", "imu"))
10 |
--------------------------------------------------------------------------------
/multi_goal/README.md:
--------------------------------------------------------------------------------
1 | ## Multi Goal ##
2 | #### 包内有两个代码文件 .\src\getpoints.py .\src\goal_loop.py
3 |
4 | ##### getpoints.py
5 | 该文件的主要功能为记录途经点,并将途经点保存至同目录下的test.csv中,运行该脚本时需要在终端中cd到multi_goal\src文件夹,在rviz中可以使用goal point选点,需要注意顺序,结束选点时,在脚本的终端内输入 f 即可
6 |
7 | ##### goal_loop.py
8 | 该文件的主要功能是根据车辆的位置进行多点循环导航。导航点读取的是test.csv中的数据,切换点的时间会有一点的提前,为了保证比较好的路径跟踪效果。
--------------------------------------------------------------------------------
/racecar/launch/car.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/serial_imu/src/sub_spec.cpp:
--------------------------------------------------------------------------------
1 | //subscriber imu specifcation data package
2 | #include
3 | #include
4 | #include
5 |
6 |
7 | int main(int argc, char **argv)
8 | {
9 | ros::init(argc,argv,"sub_spec");
10 | ros::NodeHandle n;
11 | execlp("rostopic", "rostopic", "echo", "/IMU_data",NULL);
12 |
13 | ros::spin();
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/imu_tool/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 |
3 | services:
4 | - docker
5 |
6 | env:
7 | matrix:
8 | - CI_ROS_DISTRO="kinetic"
9 |
10 | install:
11 | - docker build -t imu_tools_$CI_ROS_DISTRO -f Dockerfile-$CI_ROS_DISTRO .
12 |
13 | script:
14 | - docker run imu_tools_$CI_ROS_DISTRO /bin/bash -c "source devel/setup.bash && catkin run_tests && catkin_test_results"
15 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/imu_filter_nodelet.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 | Imu Filter nodelet publisher.
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/plugin_description.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | Displays the orientation and acceleration components of sensor_msgs/Imu messages.
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/multi_goal/src/test.csv:
--------------------------------------------------------------------------------
1 | 3.802596092224121,2.1412878036499023,0.2882125757511959,0.957566452617708
2 | 2.6905717849731445,5.376918792724609,0.7896941641660048,0.6135007148179658
3 | 1.2487719058990479,8.993573188781738,0.9205451596762635,0.3906361593562514
4 | -1.7957332134246826,10.536282539367676,0.987439580364141,0.15799707317000827
5 | -6.061672210693359,9.39711856842041,-0.9997963389312687,0.02018119569380167
6 |
--------------------------------------------------------------------------------
/racecar_driver/README:
--------------------------------------------------------------------------------
1 | /*******************************************************************/
2 | /***************racecar_driver*****************************************/
3 | /*******************************************************************/
4 | 这是racecar的底层驱动例程
5 | 这个历程订阅/car/cmd_vel的twist的消息,发送给底层单片机
6 | 具体可以参考racecar.cpp
7 | 使用send_cmd()函数向单片机发送指令,函数参数分别为电机PWM和舵机PWM.
8 | PWM范围为500-2500us.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/serial_imu/msg/Imu_data_package.msg:
--------------------------------------------------------------------------------
1 | uint8 tag
2 | uint8 bitmap
3 | uint8 id
4 | float32 prs
5 | uint32 time
6 | uint32 frame_rate
7 | float32 acc_x
8 | float32 acc_y
9 | float32 acc_z
10 | float32 gyr_x
11 | float32 gyr_y
12 | float32 gyr_z
13 | float32 mag_x
14 | float32 mag_y
15 | float32 mag_z
16 | float32 eul_r
17 | float32 eul_p
18 | float32 eul_y
19 | float32 quat_w
20 | float32 quat_x
21 | float32 quat_y
22 | float32 quat_z
23 |
--------------------------------------------------------------------------------
/racecar/param/move_base_params.yaml:
--------------------------------------------------------------------------------
1 | # Move base node parameters. For full documentation of the parameters in this file, please see
2 | #
3 | # http://www.ros.org/wiki/move_base
4 | #
5 | shutdown_costmaps: false
6 |
7 | controller_frequency: 1.0
8 | controller_patience: 3.0
9 |
10 | planner_frequency: 10.0
11 | planner_patience: 5.0
12 |
13 | oscillation_timeout: 10.0
14 | oscillation_distance: 0.2
15 |
16 | clearing_rotation_allowed: false
17 |
--------------------------------------------------------------------------------
/imu_tool/.gitignore:
--------------------------------------------------------------------------------
1 | .cproject
2 | .project
3 | .pydevproject
4 | cmake_install.cmake
5 | bin/
6 | build/
7 | lib/
8 | *.cfgc
9 | imu_filter_madgwick/cfg/cpp/
10 | imu_filter_madgwick/docs/ImuFilterMadgwickConfig-usage.dox
11 | imu_filter_madgwick/docs/ImuFilterMadgwickConfig.dox
12 | imu_filter_madgwick/docs/ImuFilterMadgwickConfig.wikidoc
13 | imu_filter_madgwick/src/imu_filter_madgwick/__init__.py
14 | imu_filter_madgwick/src/imu_filter_madgwick/cfg/
15 | *~
--------------------------------------------------------------------------------
/racecar/racecar_rviz.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #for open rviz and set ROS master ip
4 | #Steven.Zhang
5 | #2018.03.09
6 |
7 | function get_ip_address { ifconfig | fgrep -v 127.0.0.1 | fgrep 'Mask:255.255.255.0' | egrep -o 'addr:[^ ]*' | fgrep '.8.'| sed 's/^.*://'; }
8 |
9 | #export ROS_IP=$(get_ip_address)
10 | export ROS_IP=`hostname -I`
11 | export ROS_MASTER_URI=http://192.168.5.101:11311
12 |
13 | ##source ../devel/setup.bash
14 | #rosrun rviz rviz
15 |
--------------------------------------------------------------------------------
/racecar/launch/includes/car_tf.launch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/encoder_driver/README.md:
--------------------------------------------------------------------------------
1 | ## Encoder ##
2 | #### 包内有两个代码文件 .\src\Encoder_vel.py .\src\imu_encoder_mix.cpp
3 | ##### Encoder_vel.py
4 | 负责串口的打开与数据读取发布,主要参数为:port baud k
5 | racecar\launch\Run_car.launch中已经写入了该脚本,port 与 baud都不需要修改(新车需要绑定串口)
6 | k是滑移系数,需要在使用前进行标定,即让车行走1m,观察里程计话题(/encoder_imu_odom)的输出量为a,则k=1/a
7 |
8 | ##### imu_encoder_mix.cpp
9 | IMU 与编码器的融合节点,订阅的话题为/imu_data /encoder ,输出话题为/encoder_imu_odom, 如果里程计不工作先排查两个输入的话题是否正常发值。
10 | encoder_driver\launch\wheel_odom.launch 该文件可以单独启动轮式里程计
11 |
--------------------------------------------------------------------------------
/racecar/launch/includes/rplidar.launch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/racecar_driver/include/racecar_driver.h:
--------------------------------------------------------------------------------
1 |
2 | //
3 | //racecar
4 | //
5 |
6 | #ifndef RACECAR_DRIVER
7 | #define RACECAR_DRIVER
8 | #include
9 | #include
10 |
11 | #if defined(__cplusplus)
12 | extern "C" {
13 | #endif
14 |
15 |
16 |
17 |
18 | int Open_Serial_Dev(char *dev);
19 |
20 | int art_racecar_init(int speed,char *dev);//设置波特率和串口设备
21 |
22 |
23 | unsigned char send_cmd(uint16_t motor_pwm,uint16_t servo_pwm);//发送指令(电机PWM,舵机PWM),单位为us.
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | #if defined(__cplusplus)
32 | }
33 | #endif
34 | #endif
35 |
--------------------------------------------------------------------------------
/racecar/param/base_global_planner_params.yaml:
--------------------------------------------------------------------------------
1 | GlobalPlanner:
2 | allow_unknown: false
3 | default_tolerance: 0.5 #路径规划器目标点的公差范围
4 | # visualize_potential: true #指定是否通过可视化PointCloud2计算的潜在区域
5 | use_dijkstra: false #如果为ture,则使用dijkstra算法。 否则使用A *算法
6 | use_quadratic: true #二次逼近
7 | use_grid_path: false #如果为true,沿着栅格边界创建路径。 否则,使用梯度下降的方法。
8 | # old_navfn_behavior: true #如果你想要global_planner准确反映navfn的行为,此项设置为true。
9 |
10 | # lethal_cost: 25
11 | # neutral_cost: 50
12 | # cost_factor: 3
13 | # publish_potential: True
14 |
15 |
16 | NavfnROS:
17 | allow_unknown: false
18 |
--------------------------------------------------------------------------------
/racecar/src/PID.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef PID_H
3 | #define PID_H
4 |
5 | /***********************************/
6 | typedef struct PID
7 | { //结构体定义
8 | double SetPoint; //设定值
9 | double Proportion; // Proportion 比例系数
10 | double Integral; // Integral 积分系数
11 | double Derivative; // Derivative 微分系数
12 | double LastError; // Error[-1] 前一拍误差
13 | double PreError; // Error[-2] 前两拍误差
14 |
15 |
16 | }PID;
17 |
18 |
19 | void PIDInit (struct PID *pp);
20 | double PIDCal(struct PID *pp, double ThisError);
21 |
22 |
23 |
24 |
25 | #endif
26 |
27 |
28 |
--------------------------------------------------------------------------------
/imu_tool/imu_complementary_filter/launch/complementary_filter.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 | #### Nodelet manager ######################################################
4 |
5 |
6 |
7 | #### Complementary filter
8 |
9 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/serial_imu/src/packet.h:
--------------------------------------------------------------------------------
1 | #ifndef __PACKET_H__
2 | #define __PACKET_H__
3 |
4 | #include
5 | #include
6 |
7 | #define MAX_PACKET_LEN (2048)
8 | extern uint32_t frame_count;
9 | extern uint32_t crc_error_count;
10 |
11 | typedef struct
12 | {
13 | uint32_t ofs;
14 | uint8_t buf[MAX_PACKET_LEN]; /* total frame buffer */
15 | uint16_t payload_len;
16 | uint16_t len; /* total frame len */
17 | uint8_t type;
18 | }packet_t;
19 |
20 |
21 | /* packet Rx API */
22 | typedef void (*on_data_received_event)(packet_t *pkt);
23 | void packet_decode_init(packet_t *pkt, on_data_received_event rx_handler);
24 | uint32_t packet_decode(uint8_t c);
25 |
26 |
27 | #endif
28 |
29 |
--------------------------------------------------------------------------------
/imu_tool/Dockerfile-kinetic:
--------------------------------------------------------------------------------
1 | FROM ros:kinetic-ros-core
2 |
3 | RUN apt-get update \
4 | && apt-get install -y build-essential python-catkin-tools python-rosdep \
5 | && rm -rf /var/lib/apt/lists/{apt,dpkg,cache,log} /tmp/* /var/tmp/*
6 |
7 | # Create ROS workspace
8 | COPY . /ws/src/imu_tools
9 | WORKDIR /ws
10 |
11 | # Use rosdep to install all dependencies (including ROS itself)
12 | RUN rosdep init && rosdep update && rosdep install --from-paths src -i -y --rosdistro kinetic
13 |
14 | RUN /bin/bash -c "source /opt/ros/kinetic/setup.bash && \
15 | catkin init && \
16 | catkin config --install -j 1 -p 1 && \
17 | catkin build --limit-status-rate 0.1 --no-notify && \
18 | catkin build --limit-status-rate 0.1 --no-notify --make-args tests"
19 |
--------------------------------------------------------------------------------
/racecar/launch/ls01g_lidar.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #设置激光数据topic名称
7 | #激光坐标
8 | #雷达连接的串口
9 | # 设置为true探测不到区域会变成最大值
10 | # true:探测不到区域为0,false:探测不到区域为inf
11 | # 角度制,从angle_disable_min到angle_disable_max之前的值为0
12 |
13 | # 如果0度方向在串口线的方向上设置为true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/racecar_driver/src/racecar.cpp:
--------------------------------------------------------------------------------
1 | //
2 | //racecar
3 | //
4 |
5 | #include "../include/racecar_driver.h"
6 | #include
7 | #include
8 | #include
9 |
10 | void TwistCallback(const geometry_msgs::Twist& twist)
11 | {
12 | double angle;
13 | //ROS_INFO("x= %f", twist.linear.x);
14 | //ROS_INFO("z= %f", twist.angular.z);
15 | angle = 2500.0 - twist.angular.z * 2000.0 / 180.0;
16 | //ROS_INFO("angle= %d",uint16_t(angle));
17 | send_cmd(uint16_t(twist.linear.x),uint16_t(angle));
18 | }
19 |
20 | int main(int argc, char** argv)
21 | {
22 | char data[] = "/dev/car";
23 | art_racecar_init(38400,data);
24 | ros::init(argc, argv, "racecar_driver");
25 | ros::NodeHandle n;
26 |
27 | ros::Subscriber sub = n.subscribe("/car/cmd_vel",1,TwistCallback);
28 |
29 |
30 |
31 | ros::spin();
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/racecar/launch/includes/ls01g.launch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | #设置激光数据topic名称
6 | #激光坐标
7 | #雷达连接的串口
8 | # 设置为true探测不到区域会变成最大值
9 | # true:探测不到区域为0,false:探测不到区域为inf
10 | # 角度制,从angle_disable_min到angle_disable_max之前的值为0
11 |
12 | # 如果0度方向在串口线的方向上设置为true
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/racecar/launch/ls01b_lidar.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | #设置激光数据topic名称
6 | #激光坐标
7 | #雷达连接的串口
8 | #雷达连接的串口波特率
9 | #雷达角度分辨率
10 | # 设置为true探测不到区域会变成最大值
11 | # true:探测不到区域为0,false:探测不到区域为inf
12 | # 雷达转速
13 | # 角度补偿,非同轴
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/racecar/param/dwa_local_planner_params.yaml:
--------------------------------------------------------------------------------
1 | DWAPlannerROS:
2 |
3 | acc_lim_th: 1
4 | acc_lim_x: 1
5 | acc_lim_y: 1
6 |
7 |
8 | max_vel_x: 1
9 | min_vel_x: 1
10 |
11 | max_vel_y: 1
12 | min_vel_y: 1
13 |
14 | max_vel_trans: 1
15 | min_vel_trans: 1
16 | max_rot_vel: 1
17 | min_rot_vel: 1
18 |
19 | sim_time: 1.5
20 |
21 | sim_granularity: 0.1
22 |
23 | goal_distance_bias: 30.0
24 | path_distance_bias: 20.0
25 | occdist_scale: 0.01
26 | forward_point_distance: 0.5
27 | stop_time_buffer: 0.2
28 | #######
29 | scaling_speed: 0.5
30 | #######
31 | max_scaling_factor: 0.2
32 | oscillation_reset_dist: 0.05
33 |
34 | #
35 | vx_samples: 20
36 | vy_samples: 0
37 | vtheta_samples: 10
38 |
39 | theta_stopped_vel: 0.01
40 | trans_stopped_vel: 0.01
41 | #
42 | xy_goal_tolerance: 0.2
43 | yaw_goal_tolerance: 0.1
44 | latch_xy_goal_tolerance: true #如果目标误差被锁定,若机器人达到目标XY位置,它将旋转到位,即使误差没有达到,也会做旋转
45 |
--------------------------------------------------------------------------------
/racecar/param/local_costmap_params.yaml:
--------------------------------------------------------------------------------
1 | local_costmap:
2 | footprint: [[-0.305, -0.18], [-0.305, 0.18], [0.305, 0.18], [0.305, -0.18]]
3 | footprint_padding: 0.01
4 | transform_tolerance: 0.5
5 | update_frequency: 10.0
6 | publish_frequency: 10.0
7 |
8 | global_frame: map
9 | robot_base_frame: base_footprint
10 | resolution: 0.10
11 |
12 | rolling_window: true
13 | width: 10.0
14 | height: 10.0
15 | resolution: 0.05
16 |
17 | track_unknown_space: false
18 |
19 | plugins:
20 | - {name: sensor, type: "costmap_2d::ObstacleLayer"}
21 | - {name: inflation, type: "costmap_2d::InflationLayer"}
22 |
23 | sensor:
24 | observation_sources: laser_scan_sensor
25 | laser_scan_sensor: {sensor_frame: laser_link, data_type: LaserScan, topic: scan, marking: true, clearing: true}
26 |
27 | inflation:
28 | inflation_radius: 0.1
29 | cost_scaling_factor: 8.0
30 |
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/package.xml:
--------------------------------------------------------------------------------
1 |
2 | rviz_imu_plugin
3 | 1.1.8
4 |
5 | RVIZ plugin for IMU visualization
6 |
7 | BSD
8 | http://ros.org/wiki/rviz_imu_plugin
9 | Ivan Dryanovski
10 | Martin Günther
11 |
12 | catkin
13 |
14 | qtbase5-dev
15 | roscpp
16 | rviz
17 |
18 | libqt5-core
19 | libqt5-gui
20 | libqt5-widgets
21 | roscpp
22 | rviz
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/racecar/param/global_costmap_params.yaml:
--------------------------------------------------------------------------------
1 | global_costmap:
2 | footprint: [[-0.305, -0.18], [-0.305, 0.18], [0.305, 0.18], [0.305, -0.18]]
3 | footprint_padding: 0.01
4 | transform_tolerance: 0.5
5 | update_frequency: 10.0
6 | publish_frequency: 10.0
7 |
8 | global_frame: map
9 | robot_base_frame: base_footprint
10 | resolution: 0.10
11 |
12 | rolling_window: true
13 | width: 20.0
14 | height: 20.0
15 | track_unknown_space: false
16 |
17 | plugins:
18 | - {name: static, type: "costmap_2d::StaticLayer"}
19 | - {name: sensor, type: "costmap_2d::ObstacleLayer"}
20 | - {name: inflation, type: "costmap_2d::InflationLayer"}
21 |
22 | static:
23 | map_topic: /map
24 | subscribe_to_updates: true
25 |
26 | sensor:
27 | observation_sources: laser_scan_sensor
28 | laser_scan_sensor: {sensor_frame: laser_link, data_type: LaserScan, topic: scan, marking: true, clearing: true}
29 |
30 | inflation:
31 | inflation_radius: 0.1
32 | cost_scaling_factor: 8.0
33 |
34 |
--------------------------------------------------------------------------------
/racecar/launch/Run_car.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/cfg/ImuFilterMadgwick.cfg:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | # IMU Filter dynamic reconfigure
3 |
4 | PACKAGE='imu_filter_madgwick'
5 |
6 | from dynamic_reconfigure.parameter_generator_catkin import *
7 |
8 | gen = ParameterGenerator()
9 |
10 | gen.add("gain", double_t, 0, "Gain of the filter. Higher values lead to faster convergence but more noise. Lower values lead to slower convergence but smoother signal.", 0.1, 0.0, 1.0)
11 | gen.add("zeta", double_t, 0, "Gyro drift gain (approx. rad/s).", 0, -1.0, 1.0)
12 | gen.add("mag_bias_x", double_t, 0, "Magnetometer bias (hard iron correction), x component.", 0, -10.0, 10.0)
13 | gen.add("mag_bias_y", double_t, 0, "Magnetometer bias (hard iron correction), y component.", 0, -10.0, 10.0)
14 | gen.add("mag_bias_z", double_t, 0, "Magnetometer bias (hard iron correction), z component.", 0, -10.0, 10.0)
15 | gen.add("orientation_stddev", double_t, 0, "Standard deviation of the orientation estimate.", 0, 0, 1.0)
16 |
17 | exit(gen.generate(PACKAGE, "dynamic_reconfigure_node", "ImuFilterMadgwick"))
18 |
19 |
--------------------------------------------------------------------------------
/encoder_driver/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(encoder_driver)
3 |
4 | ## Compile as C++11, supported in ROS Kinetic and newer
5 | # add_compile_options(-std=c++11)
6 |
7 | ## Find catkin macros and libraries
8 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
9 | ## is used, also find other catkin packages
10 | find_package(catkin REQUIRED COMPONENTS
11 | rospy
12 | roscpp
13 | serial
14 | std_msgs
15 | nav_msgs
16 | std_msgs
17 | geometry_msgs
18 | tf
19 | dynamic_reconfigure
20 | )
21 |
22 | catkin_package(
23 | LIBRARIES art_encoder_driver
24 | CATKIN_DEPENDS
25 | rospy
26 | std_msgs
27 | serial
28 | geometry_msgs
29 | tf
30 | )
31 |
32 | include_directories(
33 | # include
34 | ${catkin_INCLUDE_DIRS}
35 | )
36 |
37 |
38 |
39 | add_executable(${PROJECT_NAME}_node1
40 | src/imu_encoder_mix.cpp)
41 | add_dependencies(${PROJECT_NAME}_node1 ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
42 | target_link_libraries(${PROJECT_NAME}_node1
43 | ${catkin_LIBRARIES}
44 | )
45 |
46 |
47 |
48 | SET( CMAKE_CXX_FLAGS "-std=c++11 -O3")
49 |
50 |
51 |
--------------------------------------------------------------------------------
/imu_tool/imu_complementary_filter/launch/complementary_filter.l:
--------------------------------------------------------------------------------
1 |
2 |
3 | #### Nodelet manager ######################################################
4 |
5 |
7 |
8 | #### IMU Driver ###########################################################
9 |
10 |
13 |
14 | # supported data rates: 4 8 16 24 32 40 ... 1000 (in ms)
15 |
16 |
17 |
18 |
19 | #### Complementary filter
20 |
21 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/src/imu_filter_node.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010, CCNY Robotics Lab
3 | * Ivan Dryanovski
4 | *
5 | * http://robotics.ccny.cuny.edu
6 | *
7 | * Based on implementation of Madgwick's IMU and AHRS algorithms.
8 | * http://www.x-io.co.uk/node/8#open_source_ahrs_and_imu_algorithms
9 | *
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include "imu_filter_madgwick/imu_filter_ros.h"
26 |
27 | int main (int argc, char **argv)
28 | {
29 | ros::init (argc, argv, "ImuFilter");
30 | ros::NodeHandle nh;
31 | ros::NodeHandle nh_private("~");
32 | ImuFilterRos imu_filter(nh, nh_private);
33 | ros::spin();
34 | return 0;
35 | }
36 |
--------------------------------------------------------------------------------
/imu_tool/imu_complementary_filter/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | imu_complementary_filter
4 | 1.1.8
5 | Filter which fuses angular velocities, accelerations, and (optionally) magnetic readings from a generic IMU device into a quaternion to represent the orientation of the device wrt the global frame. Based on the algorithm by Roberto G. Valenti etal. described in the paper "Keeping a Good Attitude: A Quaternion-Based Orientation Filter for IMUs and MARGs" available at http://www.mdpi.com/1424-8220/15/8/19302 .
6 |
7 | Roberto G. Valenti
8 | BSD
9 |
10 | http://www.mdpi.com/1424-8220/15/8/19302
11 | Roberto G. Valenti
12 |
13 | catkin
14 | cmake_modules
15 | message_filters
16 | roscpp
17 | sensor_msgs
18 | std_msgs
19 | tf
20 | message_filters
21 | roscpp
22 | sensor_msgs
23 | std_msgs
24 | tf
25 |
26 |
--------------------------------------------------------------------------------
/racecar/launch/includes/rf2o.launch.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/include/imu_filter_madgwick/imu_filter_nodelet.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010, CCNY Robotics Lab
3 | * Ivan Dryanovski
4 | *
5 | * http://robotics.ccny.cuny.edu
6 | *
7 | * Based on implementation of Madgwick's IMU and AHRS algorithms.
8 | * http://www.x-io.co.uk/node/8#open_source_ahrs_and_imu_algorithms
9 | *
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef IMU_FILTER_MADGWICK_IMU_FILTER_NODELET_H
26 | #define IMU_FILTER_MADGWICK_IMU_FILTER_NODELET_H
27 |
28 | #include
29 |
30 | #include "imu_filter_madgwick/imu_filter_ros.h"
31 |
32 | class ImuFilterNodelet : public nodelet::Nodelet
33 | {
34 | public:
35 | virtual void onInit();
36 |
37 | private:
38 | boost::shared_ptr filter_;
39 | };
40 |
41 | #endif // IMU_FILTER_MADGWICK_IMU_FILTER_NODELET_H
42 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/src/imu_filter_nodelet.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010, CCNY Robotics Lab
3 | * Ivan Dryanovski
4 | *
5 | * http://robotics.ccny.cuny.edu
6 | *
7 | * Based on implementation of Madgwick's IMU and AHRS algorithms.
8 | * http://www.x-io.co.uk/node/8#open_source_ahrs_and_imu_algorithms
9 | *
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include "imu_filter_madgwick/imu_filter_nodelet.h"
26 | #include
27 |
28 | void ImuFilterNodelet::onInit()
29 | {
30 | NODELET_INFO("Initializing IMU Filter Nodelet");
31 |
32 | // TODO: Do we want the single threaded or multithreaded NH?
33 | ros::NodeHandle nh = getMTNodeHandle();
34 | ros::NodeHandle nh_private = getMTPrivateNodeHandle();
35 |
36 | filter_.reset(new ImuFilterRos(nh, nh_private));
37 | }
38 |
39 | PLUGINLIB_EXPORT_CLASS(ImuFilterNodelet, nodelet::Nodelet)
40 |
--------------------------------------------------------------------------------
/racecar/README.md:
--------------------------------------------------------------------------------
1 | #Racecar
2 |
3 | ROS racecar
4 | ************************安装************************
5 |
6 | 配置小车串口udev:
7 | cd ~/racecar/src/racecar/udev
8 | sudo bash racecar_init.sh
9 | sudo reboot
10 | **********************建立地图**********************
11 | 先安装电脑用户名和主机名配置主从机
12 | a) 运行车
13 | roslaunch racecar Run_car.launch
14 | b) 3.3运行gmapping
15 | roslaunch racecar Run_gmapping.launch
16 | c) 3.4运行键盘控制
17 | rosrun racecar racecar_teleop.py
18 | 或者手柄遥控
19 | roslaunch racecar teleop_joy.launch
20 | d) 3.6 建立地图
21 | 键盘控制建立地图,按键如下:
22 | U I O
23 | J K L
24 | M , .
25 | 加减速为W,S.
26 | 手柄控制:
27 | L侧方向键:上下为加速减速,左右为转向幅度大小调节
28 | R侧摇杆:控制小车运动
29 | e) 保存地图(地图直接保存在小车上)
30 | 在racecar文件夹下执行:bash save_map.sh
31 | 地图保存在racecar/map/mymap.pgm
32 |
33 |
34 | ************************导航************************
35 |
36 | a) 运行车
37 | roslaunch racecar Run_car.launch
38 | b) 运行AMCL
39 | roslaunch racecar amcl_nav.launch
40 | c) 4.5 开始导航
41 | 在RVIZ中设定初始坐标,设定目标位置,开始导航
42 | *********************软件接口***********************
43 | 1.启动底盘
44 | 启动底盘需要启动rosserial_python节点。
45 | 设置参考racecar/launch/Run_car.launch
46 | 2.发布地盘控制指令:
47 | 通过发布Twist消息控制底盘。
48 | 线速度:twist.linear.x,这里的线速度范围为500~2500(对应PWM脉冲为0.5ms~2.5ms),1500为静止,1500-2500为正向速度,500-1500为反向速度。
49 | 角速度:twist.angular.x,这里角度范围为0~180度,90度为中间值,90-180度左转,0-90度右转。
50 | 3.里程计数据:
51 | 里程计采用激光雷达和IMU数据融合的里程计。
52 | 需要先启动IMU节点和雷达节点,参考racecar/launch/Run_car.launch
53 | 然后启动rf2o节点,用rf2o生成激光里程计,参考racecar/launch/includes/rf2o.launch.xml
54 | 再启动robot_localization用EKF融合里程计信息,参考racecar/launch/Run_gmapping.launch
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/package.xml:
--------------------------------------------------------------------------------
1 |
2 | imu_filter_madgwick
3 | 1.1.8
4 |
5 | Filter which fuses angular velocities, accelerations, and (optionally) magnetic readings from a generic IMU device into an orientation. Based on code by Sebastian Madgwick, http://www.x-io.co.uk/node/8#open_source_ahrs_and_imu_algorithms.
6 |
7 | GPL
8 | http://ros.org/wiki/imu_filter_madgwick
9 | Ivan Dryanovski
10 | Martin Günther
11 |
12 | catkin
13 |
14 | roscpp
15 | sensor_msgs
16 | geometry_msgs
17 | tf2
18 | tf2_geometry_msgs
19 | tf2_ros
20 | nodelet
21 | pluginlib
22 | message_filters
23 | dynamic_reconfigure
24 |
25 | roscpp
26 | sensor_msgs
27 | geometry_msgs
28 | tf2
29 | tf2_geometry_msgs
30 | tf2_ros
31 | nodelet
32 | pluginlib
33 | message_filters
34 | dynamic_reconfigure
35 |
36 | rosunit
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/include/imu_filter_madgwick/stateless_orientation.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010, CCNY Robotics Lab
3 | * Ivan Dryanovski
4 | *
5 | * http://robotics.ccny.cuny.edu
6 | *
7 | * Based on implementation of Madgwick's IMU and AHRS algorithms.
8 | * http://www.x-io.co.uk/node/8#open_source_ahrs_and_imu_algorithms
9 | *
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef IMU_FILTER_MADWICK_STATELESS_ORIENTATION_H
26 | #define IMU_FILTER_MADWICK_STATELESS_ORIENTATION_H
27 |
28 | #include
29 | #include
30 | #include
31 |
32 | class StatelessOrientation
33 | {
34 | public:
35 | static bool computeOrientation(
36 | WorldFrame::WorldFrame frame,
37 | geometry_msgs::Vector3 acceleration,
38 | geometry_msgs::Vector3 magneticField,
39 | geometry_msgs::Quaternion& orientation);
40 |
41 | static bool computeOrientation(
42 | WorldFrame::WorldFrame frame,
43 | geometry_msgs::Vector3 acceleration,
44 | geometry_msgs::Quaternion& orientation);
45 |
46 | };
47 |
48 | #endif // IMU_FILTER_MADWICK_STATELESS_ORIENTATION_H
49 |
--------------------------------------------------------------------------------
/imu_tool/imu_complementary_filter/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.5.1)
2 | cmake_policy(SET CMP0048 NEW)
3 | project(imu_complementary_filter)
4 |
5 | find_package(Boost REQUIRED COMPONENTS thread)
6 |
7 | find_package(catkin REQUIRED COMPONENTS
8 | cmake_modules
9 | message_filters
10 | roscpp
11 | sensor_msgs
12 | std_msgs
13 | tf
14 | )
15 |
16 | catkin_package(
17 | INCLUDE_DIRS include
18 | LIBRARIES complementary_filter
19 | CATKIN_DEPENDS message_filters roscpp sensor_msgs std_msgs tf
20 | )
21 |
22 | include_directories(
23 | include
24 | ${catkin_INCLUDE_DIRS}
25 | ${Boost_INCLUDE_DIRS}
26 | )
27 |
28 | ## Declare a cpp library
29 | add_library(complementary_filter
30 | src/complementary_filter.cpp
31 | src/complementary_filter_ros.cpp
32 | include/imu_complementary_filter/complementary_filter.h
33 | include/imu_complementary_filter/complementary_filter_ros.h
34 | )
35 | target_link_libraries(complementary_filter ${catkin_LIBRARIES} ${Boost_LIBRARIES})
36 |
37 |
38 | # create complementary_filter_node executable
39 | add_executable(complementary_filter_node
40 | src/complementary_filter_node.cpp)
41 | target_link_libraries(complementary_filter_node complementary_filter ${catkin_LIBRARIES})
42 |
43 | install(TARGETS complementary_filter
44 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
45 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
46 | RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
47 | )
48 |
49 | install(TARGETS complementary_filter_node
50 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
51 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
52 | RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
53 | )
54 |
55 | ## Mark cpp header files for installation
56 | install(DIRECTORY include/${PROJECT_NAME}/
57 | DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
58 | FILES_MATCHING PATTERN "*.h"
59 | PATTERN ".svn" EXCLUDE
60 | )
61 |
--------------------------------------------------------------------------------
/serial_imu/src/imu_data_decode.h:
--------------------------------------------------------------------------------
1 | #ifndef __IMU_DATA_DECODE_H__
2 | #define __IMU_DATA_DECODE_H__
3 |
4 | #include
5 | #include
6 | #define MAX_LENGTH 16
7 |
8 | extern uint8_t bitmap;
9 | #define BIT_VALID_ID (0x01)
10 | #define BIT_VALID_ACC (0x02)
11 | #define BIT_VALID_GYR (0x04)
12 | #define BIT_VALID_MAG (0x08)
13 | #define BIT_VALID_EUL (0x10)
14 | #define BIT_VALID_QUAT (0x20)
15 | #define BIT_VALID_TIME (0x40)
16 | #define BIT_VALID_PRS (0x80)
17 | #define BIT_VALID_ALL (BIT_VALID_QUAT | BIT_VALID_EUL | BIT_VALID_MAG | BIT_VALID_GYR | BIT_VALID_ACC | BIT_VALID_ID | BIT_VALID_TIME | BIT_VALID_PRS)
18 |
19 | typedef struct id0x91_t {
20 | uint8_t tag;
21 | uint8_t id;
22 | uint8_t rev[2];
23 | float prs;
24 | uint32_t time;
25 | float acc[3];
26 | float gyr[3];
27 | float mag[3];
28 | float eul[3];
29 | float quat[4];
30 |
31 | }__attribute__((packed())) id0x91_t;
32 |
33 | typedef struct id0x62_t {
34 | uint8_t tag;
35 | uint8_t gw_id;
36 | uint8_t n;
37 | uint8_t rev[5];
38 | id0x91_t id0x91[MAX_LENGTH];
39 | }__attribute__((packed())) id0x62_t;
40 |
41 | extern id0x91_t id0x91;
42 | extern id0x62_t id0x62;
43 |
44 | typedef enum
45 | {
46 | kItemID = 0x90, /* user programed ID */
47 | kItemAccRaw = 0xA0, /* raw acc */
48 | kItemGyrRaw = 0xB0, /* raw gyro */
49 | kItemGyrRaw_yunjing = 0xB1, /* raw gyro yunjing */
50 | kItemMagRaw = 0xC0, /* raw mag */
51 | kItemRotationEul = 0xD0, /* eular angle */
52 | kItemRotationQuat = 0xD1, /* att q */
53 | kItemPressure = 0xF0, /* pressure */
54 | kItemEnd = 0x00,
55 | KItemIMUSOL = 0x91, /* IMUSOL */
56 | KItemGWSOL = 0x62, /* RFSOL */
57 | }ItemID_t;
58 |
59 | int imu_data_decode_init(void);
60 |
61 | #endif
62 |
63 |
64 |
--------------------------------------------------------------------------------
/racecar/src/car_controller.hpp:
--------------------------------------------------------------------------------
1 | /********************/
2 | /* CLASS DEFINITION */
3 | /********************/
4 | class L1Controller
5 | {
6 | public:
7 | L1Controller();
8 | void initMarker();
9 | bool isForwardWayPt(const geometry_msgs::Point& wayPt, const geometry_msgs::Pose& carPose);
10 | bool isWayPtAwayFromLfwDist(const geometry_msgs::Point& wayPt, const geometry_msgs::Point& car_pos);
11 | double getYawFromPose(const geometry_msgs::Pose& carPose);
12 | double getEta(const geometry_msgs::Pose& carPose);
13 | double getCar2GoalDist();
14 | double getL1Distance(const double& _Vcmd);
15 | double getSteeringAngle(double eta);
16 | double getGasInput(const float& current_v);
17 | geometry_msgs::Point get_odom_car2WayPtVec(const geometry_msgs::Pose& carPose);
18 | void PID_init();
19 |
20 | private:
21 | struct PID *speed_pid;
22 | ros::NodeHandle n_;
23 | ros::Subscriber odom_sub, path_sub, goal_sub;
24 | ros::Publisher pub_, marker_pub;
25 | ros::Timer timer1, timer2;
26 | tf::TransformListener tf_listener;
27 |
28 | visualization_msgs::Marker points, line_strip, goal_circle;
29 | geometry_msgs::Twist cmd_vel;
30 | geometry_msgs::Point odom_goal_pos;
31 | nav_msgs::Odometry odom;
32 | nav_msgs::Path map_path, odom_path;
33 |
34 | double L, Lfw, Lrv, Vcmd, lfw, lrv, steering, u, v;
35 | double Gas_gain, baseAngle, Angle_gain, goalRadius;
36 | int controller_freq, baseSpeed;
37 | bool foundForwardPt, goal_received, goal_reached;
38 | int car_stop;
39 |
40 | void odomCB(const nav_msgs::Odometry::ConstPtr& odomMsg);
41 | void pathCB(const nav_msgs::Path::ConstPtr& pathMsg);
42 | void goalCB(const geometry_msgs::PoseStamped::ConstPtr& goalMsg);
43 | void goalReachingCB(const ros::TimerEvent&);
44 | void controlLoopCB(const ros::TimerEvent&);
45 |
46 |
47 |
48 | }; // end of class
49 |
50 |
--------------------------------------------------------------------------------
/multi_goal/src/getpoints.py:
--------------------------------------------------------------------------------
1 | #get the point and ore form rviz to txt
2 | #Type: geometry_msgs/PoseStamped /move_base_simple/goal
3 | #todo: change the count to the key "finish"
4 | #todo: not the cover the last csv
5 | import rospy
6 | import math
7 | import sys,select,termios,tty
8 | import tf
9 | import csv
10 | import codecs
11 | from geometry_msgs.msg import PoseStamped
12 |
13 | count = 0
14 | point=[]
15 | def PoseStampedCB(data):
16 | global count
17 | gx = data.pose.position.x
18 | gy = data.pose.position.y
19 | gz = data.pose.orientation.z
20 | gw = data.pose.orientation.w
21 | #count = count + 1
22 | point.append([gx,gy,gz,gw])
23 | if(count == 3):
24 | data_write_csv('test.csv',point)
25 | # with open('test.csv','wb') as csvfile:
26 | # pointwriter = csv.writer(csvfile,delimiter=' ',quotechar='|',quoting=csv.QUOTE_MINIMAL)
27 | # pointwriter.writerow([gx,gy,gz,gw])
28 | # print("write succ!!")
29 |
30 | def getKey():
31 | tty.setraw(sys.stdin.fileno())
32 | rlist,_,_ = select.select([sys.stdin],[],[],0.1)
33 | if rlist:
34 | key = sys.stdin.read(1)
35 | else:
36 | key = ''
37 | termios.tcsetattr(sys.stdin,termios.TCSADRAIN,settings)
38 | return key
39 |
40 | def data_write_csv(file_name, datas):
41 | file_csv = codecs.open(file_name,'w+','utf-8')
42 | writer = csv.writer(file_csv, delimiter=',', quoting=csv.QUOTE_MINIMAL)
43 | for data in datas:
44 | writer.writerow(data)
45 | print("write succ!!")
46 |
47 | if __name__ == '__main__':
48 | try:
49 | rospy.init_node("getPoint",anonymous=True)
50 | rospy.Subscriber('/move_base_simple/goal',PoseStamped,PoseStampedCB,queue_size=10)
51 | settings = termios.tcgetattr(sys.stdin)
52 | while(1):
53 | Key = getKey()
54 | if Key == 'f' or Key == 'F':
55 | data_write_csv('test.csv',point)
56 | if Key == '\x03':
57 | break
58 | rospy.spin()
59 | except rospy.ROSInterruptException:
60 | pass
61 |
--------------------------------------------------------------------------------
/imu_tool/README.md:
--------------------------------------------------------------------------------
1 | IMU tools for ROS
2 | ===================================
3 |
4 | Overview
5 | -----------------------------------
6 |
7 | IMU-related filters and visualizers. The stack contains:
8 |
9 | * `imu_filter_madgwick`: a filter which fuses angular velocities,
10 | accelerations, and (optionally) magnetic readings from a generic IMU
11 | device into an orientation. Based on the work of [1].
12 |
13 | * `imu_complementary_filter`: a filter which fuses angular velocities,
14 | accelerations, and (optionally) magnetic readings from a generic IMU
15 | device into an orientation quaternion using a novel approach based on a complementary fusion. Based on the work of [2].
16 |
17 | * `rviz_imu_plugin` a plugin for rviz which displays `sensor_msgs::Imu`
18 | messages
19 |
20 | Installing
21 | -----------------------------------
22 |
23 | ### From source ###
24 |
25 | [Create a catkin workspace](http://wiki.ros.org/catkin/Tutorials/create_a_workspace)
26 | (e.g., `~/ros-hydro-ws/`) and source the `devel/setup.bash` file.
27 |
28 | Make sure you have git installed:
29 |
30 | sudo apt-get install git-core
31 |
32 | Download the stack from our repository into your catkin workspace (e.g.,
33 | `ros-hydro-ws/src`; use the proper branch for your distro, e.g., `groovy`,
34 | `hydro`...):
35 |
36 | git clone -b https://github.com/ccny-ros-pkg/imu_tools.git
37 |
38 | Install any dependencies using [rosdep](http://www.ros.org/wiki/rosdep).
39 |
40 | rosdep install imu_tools
41 |
42 | Compile the stack:
43 |
44 | cd ~/ros-hydro-ws
45 | catkin_make
46 |
47 | More info
48 | -----------------------------------
49 |
50 | http://wiki.ros.org/imu_tools
51 |
52 | License
53 | -----------------------------------
54 |
55 | * `imu_filter_madgwick`: currently licensed as GPL, following the original implementation
56 |
57 | * `imu_complementary_filter`: BSD
58 |
59 | * `rviz_imu_plugin`: BSD
60 |
61 | References
62 | -----------------------------------
63 | [1] http://www.x-io.co.uk/open-source-imu-and-ahrs-algorithms/
64 |
65 | [2] http://www.mdpi.com/1424-8220/15/8/19302
66 |
--------------------------------------------------------------------------------
/imu_tool/imu_complementary_filter/src/complementary_filter_node.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | @author Roberto G. Valenti
3 |
4 | @section LICENSE
5 | Copyright (c) 2015, City University of New York
6 | CCNY Robotics Lab
7 | All rights reserved.
8 |
9 | Redistribution and use in source and binary forms, with or without
10 | modification, are permitted provided that the following conditions are met:
11 | 1. Redistributions of source code must retain the above copyright
12 | notice, this list of conditions and the following disclaimer.
13 | 2. Redistributions in binary form must reproduce the above copyright
14 | notice, this list of conditions and the following disclaimer in the
15 | documentation and/or other materials provided with the distribution.
16 | 3. Neither the name of the City College of New York nor the
17 | names of its contributors may be used to endorse or promote products
18 | derived from this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL the CCNY ROBOTICS LAB BE LIABLE FOR ANY
24 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 | */
31 |
32 | #include "imu_complementary_filter/complementary_filter_ros.h"
33 |
34 | int main (int argc, char **argv)
35 | {
36 | ros::init (argc, argv, "ComplementaryFilterROS");
37 | ros::NodeHandle nh;
38 | ros::NodeHandle nh_private("~");
39 | imu_tools::ComplementaryFilterROS filter(nh, nh_private);
40 | ros::spin();
41 | return 0;
42 | }
43 |
--------------------------------------------------------------------------------
/racecar/launch/amcl_nav_no_control.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/serial_imu/src/sub_0x91.cpp:
--------------------------------------------------------------------------------
1 | //subscriiber 0x91 data package
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include "imu_data_decode.h"
8 |
9 | void imu_0x91_callback(const serial_imu::Imu_0x91_msg imu_0x91_msg);
10 |
11 | int main(int argc,char **argv)
12 | {
13 | ros::init(argc,argv,"sub_0x91");
14 |
15 | ros::NodeHandle n;
16 |
17 | ros::Subscriber imu_0x91_sub = n.subscribe("/imu_0x91_package", 10, imu_0x91_callback);
18 |
19 | ros::spin();
20 | }
21 |
22 |
23 |
24 |
25 | void imu_0x91_callback(const serial_imu::Imu_0x91_msg imu_0x91_msg)
26 | {
27 | printf("\033c");
28 |
29 | if(imu_0x91_msg.imu_data.bitmap & BIT_VALID_ID)
30 | printf(" Devie ID:%6d\n",imu_0x91_msg.imu_data.id);
31 | if(imu_0x91_msg.imu_data.bitmap & BIT_VALID_PRS)
32 | printf(" Prs(hPa): %6f\n", imu_0x91_msg.imu_data.prs);
33 |
34 | if(imu_0x91_msg.imu_data.bitmap & BIT_VALID_TIME)
35 | printf(" Run times: %d days %d:%d:%d:%d\n",imu_0x91_msg.imu_data.time / 86400000, imu_0x91_msg.imu_data.time / 3600000 % 24, imu_0x91_msg.imu_data.time / 60000 % 60, imu_0x91_msg.imu_data.time / 1000 % 60, imu_0x91_msg.imu_data.time % 1000);
36 |
37 | printf(" Frame Rate: %4dHz\r\n", imu_0x91_msg.imu_data.frame_rate);
38 | if(imu_0x91_msg.imu_data.bitmap & BIT_VALID_ACC)
39 | printf(" Acc(G):%8.3f %8.3f %8.3f\r\n", imu_0x91_msg.imu_data.acc_x, imu_0x91_msg.imu_data.acc_y, imu_0x91_msg.imu_data.acc_z);
40 |
41 | if(imu_0x91_msg.imu_data.bitmap & BIT_VALID_GYR)
42 | printf(" Gyr(deg/s):%8.2f %8.2f %8.2f\r\n", imu_0x91_msg.imu_data.gyr_x, imu_0x91_msg.imu_data.gyr_y, imu_0x91_msg.imu_data.gyr_z);
43 |
44 | if(imu_0x91_msg.imu_data.bitmap & BIT_VALID_MAG)
45 | printf(" Mag(uT):%8.2f %8.2f %8.2f\r\n", imu_0x91_msg.imu_data.mag_x, imu_0x91_msg.imu_data.mag_y, imu_0x91_msg.imu_data.mag_z);
46 |
47 | if(imu_0x91_msg.imu_data.bitmap & BIT_VALID_EUL)
48 | printf(" Eul(R P Y):%8.2f %8.2f %8.2f\r\n", imu_0x91_msg.imu_data.eul_r, imu_0x91_msg.imu_data.eul_p, imu_0x91_msg.imu_data.eul_y);
49 |
50 | if(imu_0x91_msg.imu_data.bitmap & BIT_VALID_QUAT)
51 | printf("Quat(W X Y Z):%8.3f %8.3f %8.3f %8.3f\r\n", imu_0x91_msg.imu_data.quat_w, imu_0x91_msg.imu_data.quat_x, imu_0x91_msg.imu_data.quat_y, imu_0x91_msg.imu_data.quat_z);
52 | }
53 |
--------------------------------------------------------------------------------
/racecar/launch/Run_gmapping.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/racecar/src/ESC_calibration.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import rospy
4 |
5 | from geometry_msgs.msg import Twist
6 |
7 | import sys, select, termios, tty
8 | import time
9 |
10 | msg = ""
11 |
12 |
13 | def getKey():
14 | tty.setraw(sys.stdin.fileno())
15 | rlist, _, _ = select.select([sys.stdin], [], [], 0.1)
16 | if rlist:
17 | key = sys.stdin.read(1)
18 | else:
19 | key = ''
20 |
21 | termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
22 | return key
23 |
24 |
25 | def vels(speed,turn):
26 | return "currently:\tspeed %s\tturn %s " % (speed,turn)
27 |
28 | if __name__=="__main__":
29 | settings = termios.tcgetattr(sys.stdin)
30 |
31 | rospy.init_node('racecar_teleop')
32 | pub = rospy.Publisher('~/car/cmd_vel', Twist, queue_size=5)
33 |
34 |
35 | run = 0
36 |
37 | try:
38 | while(1):
39 | key = getKey()
40 | twist = Twist()
41 | if key == '1':
42 | twist.linear.x = 1500; twist.linear.y = 0;
43 | twist.linear.z = 0
44 | twist.angular.x = 0;
45 | twist.angular.y = 0;
46 | twist.angular.z = 90
47 | print ("vel = 0")
48 | elif key == '2':
49 | twist.linear.x = 2500; twist.linear.y = 0; twist.linear.z = 0;
50 | twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = 90;
51 | print ("vel = +Max")
52 | elif key == '3':
53 | twist.linear.x = 500; twist.linear.y = 0; twist.linear.z = 0;
54 | twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = 90;
55 | print ("vel = -Max")
56 | else:
57 | twist.linear.x = 1500; twist.linear.y = 0; twist.linear.z = 0;
58 | twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = 90;
59 | print ("stop")
60 |
61 | pub.publish(twist)
62 |
63 |
64 |
65 | if (key == '\x03'): #for ctrl + c exit
66 | break
67 |
68 | except:
69 | print ("error")
70 |
71 | finally:
72 | twist = Twist()
73 | twist.linear.x = speed_mid; twist.linear.y = 0; twist.linear.z = 0
74 | twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = turn_mid
75 | pub.publish(twist)
76 |
77 | termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
78 |
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | cmake_policy(SET CMP0048 NEW)
3 | project(rviz_imu_plugin)
4 |
5 | find_package(catkin REQUIRED COMPONENTS rviz)
6 |
7 | ## This setting causes Qt's "MOC" generation to happen automatically.
8 | set(CMAKE_AUTOMOC ON)
9 |
10 | ## This plugin includes Qt widgets, so we must include Qt.
11 | ## We'll use the version that rviz used so they are compatible.
12 | if(rviz_QT_VERSION VERSION_LESS "5")
13 | message(STATUS "Using Qt4 based on the rviz_QT_VERSION: ${rviz_QT_VERSION}")
14 | find_package(Qt4 COMPONENTS QtCore QtGui REQUIRED)
15 | include(${QT_USE_FILE})
16 | else()
17 | message(STATUS "Using Qt5 based on the rviz_QT_VERSION: ${rviz_QT_VERSION}")
18 | find_package(Qt5Widgets REQUIRED)
19 | find_package(Qt5Core REQUIRED)
20 | find_package(Qt5OpenGL REQUIRED)
21 | ## Set the QT_LIBRARIES variable for Qt5, so it can be used below.
22 | set(QT_LIBRARIES Qt5::Widgets)
23 | endif()
24 |
25 | ## I prefer the Qt signals and slots to avoid defining "emit", "slots",
26 | ## etc because they can conflict with boost signals, so define QT_NO_KEYWORDS here.
27 | add_definitions(-DQT_NO_KEYWORDS)
28 |
29 | catkin_package(
30 | DEPENDS
31 | CATKIN_DEPENDS rviz
32 | INCLUDE_DIRS
33 | LIBRARIES
34 | )
35 |
36 | include_directories(
37 | include
38 | ${catkin_INCLUDE_DIRS}
39 | )
40 |
41 | ## Here we specify the list of source files.
42 | ## The generated MOC files are included automatically as headers.
43 | set(SRC_FILES src/imu_display.cpp
44 | src/imu_orientation_visual.cpp
45 | src/imu_axes_visual.cpp
46 | src/imu_acc_visual.cpp)
47 |
48 | ## Build libraries
49 | add_library(${PROJECT_NAME} ${SRC_FILES})
50 |
51 | set_target_properties(${PROJECT_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
52 |
53 | ## Link the library with whatever Qt libraries have been defined by
54 | ## the ``find_package(Qt4 ...)`` line above, or by the
55 | ## ``set(QT_LIBRARIES Qt5::Widgets)``, and with whatever libraries
56 | ## catkin has included.
57 | target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${catkin_LIBRARIES})
58 |
59 | install(TARGETS
60 | ${PROJECT_NAME}
61 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
62 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
63 | RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
64 | )
65 |
66 | install(FILES plugin_description.xml
67 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
68 |
--------------------------------------------------------------------------------
/racecar/launch/includes/default_mapping.launch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.5.1)
2 | cmake_policy(SET CMP0048 NEW)
3 | project(imu_filter_madgwick)
4 |
5 | find_package(catkin REQUIRED COMPONENTS roscpp sensor_msgs geometry_msgs tf2 tf2_geometry_msgs tf2_ros nodelet pluginlib message_filters dynamic_reconfigure)
6 |
7 | find_package(Boost REQUIRED COMPONENTS system thread)
8 |
9 | # Generate dynamic parameters
10 | generate_dynamic_reconfigure_options(cfg/ImuFilterMadgwick.cfg)
11 |
12 |
13 | catkin_package(
14 | DEPENDS Boost
15 | CATKIN_DEPENDS roscpp sensor_msgs geometry_msgs tf2_ros tf2_geometry_msgs nodelet pluginlib message_filters dynamic_reconfigure
16 | INCLUDE_DIRS
17 | LIBRARIES imu_filter imu_filter_nodelet
18 | )
19 |
20 | include_directories(
21 | include
22 | ${catkin_INCLUDE_DIRS}
23 | ${Boost_INCLUDE_DIRS}
24 | )
25 |
26 |
27 | # create imu_filter library
28 | add_library (imu_filter src/imu_filter.cpp src/imu_filter_ros.cpp src/stateless_orientation.cpp)
29 | add_dependencies(imu_filter ${PROJECT_NAME}_gencfg)
30 | target_link_libraries(imu_filter ${catkin_LIBRARIES} ${Boost_LIBRARIES})
31 |
32 | # create imu_filter_nodelet library
33 | add_library (imu_filter_nodelet src/imu_filter_nodelet.cpp)
34 | add_dependencies(imu_filter_nodelet ${PROJECT_NAME}_gencfg)
35 | target_link_libraries(imu_filter_nodelet imu_filter ${catkin_LIBRARIES} ${Boost_LIBRARIES})
36 |
37 | # create imu_filter_node executable
38 | add_executable(imu_filter_node src/imu_filter_node.cpp)
39 | add_dependencies(imu_filter_node ${PROJECT_NAME}_gencfg)
40 | target_link_libraries(imu_filter_node imu_filter ${catkin_LIBRARIES} ${Boost_LIBRARIES})
41 |
42 |
43 | install(TARGETS imu_filter_node
44 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
45 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
46 | RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
47 | )
48 |
49 | install(TARGETS imu_filter imu_filter_nodelet
50 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
51 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
52 | RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
53 | )
54 |
55 | install(DIRECTORY include/${PROJECT_NAME}/
56 | DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
57 | FILES_MATCHING PATTERN "*.h"
58 | )
59 |
60 | install(FILES imu_filter_nodelet.xml
61 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
62 | )
63 |
64 |
65 |
66 | if(CATKIN_ENABLE_TESTING)
67 | catkin_add_gtest(${PROJECT_NAME}-madgwick_test
68 | test/stateless_orientation_test.cpp
69 | test/madgwick_test.cpp
70 | )
71 | target_link_libraries(${PROJECT_NAME}-madgwick_test
72 | imu_filter
73 | ${catkin_LIBRARIES}
74 | )
75 | endif()
76 |
--------------------------------------------------------------------------------
/racecar/launch/includes/amcl.launch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/imu_launch/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | imu_launch
4 | 0.0.0
5 | The imu_launch package
6 |
7 |
8 |
9 |
10 | linux
11 |
12 |
13 |
14 |
15 |
16 | TODO
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | catkin
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/CHANGELOG.rst:
--------------------------------------------------------------------------------
1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 | Changelog for package rviz_imu_plugin
3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 |
5 | 1.1.8 (2020-05-25)
6 | ------------------
7 | * Export symbols so plugin can load
8 | * properly show/hide visualization when enabled/disabled
9 | * Contributors: Lou Amadio, v4hn
10 |
11 | 1.1.7 (2019-05-06)
12 | ------------------
13 | * Fix includes, typos and log messages
14 | * print ros_warn and give unit quaternion to ogre to prevent rviz crash (`#90 `_)
15 | * Contributors: Jackey-Huo, Martin Günther
16 |
17 | 1.1.6 (2018-05-25)
18 | ------------------
19 |
20 | 1.1.4 (2017-05-22)
21 | ------------------
22 | * Add option to display orientation in world frame (`#69 `_)
23 | Per REP 145 IMU orientation is in the world frame. Rotating the
24 | orientation data to transform into the sensor frame results in strange
25 | behavior, such as double-rotation of orientation on a robot. Provide an
26 | option to display orientation in the world frame, and enable it by
27 | default. Continue to translate the position of the data to the sensor
28 | frame.
29 | * Contributors: C. Andy Martin
30 |
31 | 1.1.3 (2017-03-10)
32 | ------------------
33 |
34 | 1.1.2 (2016-09-07)
35 | ------------------
36 |
37 | 1.1.1 (2016-09-07)
38 | ------------------
39 |
40 | 1.1.0 (2016-04-25)
41 | ------------------
42 | * Add qt5 dependencies to rviz_imu_plugin package.xml
43 | This fixes the compilation errors on Kinetic for Debian Jessie.
44 | * Contributors: Martin Guenther
45 |
46 | 1.0.11 (2016-04-22)
47 | -------------------
48 |
49 | 1.0.10 (2016-04-22)
50 | -------------------
51 | * Support qt4/qt5 using rviz's exported qt version
52 | Closes `#58 `_ .
53 | This fixes the build on Kinetic, where only Qt5 is available, and
54 | is backwards compatible with Qt4 for Indigo.
55 | * Contributors: Martin Guenther
56 |
57 | 1.0.9 (2015-10-16)
58 | ------------------
59 |
60 | 1.0.8 (2015-10-07)
61 | ------------------
62 |
63 | 1.0.7 (2015-10-07)
64 | ------------------
65 |
66 | 1.0.6 (2015-10-06)
67 | ------------------
68 |
69 | 1.0.5 (2015-06-24)
70 | ------------------
71 |
72 | 1.0.4 (2015-05-06)
73 | ------------------
74 |
75 | 1.0.3 (2015-01-29)
76 | ------------------
77 |
78 | 1.0.2 (2015-01-27)
79 | ------------------
80 |
81 | 1.0.1 (2014-12-10)
82 | ------------------
83 | * add me as maintainer to package.xml
84 | * Contributors: Martin Günther
85 |
86 | 1.0.0 (2014-09-03)
87 | ------------------
88 | * First public release
89 | * Contributors: Ivan Dryanovski, Martin Günther, Davide Tateo, Francisco Vina, Lorenzo Riano
90 |
--------------------------------------------------------------------------------
/imu_tool/imu_complementary_filter/CHANGELOG.rst:
--------------------------------------------------------------------------------
1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 | Changelog for package imu_complementary_filter
3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 |
5 | 1.1.8 (2020-05-25)
6 | ------------------
7 | * fix install path & boost linkage issues
8 | * Contributors: Sean Yen
9 |
10 | 1.1.7 (2019-05-06)
11 | ------------------
12 | * Remove junk xml (`#93 `_)
13 | * Fix C++14 builds (`#89 `_)
14 | * Contributors: David V. Lu!!, Paul Bovbel
15 |
16 | 1.1.6 (2018-05-25)
17 | ------------------
18 | * Add std dev parameter to orientation estimate from filter (`#85 `_)
19 | Similar to `#41 `_, but not using dynamic_reconfigure as not implemented for complementary filter
20 | * Contributors: Stefan Kohlbrecher
21 |
22 | 1.1.4 (2017-05-22)
23 | ------------------
24 |
25 | 1.1.3 (2017-03-10)
26 | ------------------
27 | * complementary_filter: move const initializations out of header
28 | Initialization of static consts other than int (here: float) inside the
29 | class declaration is not permitted in C++. It works in gcc (due to a
30 | non-standard extension), but throws an error in C++11.
31 | * Contributors: Martin Guenther
32 |
33 | 1.1.2 (2016-09-07)
34 | ------------------
35 |
36 | 1.1.1 (2016-09-07)
37 | ------------------
38 |
39 | 1.1.0 (2016-04-25)
40 | ------------------
41 |
42 | 1.0.11 (2016-04-22)
43 | -------------------
44 |
45 | 1.0.10 (2016-04-22)
46 | -------------------
47 | * Remove Eigen dependency
48 | Eigen is not actually used anywhere. Thanks @asimay!
49 | * Removed main function from shared library
50 | * Contributors: Martin Guenther, Matthias Nieuwenhuisen
51 |
52 | 1.0.9 (2015-10-16)
53 | ------------------
54 | * complementary: Add Eigen dependency
55 | Fixes `#54 `_.
56 | * Contributors: Martin Günther
57 |
58 | 1.0.8 (2015-10-07)
59 | ------------------
60 |
61 | 1.0.7 (2015-10-07)
62 | ------------------
63 | * Allow remapping imu namespace
64 | * Publish RPY as Vector3Stamped
65 | * Add params: constant_dt, publish_tf, reverse_tf, publish_debug_topics
66 | * Use MagneticField instead of Vector3
67 | * Contributors: Martin Günther
68 |
69 | 1.0.6 (2015-10-06)
70 | ------------------
71 | * Add new package: imu_complementary_filter
72 | * Contributors: Roberto G. Valentini, Martin Günther, Michael Görner
73 |
74 | 1.0.5 (2015-06-24)
75 | ------------------
76 |
77 | 1.0.4 (2015-05-06)
78 | ------------------
79 |
80 | 1.0.3 (2015-01-29)
81 | ------------------
82 |
83 | 1.0.2 (2015-01-27)
84 | ------------------
85 |
86 | 1.0.1 (2014-12-10)
87 | ------------------
88 |
89 | 1.0.0 (2014-11-28)
90 | ------------------
91 |
--------------------------------------------------------------------------------
/racecar/launch/amcl_nav.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/racecar_driver/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | racecar_driver
4 | 0.1.0
5 | The racecar_driver package
6 |
7 |
8 |
9 |
10 | ***
11 |
12 |
13 |
14 |
15 |
16 | TODO
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | catkin
51 | roscpp
52 | rospy
53 | std_msgs
54 | roscpp
55 | rospy
56 | std_msgs
57 | roscpp
58 | rospy
59 | std_msgs
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/racecar/launch/amcl_nav copy.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/encoder_driver/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | encoder_driver
4 | 0.0.0
5 | The encoder_driver package
6 |
7 |
8 |
9 |
10 | hzx
11 |
12 |
13 |
14 |
15 |
16 | TODO
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | catkin
52 | serial
53 | serial
54 | geometry_msgs
55 | geometry_msgs
56 | tf
57 | tf
58 | roscpp
59 | rospy
60 | std_msgs
61 | roscpp
62 | rospy
63 | std_msgs
64 | roscpp
65 | rospy
66 | std_msgs
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/serial_imu/src/imu_data_decode.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "packet.h"
5 | #include "imu_data_decode.h"
6 |
7 | static packet_t RxPkt; /* used for data receive */
8 | /*
9 | **采用结构体来保存数据
10 | **将标志位都集中到一个32位的变量上,用位来表示
11 | **在复制数据时,在用户程序中直接调用一个memcpy函数
12 | */
13 |
14 | uint8_t bitmap;
15 | id0x91_t id0x91; /* HI226 HI229 CH100 CH110 HI221 protocol packet */
16 | id0x62_t id0x62; /* HI221 Dongle protocol packet */
17 |
18 | static int stream2int16(int *dest,uint8_t *src)
19 | {
20 | dest[0] = (int16_t)(src[0] | src[1] << 8);
21 | dest[1] = (int16_t)(src[2] | src[3] << 8);
22 | dest[2] = (int16_t)(src[4] | src[5] << 8);
23 | return 0;
24 | }
25 |
26 |
27 | /* callback function of when recv a data frame successfully */
28 | static void on_data_received(packet_t *pkt)
29 | {
30 | int temp[3] = {0};
31 | int offset = 0;
32 | uint8_t *p = pkt->buf;
33 |
34 | if(pkt->type != 0xA5)
35 | {
36 | return;
37 | }
38 |
39 | bitmap = 0;
40 | while(offset < pkt->payload_len)
41 | {
42 | switch(p[offset])
43 | {
44 | case kItemID:
45 | bitmap |= BIT_VALID_ID;
46 | id0x91.id = p[1];
47 | offset += 2;
48 | break;
49 |
50 | case kItemAccRaw:
51 | bitmap |= BIT_VALID_ACC;
52 | stream2int16(temp, p + offset + 1);
53 | id0x91.acc[0] = (float)temp[0] / 1000;
54 | id0x91.acc[1] = (float)temp[1] / 1000;
55 | id0x91.acc[2] = (float)temp[2] / 1000;
56 | offset += 7;
57 | break;
58 |
59 | case kItemGyrRaw:
60 | case kItemGyrRaw_yunjing:
61 | bitmap |= BIT_VALID_GYR;
62 | stream2int16(temp, p + offset + 1);
63 | id0x91.gyr[0] = (float)temp[0] / 10;
64 | id0x91.gyr[1] = (float)temp[1] / 10;
65 | id0x91.gyr[2] = (float)temp[2] / 10;
66 | offset += 7;
67 | break;
68 |
69 | case kItemMagRaw:
70 | bitmap |= BIT_VALID_MAG;
71 | stream2int16(temp, p + offset + 1);
72 | id0x91.mag[0] = (float)temp[0] / 10;
73 | id0x91.mag[1] = (float)temp[1] / 10;
74 | id0x91.mag[2] = (float)temp[2] / 10;
75 | offset += 7;
76 | break;
77 |
78 | case kItemRotationEul:
79 | bitmap |= BIT_VALID_EUL;
80 | stream2int16(temp, p + offset + 1);
81 | id0x91.eul[1] = (float)temp[0] / 100;
82 | id0x91.eul[0] = (float)temp[1] / 100;
83 | id0x91.eul[2] = (float)temp[2] / 10;
84 | offset += 7;
85 | break;
86 |
87 | case kItemRotationQuat:
88 | bitmap |= BIT_VALID_QUAT;
89 | memcpy(id0x91.quat, p + offset + 1, sizeof( id0x91.quat));
90 | offset += 17;
91 | break;
92 |
93 | case kItemPressure:
94 | offset += 5;
95 | break;
96 |
97 | case KItemIMUSOL:
98 | bitmap = BIT_VALID_ALL;
99 | memcpy((void *)&id0x91, p, sizeof(id0x91_t));
100 | offset += sizeof(id0x91_t);
101 | break;
102 |
103 | case KItemGWSOL:
104 | memcpy((void *)&id0x62, p, 8);
105 | offset += 8;
106 | for (int i = 0; i < id0x62.n; i++)
107 | {
108 | bitmap = BIT_VALID_ALL;
109 | bitmap &= ~BIT_VALID_TIME;
110 | memcpy((void *)&id0x62.id0x91[i], p + offset, sizeof(id0x91_t));
111 |
112 | offset += sizeof(id0x91_t);
113 | }
114 | break;
115 |
116 | default:
117 | /* offset ==> 0 2 9 16 23 30 47 52 76 */
118 | offset++;
119 | }
120 | }
121 | }
122 |
123 |
124 | int imu_data_decode_init(void)
125 | {
126 | packet_decode_init(&RxPkt, on_data_received);
127 | return 0;
128 | }
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/include/imu_filter_madgwick/imu_filter.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010, CCNY Robotics Lab
3 | * Ivan Dryanovski
4 | *
5 | * http://robotics.ccny.cuny.edu
6 | *
7 | * Based on implementation of Madgwick's IMU and AHRS algorithms.
8 | * http://www.x-io.co.uk/node/8#open_source_ahrs_and_imu_algorithms
9 | *
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef IMU_FILTER_MADWICK_IMU_FILTER_H
26 | #define IMU_FILTER_MADWICK_IMU_FILTER_H
27 |
28 | #include
29 | #include
30 | #include
31 |
32 | class ImuFilter
33 | {
34 | public:
35 |
36 | ImuFilter();
37 | virtual ~ImuFilter();
38 |
39 | private:
40 | // **** paramaters
41 | double gain_; // algorithm gain
42 | double zeta_; // gyro drift bias gain
43 | WorldFrame::WorldFrame world_frame_; // NWU, ENU, NED
44 |
45 | // **** state variables
46 | double q0, q1, q2, q3; // quaternion
47 | float w_bx_, w_by_, w_bz_; //
48 |
49 | public:
50 | void setAlgorithmGain(double gain)
51 | {
52 | gain_ = gain;
53 | }
54 |
55 | void setDriftBiasGain(double zeta)
56 | {
57 | zeta_ = zeta;
58 | }
59 |
60 | void setWorldFrame(WorldFrame::WorldFrame frame)
61 | {
62 | world_frame_ = frame;
63 | }
64 |
65 | void getOrientation(double& q0, double& q1, double& q2, double& q3)
66 | {
67 | q0 = this->q0;
68 | q1 = this->q1;
69 | q2 = this->q2;
70 | q3 = this->q3;
71 |
72 | // perform precise normalization of the output, using 1/sqrt()
73 | // instead of the fast invSqrt() approximation. Without this,
74 | // TF2 complains that the quaternion is not normalized.
75 | double recipNorm = 1 / sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
76 | q0 *= recipNorm;
77 | q1 *= recipNorm;
78 | q2 *= recipNorm;
79 | q3 *= recipNorm;
80 | }
81 |
82 | void setOrientation(double q0, double q1, double q2, double q3)
83 | {
84 | this->q0 = q0;
85 | this->q1 = q1;
86 | this->q2 = q2;
87 | this->q3 = q3;
88 |
89 | w_bx_ = 0;
90 | w_by_ = 0;
91 | w_bz_ = 0;
92 | }
93 |
94 | void madgwickAHRSupdate(float gx, float gy, float gz,
95 | float ax, float ay, float az,
96 | float mx, float my, float mz,
97 | float dt);
98 |
99 | void madgwickAHRSupdateIMU(float gx, float gy, float gz,
100 | float ax, float ay, float az,
101 | float dt);
102 |
103 | void getGravity(float& rx, float& ry, float& rz,
104 | float gravity = 9.80665);
105 | };
106 |
107 | #endif // IMU_FILTER_IMU_MADWICK_FILTER_H
108 |
--------------------------------------------------------------------------------
/racecar/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | racecar
4 | 0.1.0
5 | The racecar package
6 |
7 |
8 |
9 |
10 | ***
11 |
12 |
13 |
14 |
15 |
16 | TODO
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | catkin
52 | geometry_msgs
53 | joy
54 | move_base
55 | roscpp
56 | rospy
57 | std_msgs
58 | visualization_msgs
59 | tf
60 | sensor_msgs
61 | python-serial
62 | dynamic_reconfigure
63 |
64 |
65 | geometry_msgs
66 | move_base
67 | joy
68 | roscpp
69 | rospy
70 | std_msgs
71 | visualization_msgs
72 | tf
73 | tf
74 | sensor_msgs
75 | python-serial
76 | dynamic_reconfigure
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/serial_imu/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | serial_imu
4 | 0.0.0
5 | The serial_imu package
6 |
7 |
8 |
9 |
10 | linux
11 |
12 |
13 |
14 |
15 |
16 | TODO
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | catkin
52 | geometry_msgs
53 | roscpp
54 | rospy
55 | serial
56 | std_msgs
57 | turtlesim
58 | geometry_msgs
59 | roscpp
60 | rospy
61 | serial
62 | std_msgs
63 | turtlesim
64 | geometry_msgs
65 | roscpp
66 | rospy
67 | serial
68 | std_msgs
69 | turtlesim
70 |
71 | http://ros.org/wiki/sensor_mags
72 |
73 |
74 | message_generation
75 | message_runtime
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/encoder_driver/src/Encoder_vel.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | #coding:UTF-8
3 |
4 | import rospy
5 | from rospy.timer import Rate
6 | import serial
7 | import time
8 |
9 | from nav_msgs.msg import Odometry
10 |
11 |
12 |
13 | Bytenum_vel = 0 #读取到这一段的第几位
14 | Bytenum_dir = 0
15 | last_pose = 0
16 | C = 227.45/1000
17 |
18 |
19 | def DueVelData(inputdata): #新增的核心程序,对读取的数据进行划分,各自读到对应的数组里
20 | #在局部修改全局变量,要进行global的定义
21 | global Bytenum_vel
22 |
23 | for data in inputdata: #在输入的数据进行遍历 'ex:01 03 04 02 7A (D8 C6)'
24 | # print(data)
25 | if data==0x01 and Bytenum_vel==0:
26 | Bytenum_vel = 1
27 | continue
28 | if data==0x03 and Bytenum_vel==1:
29 | Bytenum_vel = 2
30 | continue
31 | if data==0x02 and Bytenum_vel==2:
32 | Bytenum_vel = 3
33 | continue
34 | if Bytenum_vel==3:
35 | data_high = data
36 | Bytenum_vel = 4
37 | continue
38 | if Bytenum_vel==4:
39 | data_low = data
40 | Bytenum_vel = 0
41 | Angle_vel= data_high * 256 + data_low
42 | return float(Angle_vel)
43 |
44 | def DueDirData(inputdata): #新增的核心程序,对读取的数据进行划分,各自读到对应的数组里
45 | #在局部修改全局变量,要进行global的定义
46 | global Bytenum_dir
47 | global last_pose
48 |
49 | for data in inputdata: #在输入的数据进行遍历 'ex:01 03 02 01 42 (39 E5)'
50 | # print(data)
51 | if data==0x01 and Bytenum_dir==0:
52 | Bytenum_dir = 1
53 | continue
54 | if data==0x03 and Bytenum_dir==1:
55 | Bytenum_dir = 2
56 | continue
57 | if data==0x02 and Bytenum_dir==2:
58 | Bytenum_dir = 3
59 | continue
60 | if Bytenum_dir==3:
61 | data_high = data
62 | Bytenum_dir = 4
63 | continue
64 | if Bytenum_dir==4:
65 | data_low = data
66 | Bytenum_dir = 0
67 | position = data_high * 256 + data_low
68 | pose = position - last_pose
69 | last_pose = position
70 |
71 | if (pose>=0 and pose<512) or (pose> -1024 and pose< -512):
72 | direction = 1
73 | elif (pose<0 and pose> -512) or (pose < 1024 and pose > 512):
74 | direction = -1
75 |
76 | return int(direction)
77 |
78 | def init_topic():
79 |
80 |
81 | return 0
82 |
83 |
84 | if __name__=='__main__':
85 | rospy.init_node('encoder_vel', log_level=rospy.DEBUG)
86 | pub = rospy.Publisher('encoder', Odometry, queue_size=10)
87 |
88 | port = rospy.get_param('~serial_port', '/dev/ttyUSB0')
89 | baud = rospy.get_param('~baud_rate', 57600) # about 100hz
90 | k = rospy.get_param('~k',1) # fix param
91 |
92 | ser = serial.Serial(port, baud)
93 | print(ser.is_open)
94 |
95 | while( not rospy.is_shutdown()):
96 | # time1 = time.time()
97 | send_data = bytes.fromhex('01 03 00 03 00 01 74 0A') # read velocity value in 20ms
98 | ser.write(send_data)
99 | datahex = ser.read(7)
100 | angle_v = DueVelData(datahex)
101 |
102 | send_data = bytes.fromhex('01 03 00 00 00 01 84 0A') #
103 | ser.write(send_data)
104 | datahex = ser.read(7)
105 | dir = DueDirData(datahex)
106 |
107 | Vel = angle_v * dir * C / 1024.0 / 0.02 * k
108 | # print(Vel)
109 | # time2 = time.time()
110 | # print(1/(time2-time1))
111 |
112 | pub_vel = Odometry()
113 | pub_vel.header.frame_id = 'odom'
114 | pub_vel.child_frame_id = 'base_footprint'
115 | pub_vel.header.stamp = rospy.Time.now()
116 | pub_vel.twist.twist.linear.x = Vel
117 | pub.publish(pub_vel)
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/src/imu_axes_visual.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012, Willow Garage, Inc.
3 | * Copyright (c) 2012, Ivan Dryanovski
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the Willow Garage, Inc. nor the names of its
15 | * contributors may be used to endorse or promote products derived from
16 | * this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 | * POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #ifndef RVIZ_IMU_PLUGIN_IMU_AXES_VISUAL_H
32 | #define RVIZ_IMU_PLUGIN_IMU_AXES_VISUAL_H
33 |
34 | #include
35 | #include
36 | #include
37 | #include
38 |
39 | namespace rviz
40 | {
41 |
42 | class Axes;
43 |
44 | class ImuAxesVisual
45 | {
46 | public:
47 | // Constructor. Creates the visual stuff and puts it into the
48 | // scene, but in an unconfigured state.
49 | ImuAxesVisual(Ogre::SceneManager * scene_manager, Ogre::SceneNode * parent_node);
50 |
51 | // Destructor. Removes the visual stuff from the scene.
52 | virtual ~ImuAxesVisual();
53 |
54 | // Configure the visual to show the data in the message.
55 | void setMessage(const sensor_msgs::Imu::ConstPtr& msg);
56 |
57 | // Set the pose of the coordinate frame the message refers to.
58 | // These could be done inside setMessage(), but that would require
59 | // calls to FrameManager and error handling inside setMessage(),
60 | // which doesn't seem as clean. This way ImuVisual is only
61 | // responsible for visualization.
62 | void setFramePosition(const Ogre::Vector3& position);
63 | void setFrameOrientation(const Ogre::Quaternion& orientation);
64 |
65 | // Set the color and alpha of the visual, which are user-editable
66 |
67 | void setScale(float scale);
68 |
69 | float getScale() { return scale_; }
70 |
71 | void show();
72 | void hide();
73 |
74 | private:
75 |
76 | void create();
77 | inline bool checkQuaternionValidity(
78 | const sensor_msgs::Imu::ConstPtr& msg);
79 |
80 | Ogre::Quaternion orientation_;
81 |
82 | float scale_;
83 | bool quat_valid_;
84 |
85 | Axes * orientation_axes_;
86 |
87 | // A SceneNode whose pose is set to match the coordinate frame of
88 | // the Imu message header.
89 | Ogre::SceneNode * frame_node_;
90 |
91 | // The SceneManager, kept here only so the destructor can ask it to
92 | // destroy the ``frame_node_``.
93 | Ogre::SceneManager * scene_manager_;
94 | };
95 |
96 | } // end namespace rviz
97 |
98 | #endif // RVIZ_IMU_PLUGIN_IMU_AXES_VISUAL_H
99 |
--------------------------------------------------------------------------------
/racecar/src/racecar_joy.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import rospy
4 |
5 | from geometry_msgs.msg import Twist
6 | from sensor_msgs.msg import Joy
7 |
8 | import sys, select, termios, tty
9 | import time
10 |
11 | msg = """
12 |
13 | CTRL-C to quit
14 | """
15 | global run
16 | global speed_add_once,turn_add_once,speed_mid,turn_mid,control_speed,control_turn,speed_max,turn_max,speed_min,turn_min
17 | global last_turn_add_once
18 |
19 |
20 |
21 | def callback(data):
22 | global last_speed_add_once
23 | twist = Twist()
24 | car_twist = Twist()
25 | global speed_add_once,turn_add_once
26 | global last_turn_add_once,last_speed_add_once
27 | if (data.buttons[6] == 1 or data.buttons[7] == 1):
28 | twist.linear.x = 0
29 | twist.angular.z = 0
30 | print("STOP!!")
31 | else:
32 | if(data.axes[5] != 0):
33 | if(last_speed_add_once == 0):
34 | speed_add_once = speed_add_once + data.axes[5] * 0.1
35 | last_speed_add_once = 1
36 | else:
37 | last_speed_add_once = 0
38 | if(data.axes[4] != 0):
39 | if(last_turn_add_once == 0):
40 | turn_add_once = turn_add_once + data.axes[4] * 0.1
41 | last_turn_add_once = 1
42 | else:
43 | last_turn_add_once = 0
44 | if(speed_add_once > 1):
45 | speed_add_once = 1
46 | elif(speed_add_once < -1):
47 | speed_add_once = -1
48 | if(turn_add_once > 1):
49 | turn_add_once = 1
50 | elif(turn_add_once < -1):
51 | turn_add_once = -1
52 | twist.linear.x = data.axes[1] * speed_add_once
53 | twist.angular.z = data.axes[3] * turn_add_once
54 | control_speed = (data.axes[1] * (speed_max - speed_min) * speed_add_once / 2 + speed_mid)
55 | if(control_speed > 1500):
56 | control_speed = control_speed + 350
57 | elif(control_speed < 1500):
58 | control_speed = control_speed - 50
59 | control_turn = (data.axes[3] * (turn_max - turn_min) * turn_add_once / 2 + turn_mid)
60 | # print('speed: %.2f, turn: %.2f'%(twist.linear.x,twist.angular.z))
61 | car_twist.linear.x = control_speed
62 | car_twist.angular.z = control_turn
63 | print('speed: %.2f, turn: %.2f'%(control_speed,control_turn))
64 | pub.publish(twist)
65 | pub_car.publish(car_twist)
66 |
67 |
68 |
69 | def vels(speed,turn):
70 | return "currently:\tspeed %s\tturn %s " % (speed,turn)
71 |
72 |
73 | def getKey():
74 | tty.setraw(sys.stdin.fileno())
75 | rlist, _, _ = select.select([sys.stdin], [], [], 0.1)
76 | if rlist:
77 | key = sys.stdin.read(1)
78 | else:
79 | key = ''
80 |
81 | termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
82 | return key
83 |
84 |
85 | if __name__=="__main__":
86 |
87 | settings = termios.tcgetattr(sys.stdin)
88 | speed_add_once = 0.25
89 | turn_add_once = 0.5
90 | speed_max = 1900
91 | speed_min = 1400
92 | speed_mid = 1500
93 | turn_max = 180
94 | turn_min = 0
95 | turn_mid = (turn_max + turn_min)/2
96 |
97 | control_speed = speed_mid
98 | control_turn = turn_mid
99 |
100 | global pub
101 | rospy.init_node('racecar_joy')
102 | pub = rospy.Publisher('~/cmd_vel', Twist, queue_size=5)
103 | pub_car = rospy.Publisher('~/car/cmd_vel', Twist, queue_size=5)
104 | try:
105 |
106 | while(1):
107 |
108 | key = getKey()
109 |
110 | rospy.Subscriber("joy", Joy, callback)
111 |
112 | rospy.spin()
113 |
114 | if (key == '\x03'): #for ctrl + c exit
115 | break
116 |
117 |
118 | except:
119 | print("error")
120 |
121 | finally:
122 | print("finally")
123 | twist = Twist()
124 | car_twist = Twist()
125 | twist.linear.x = 0; twist.linear.y = 0; twist.linear.z = 0
126 | twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = 0
127 | pub.publish(twist)
128 | pub_car.publish(car_twist)
129 |
130 | termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
131 |
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/src/imu_acc_visual.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012, Willow Garage, Inc.
3 | * Copyright (c) 2012, Ivan Dryanovski
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the Willow Garage, Inc. nor the names of its
15 | * contributors may be used to endorse or promote products derived from
16 | * this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 | * POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | #ifndef RVIZ_IMU_PLUGIN_IMU_ACC_VISUAL_H
31 | #define RVIZ_IMU_PLUGIN_IMU_ACC_VISUAL_H
32 |
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 |
40 |
41 | namespace rviz
42 | {
43 |
44 | class ImuAccVisual
45 | {
46 | public:
47 | // Constructor. Creates the visual stuff and puts it into the
48 | // scene, but in an unconfigured state.
49 | ImuAccVisual(Ogre::SceneManager * scene_manager, Ogre::SceneNode * parent_node);
50 |
51 | // Destructor. Removes the visual stuff from the scene.
52 | virtual ~ImuAccVisual();
53 |
54 | // Configure the visual to show the data in the message.
55 | void setMessage(const sensor_msgs::Imu::ConstPtr& msg);
56 |
57 | // Set the pose of the coordinate frame the message refers to.
58 | // These could be done inside setMessage(), but that would require
59 | // calls to FrameManager and error handling inside setMessage(),
60 | // which doesn't seem as clean. This way ImuVisual is only
61 | // responsible for visualization.
62 | void setFramePosition(const Ogre::Vector3& position);
63 | void setFrameOrientation(const Ogre::Quaternion& orientation);
64 |
65 | // Set the color and alpha of the visual, which are user-editable
66 |
67 | void setScale(float scale);
68 | void setColor(const QColor &color);
69 | void setAlpha(float alpha);
70 | void setDerotated(bool derotated);
71 |
72 | float getScale() { return scale_; }
73 | const QColor& getColor() { return color_; }
74 | float getAlpha() { return alpha_; }
75 | bool getDerotated() { return derotated_; }
76 |
77 | void show();
78 | void hide();
79 |
80 | private:
81 |
82 | void create();
83 |
84 | Arrow * acc_vector_;
85 |
86 | Ogre::Vector3 direction_; // computed from IMU message
87 |
88 | float arrow_length_; // computed from IMU message
89 | float arrow_radius_;
90 | float head_length_;
91 | float head_radius_;
92 |
93 | float scale_;
94 | float alpha_;
95 | QColor color_;
96 |
97 | bool derotated_;
98 |
99 | // A SceneNode whose pose is set to match the coordinate frame of
100 | // the Imu message header.
101 | Ogre::SceneNode * frame_node_;
102 |
103 | // The SceneManager, kept here only so the destructor can ask it to
104 | // destroy the ``frame_node_``.
105 | Ogre::SceneManager * scene_manager_;
106 | };
107 |
108 | } // end namespace rviz
109 |
110 | #endif // RVIZ_IMU_PLUGIN_IMU_ORIENTATATION_VISUAL_H
111 |
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/src/imu_orientation_visual.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012, Willow Garage, Inc.
3 | * Copyright (c) 2012, Ivan Dryanovski
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the Willow Garage, Inc. nor the names of its
15 | * contributors may be used to endorse or promote products derived from
16 | * this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 | * POSSIBILITY OF SUCH DAMAGE.
29 | */
30 | #ifndef RVIZ_IMU_PLUGIN_IMU_ORIENTATATION_VISUAL_H
31 | #define RVIZ_IMU_PLUGIN_IMU_ORIENTATATION_VISUAL_H
32 |
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 |
40 | namespace rviz
41 | {
42 |
43 | class ImuOrientationVisual
44 | {
45 | public:
46 | // Constructor. Creates the visual stuff and puts it into the
47 | // scene, but in an unconfigured state.
48 | ImuOrientationVisual(Ogre::SceneManager * scene_manager, Ogre::SceneNode * parent_node);
49 |
50 | // Destructor. Removes the visual stuff from the scene.
51 | virtual ~ImuOrientationVisual();
52 |
53 | // Configure the visual to show the data in the message.
54 | void setMessage(const sensor_msgs::Imu::ConstPtr& msg);
55 |
56 | // Set the pose of the coordinate frame the message refers to.
57 | // These could be done inside setMessage(), but that would require
58 | // calls to FrameManager and error handling inside setMessage(),
59 | // which doesn't seem as clean. This way ImuVisual is only
60 | // responsible for visualization.
61 | void setFramePosition(const Ogre::Vector3& position);
62 | void setFrameOrientation(const Ogre::Quaternion& orientation);
63 |
64 | // Set the color and alpha of the visual, which are user-editable
65 |
66 | void setScaleX(float x);
67 | void setScaleY(float y);
68 | void setScaleZ(float z);
69 | void setColor(const QColor &color);
70 | void setAlpha(float alpha);
71 |
72 | float getScaleX() { return scale_x_; }
73 | float getScaleY() { return scale_y_; }
74 | float getScaleZ() { return scale_z_; }
75 | const QColor& getColor() { return color_; }
76 | float getAlpha() { return alpha_; }
77 |
78 | void show();
79 | void hide();
80 |
81 | private:
82 |
83 | void create();
84 | inline bool checkQuaternionValidity(
85 | const sensor_msgs::Imu::ConstPtr& msg);
86 |
87 | Ogre::Quaternion orientation_;
88 |
89 | float scale_x_, scale_y_, scale_z_;
90 | QColor color_;
91 | float alpha_;
92 | bool quat_valid_;
93 |
94 | Shape * orientation_box_;
95 |
96 | // A SceneNode whose pose is set to match the coordinate frame of
97 | // the Imu message header.
98 | Ogre::SceneNode * frame_node_;
99 |
100 | // The SceneManager, kept here only so the destructor can ask it to
101 | // destroy the ``frame_node_``.
102 | Ogre::SceneManager * scene_manager_;
103 | };
104 |
105 | } // end namespace rviz
106 |
107 | #endif // RVIZ_IMU_PLUGIN_IMU_ORIENTATATION_VISUAL_H
108 |
--------------------------------------------------------------------------------
/imu_tool/imu_complementary_filter/include/imu_complementary_filter/complementary_filter_ros.h:
--------------------------------------------------------------------------------
1 | /*
2 | @author Roberto G. Valenti
3 |
4 | @section LICENSE
5 | Copyright (c) 2015, City University of New York
6 | CCNY Robotics Lab
7 | All rights reserved.
8 |
9 | Redistribution and use in source and binary forms, with or without
10 | modification, are permitted provided that the following conditions are met:
11 | 1. Redistributions of source code must retain the above copyright
12 | notice, this list of conditions and the following disclaimer.
13 | 2. Redistributions in binary form must reproduce the above copyright
14 | notice, this list of conditions and the following disclaimer in the
15 | documentation and/or other materials provided with the distribution.
16 | 3. Neither the name of the City College of New York nor the
17 | names of its contributors may be used to endorse or promote products
18 | derived from this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL the CCNY ROBOTICS LAB BE LIABLE FOR ANY
24 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 | */
31 |
32 | #ifndef IMU_TOOLS_COMPLEMENTARY_FILTER_ROS_H
33 | #define IMU_TOOLS_COMPLEMENTARY_FILTER_ROS_H
34 |
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 |
45 | #include "imu_complementary_filter/complementary_filter.h"
46 |
47 | namespace imu_tools {
48 |
49 | class ComplementaryFilterROS
50 | {
51 | public:
52 | ComplementaryFilterROS(const ros::NodeHandle& nh,
53 | const ros::NodeHandle& nh_private);
54 | virtual ~ComplementaryFilterROS();
55 |
56 | private:
57 |
58 | // Convenience typedefs
59 | typedef sensor_msgs::Imu ImuMsg;
60 | typedef sensor_msgs::MagneticField MagMsg;
61 | typedef message_filters::sync_policies::ApproximateTime MySyncPolicy;
63 | typedef message_filters::sync_policies::ApproximateTime
64 | SyncPolicy;
65 | typedef message_filters::Synchronizer Synchronizer;
66 | typedef message_filters::Subscriber ImuSubscriber;
67 | typedef message_filters::Subscriber MagSubscriber;
68 |
69 | // ROS-related variables.
70 | ros::NodeHandle nh_;
71 | ros::NodeHandle nh_private_;
72 |
73 | boost::shared_ptr sync_;
74 | boost::shared_ptr imu_subscriber_;
75 | boost::shared_ptr mag_subscriber_;
76 |
77 | ros::Publisher imu_publisher_;
78 | ros::Publisher rpy_publisher_;
79 | ros::Publisher state_publisher_;
80 | tf::TransformBroadcaster tf_broadcaster_;
81 |
82 | // Parameters:
83 | bool use_mag_;
84 | bool publish_tf_;
85 | bool reverse_tf_;
86 | double constant_dt_;
87 | bool publish_debug_topics_;
88 | std::string fixed_frame_;
89 | double orientation_variance_;
90 |
91 | // State variables:
92 | ComplementaryFilter filter_;
93 | ros::Time time_prev_;
94 | bool initialized_filter_;
95 |
96 | void initializeParams();
97 | void imuCallback(const ImuMsg::ConstPtr& imu_msg_raw);
98 | void imuMagCallback(const ImuMsg::ConstPtr& imu_msg_raw,
99 | const MagMsg::ConstPtr& mav_msg);
100 | void publish(const sensor_msgs::Imu::ConstPtr& imu_msg_raw);
101 |
102 | tf::Quaternion hamiltonToTFQuaternion(
103 | double q0, double q1, double q2, double q3) const;
104 | };
105 |
106 | } // namespace imu_tools
107 |
108 | #endif // IMU_TOOLS_COMPLEMENTARY_FILTER_ROS_H
109 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/test/test_helpers.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef TEST_TEST_HELPERS_H_
3 | #define TEST_TEST_HELPERS_H_
4 |
5 | #include
6 | #include
7 |
8 | #define MAX_DIFF 0.05
9 |
10 | template
11 | static inline void normalize_quaternion(T& q0, T& q1, T& q2, T& q3) {
12 | T invNorm = 1 / sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
13 | T max = q0;
14 | if (fabs(max) < fabs(q1)) max = q1;
15 | if (fabs(max) < fabs(q2)) max = q2;
16 | if (fabs(max) < fabs(q3)) max = q3;
17 | if (max < 0) invNorm *= -1.0;
18 |
19 | q0 *= invNorm;
20 | q1 *= invNorm;
21 | q2 *= invNorm;
22 | q3 *= invNorm;
23 | }
24 |
25 | // Tests for normalization in the same way as tf2:
26 | // https://github.com/ros/geometry2/blob/bd490515b1434caeff521ea14901dfe04063ca27/tf2/src/buffer_core.cpp#L244-L247
27 | template
28 | static inline bool is_normalized(T q0, T q1, T q2, T q3) {
29 | return std::abs((q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3) - 1.0f) < 10e-6;
30 | }
31 |
32 | template
33 | static inline bool quat_equal(T q0, T q1, T q2, T q3, T qr0, T qr1, T qr2, T qr3) {
34 | normalize_quaternion(q0, q1, q2, q3);
35 | normalize_quaternion(qr0, qr1, qr2, qr3);
36 |
37 | return (fabs(q0 - qr0) < MAX_DIFF) &&
38 | (fabs(q1 - qr1) < MAX_DIFF) &&
39 | (fabs(q2 - qr2) < MAX_DIFF) &&
40 | (fabs(q3 - qr3) < MAX_DIFF);
41 | }
42 |
43 | template
44 | static inline bool quat_eq_ex_z(T q0, T q1, T q2, T q3, T qr0, T qr1, T qr2, T qr3) {
45 | // assert q == qr * qz
46 | tf2::Quaternion q(q1, q2, q3, q0);
47 | tf2::Quaternion qr(qr1, qr2, qr3, qr0);
48 | tf2::Quaternion qz = q * qr.inverse();
49 |
50 | // remove x and y components.
51 | qz.setX(0.0);
52 | qz.setY(0.0);
53 |
54 | tf2::Quaternion qr_ = qz * qr;
55 |
56 | return quat_equal(q0, q1, q2, q3,
57 | qr_.getW(),
58 | qr_.getX(),
59 | qr_.getY(),
60 | qr_.getZ());
61 | }
62 |
63 | #define ASSERT_IS_NORMALIZED_(q0, q1, q2, q3) ASSERT_TRUE(is_normalized(q0, q1, q2, q3)) << "q0: " << q0 << ", q1: " << q1 << ", q2: " << q2 << ", q3: " << q3;
64 | #define ASSERT_IS_NORMALIZED(...) ASSERT_IS_NORMALIZED_(__VA_ARGS__)
65 |
66 | #define ASSERT_QUAT_EQUAL_(q0, q1, q2, q3, qr0, qr1, qr2, qr3) ASSERT_TRUE(quat_equal(q0, q1, q2, q3, qr0, qr1, qr2, qr3)) << "q0: " << q0 << ", q1: " << q1 << ", q2: " << q2 << ", q3: " << q3;
67 | #define ASSERT_QUAT_EQUAL(...) ASSERT_QUAT_EQUAL_(__VA_ARGS__)
68 |
69 | #define ASSERT_QUAT_EQUAL_EX_Z_(q0, q1, q2, q3, qr0, qr1, qr2, qr3) ASSERT_TRUE(quat_eq_ex_z(q0, q1, q2, q3, qr0, qr1, qr2, qr3)) << "q0: " << q0 << ", q1: " << q1 << ", q2: " << q2 << ", q3: " << q3;
70 | #define ASSERT_QUAT_EQUAL_EX_Z(...) ASSERT_QUAT_EQUAL_EX_Z_(__VA_ARGS__)
71 |
72 | // Well known states
73 | // scheme: AM_x_y_z
74 | #define AM_EAST_NORTH_UP /* Acceleration */ 0.0, 0.0, 9.81, /* Magnetic */ 0.0, 0.0005, -0.0005
75 | #define AM_NORTH_EAST_DOWN /* Acceleration */ 0.0, 0.0, -9.81, /* Magnetic */ 0.0005, 0.0, 0.0005
76 | #define AM_NORTH_WEST_UP /* Acceleration */ 0.0, 0.0, 9.81, /* Magnetic */ 0.0005, 0.0, -0.0005
77 | #define AM_SOUTH_UP_WEST /* Acceleration */ 0.0, 9.81, 0.0, /* Magnetic */ -0.0005, -0.0005, 0.0
78 | #define AM_SOUTH_EAST_UP /* Acceleration */ 0.0, 0.0, 9.81, /* Magnetic */ -0.0005, 0.0, -0.0005
79 | #define AM_WEST_NORTH_DOWN /* Acceleration */ 0.0, 0.0, -9.81, /* Magnetic */ 0.0, 0.0005, 0.0005
80 |
81 | // Real sensor data
82 | #define AM_WEST_NORTH_DOWN_RSD /* Acceleration */ 0.12, 0.29, -9.83, /* Magnetic */ 6.363e-06, 1.0908e-05, 4.2723e-05
83 | #define AM_NE_NW_UP_RSD /* Acceleration */ 0.20, 0.55, 9.779, /* Magnetic */ 8.484e-06, 8.181e-06, -4.3329e-05
84 |
85 | // Strip accelration from am
86 | #define ACCEL_ONLY(ax,ay,az, mx,my,mz) ax, ay, az
87 |
88 | // Well known quaternion
89 | // scheme: QUAT_axis_angle
90 | #define QUAT_IDENTITY 1.0, 0.0, 0.0, 0.0
91 | #define QUAT_MZ_90 0.707107, 0.0, 0.0, -0.707107
92 | #define QUAT_X_180 0.0, 1.0, 0.0, 0.0
93 | #define QUAT_XMYMZ_120 0.5, 0.5, -0.5, -0.5
94 | #define QUAT_WEST_NORTH_DOWN_RSD_NWU 0.01, 0.86, 0.50, 0.012 /* axis: (0.864401, 0.502559, 0.0120614) | angle: 178.848deg */
95 | #define QUAT_WEST_NORTH_DOWN_RSD_ENU 0.0, -0.25, -0.97, -0.02/* Axis: (-0.2, -0.96, 0.02), Angle: 180deg */
96 | #define QUAT_WEST_NORTH_DOWN_RSD_NED 0.86, -0.01, 0.01, -0.50 /* Axis: -Z, Angle: 60deg */
97 | #define QUAT_NE_NW_UP_RSD_NWU 0.91, 0.03, -0.02, -0.41 /* axis: (0.0300376, -0.020025, -0.410513) | angle: 48.6734deg */
98 | #define QUAT_NE_NW_UP_RSD_ENU 0.93, 0.03, 0.0, 0.35 /* Axis: Z, Angle: 41deg */
99 | #define QUAT_NE_NW_UP_RSD_NED 0.021, -0.91, -0.41, 0.02 /* Axis: (0.9, 0.4, 0.0), Angle: 180deg */
100 |
101 |
102 | #endif /* TEST_TEST_HELPERS_H_ */
103 |
--------------------------------------------------------------------------------
/serial_imu/src/sub_0x62.cpp:
--------------------------------------------------------------------------------
1 | //subscriber 0x62 data package
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include "imu_data_decode.h"
8 |
9 | void imu_0x62_callback(const serial_imu::Imu_0x62_msg imu_0x62_msg);
10 |
11 | int main(int argc, char **argv)
12 | {
13 |
14 | ros::init(argc, argv, "sub_0x62");
15 |
16 | ros::NodeHandle n;
17 |
18 | ros::Subscriber imu_0x62_sub = n.subscribe("/imu_0x62_package", 10,imu_0x62_callback);
19 |
20 | ros::spin();
21 |
22 | }
23 |
24 | void imu_0x62_callback(const serial_imu::Imu_0x62_msg imu_0x62_msg)
25 | {
26 | int i = 0;
27 |
28 |
29 | printf("\033c");
30 |
31 | printf(" Device GWID: %6d\n", imu_0x62_msg.gw_id);
32 | printf(" Device number:%6d\n", imu_0x62_msg.node_num);
33 | if(imu_0x62_msg.node_num == 1)
34 | {
35 | i = 2;
36 | goto ONE_NODE;
37 | }
38 |
39 | for (i = 0; i < imu_0x62_msg.node_num; i += 2)
40 | {
41 | putchar(10);
42 | #if 0
43 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_ID)
44 | printf(" Devie ID:%6d\n",imu_0x62_msg.node_data[i].id);
45 |
46 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_PRS)
47 | printf(" Prs(hPa): %6f\n", imu_0x62_msg.node_data[i].prs);
48 |
49 |
50 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_TIME)
51 | printf(" Run times: %d days %d:%d:%d:%d\n",imu_0x62_msg.node_data[i].time / 86400000, imu_0x62_msg.node_data[i].time / 3600000 % 24, imu_0x62_msg.node_data[i].time / 60000 % 60, imu_0x62_msg.node_data[i].time / 1000 % 60, imu_0x62_msg.node_data[i].time % 1000);
52 |
53 | printf(" Frame Rate: %4dHz\r\n", imu_0x62_msg.node_data[i].frame_rate);
54 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_ACC)
55 | printf(" Acc(G):%8.3f %8.3f %8.3f\r\n", imu_0x62_msg.node_data[i].acc_x, imu_0x62_msg.node_data[i].acc_y, imu_0x62_msg.node_data[i].acc_z);
56 |
57 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_GYR)
58 | printf(" Gyr(deg/s):%8.2f %8.2f %8.2f\r\n", imu_0x62_msg.node_data[i].gyr_x, imu_0x62_msg.node_data[i].gyr_y, imu_0x62_msg.node_data[i].gyr_z);
59 |
60 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_MAG)
61 | printf(" Mag(uT):%8.2f %8.2f %8.2f\r\n", imu_0x62_msg.node_data[i].mag_x, imu_0x62_msg.node_data[i].mag_y, imu_0x62_msg.node_data[i].mag_z);
62 |
63 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_EUL)
64 | printf(" Eul(R P Y):%8.2f %8.2f %8.2f\r\n", imu_0x62_msg.node_data[i].eul_r, imu_0x62_msg.node_data[i].eul_p, imu_0x62_msg.node_data[i].eul_y);
65 |
66 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_QUAT)
67 | printf("Quat(W X Y Z):%8.3f %8.3f %8.3f %8.3f\r\n", imu_0x62_msg.node_data[i].quat_w, imu_0x62_msg.node_data[i].quat_x, imu_0x62_msg.node_data[i].quat_y, imu_0x62_msg.node_data[i].quat_z);
68 | #endif
69 | }
70 |
71 | ONE_NODE:
72 | if(i - 1 == imu_0x62_msg.node_num)
73 | {
74 | putchar(10);
75 | i -= 2;
76 | #if 1
77 |
78 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_ID)
79 | printf(" Devie ID:%6d\n",imu_0x62_msg.node_data[i].id);
80 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_PRS)
81 | printf(" Prs(hPa): %6f\n", imu_0x62_msg.node_data[i].prs);
82 |
83 |
84 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_TIME)
85 | printf(" Run times: %d days %d:%d:%d:%d\n",imu_0x62_msg.node_data[i].time / 86400000, imu_0x62_msg.node_data[i].time / 3600000 % 24, imu_0x62_msg.node_data[i].time / 60000 % 60, imu_0x62_msg.node_data[i].time / 1000 % 60, imu_0x62_msg.node_data[i].time % 1000);
86 |
87 | printf(" Frame Rate: %4dHz\r\n", imu_0x62_msg.node_data[i].frame_rate);
88 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_ACC)
89 | printf(" Acc(G):%8.3f %8.3f %8.3f\r\n", imu_0x62_msg.node_data[i].acc_x, imu_0x62_msg.node_data[i].acc_y, imu_0x62_msg.node_data[i].acc_z);
90 |
91 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_GYR)
92 | printf(" Gyr(deg/s):%8.2f %8.2f %8.2f\r\n", imu_0x62_msg.node_data[i].gyr_x, imu_0x62_msg.node_data[i].gyr_y, imu_0x62_msg.node_data[i].gyr_z);
93 |
94 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_MAG)
95 | printf(" Mag(uT):%8.2f %8.2f %8.2f\r\n", imu_0x62_msg.node_data[i].mag_x, imu_0x62_msg.node_data[i].mag_y, imu_0x62_msg.node_data[i].mag_z);
96 |
97 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_EUL)
98 | printf(" Eul(R P Y):%8.2f %8.2f %8.2f\r\n", imu_0x62_msg.node_data[i].eul_r, imu_0x62_msg.node_data[i].eul_p, imu_0x62_msg.node_data[i].eul_y);
99 |
100 | if(imu_0x62_msg.node_data[i].bitmap & BIT_VALID_QUAT)
101 | printf("Quat(W X Y Z):%8.3f %8.3f %8.3f %8.3f\r\n", imu_0x62_msg.node_data[i].quat_w, imu_0x62_msg.node_data[i].quat_x, imu_0x62_msg.node_data[i].quat_y, imu_0x62_msg.node_data[i].quat_z);
102 |
103 | #endif
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/include/imu_filter_madgwick/imu_filter_ros.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010, CCNY Robotics Lab
3 | * Ivan Dryanovski
4 | *
5 | * http://robotics.ccny.cuny.edu
6 | *
7 | * Based on implementation of Madgwick's IMU and AHRS algorithms.
8 | * http://www.x-io.co.uk/node/8#open_source_ahrs_and_imu_algorithms
9 | *
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef IMU_FILTER_MADWICK_IMU_FILTER_ROS_H
26 | #define IMU_FILTER_MADWICK_IMU_FILTER_ROS_H
27 |
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include "tf2_ros/transform_broadcaster.h"
33 | #include
34 | #include
35 | #include
36 | #include
37 |
38 | #include "imu_filter_madgwick/imu_filter.h"
39 | #include "imu_filter_madgwick/ImuFilterMadgwickConfig.h"
40 |
41 | class ImuFilterRos
42 | {
43 | typedef sensor_msgs::Imu ImuMsg;
44 | typedef sensor_msgs::MagneticField MagMsg;
45 | typedef geometry_msgs::Vector3Stamped MagVectorMsg;
46 |
47 | typedef message_filters::sync_policies::ApproximateTime SyncPolicy;
48 | typedef message_filters::Synchronizer Synchronizer;
49 | typedef message_filters::Subscriber ImuSubscriber;
50 | typedef message_filters::Subscriber MagSubscriber;
51 | typedef message_filters::Subscriber MagVectorSubscriber;
52 |
53 | typedef imu_filter_madgwick::ImuFilterMadgwickConfig FilterConfig;
54 | typedef dynamic_reconfigure::Server FilterConfigServer;
55 |
56 | public:
57 |
58 | ImuFilterRos(ros::NodeHandle nh, ros::NodeHandle nh_private);
59 | virtual ~ImuFilterRos();
60 |
61 | private:
62 |
63 | // **** ROS-related
64 |
65 | ros::NodeHandle nh_;
66 | ros::NodeHandle nh_private_;
67 |
68 | boost::shared_ptr imu_subscriber_;
69 | boost::shared_ptr mag_subscriber_;
70 | boost::shared_ptr sync_;
71 |
72 | // Adapter to support the use_magnetic_field_msg param.
73 | boost::shared_ptr vector_mag_subscriber_;
74 | ros::Publisher mag_republisher_;
75 |
76 | ros::Publisher rpy_filtered_debug_publisher_;
77 | ros::Publisher rpy_raw_debug_publisher_;
78 | ros::Publisher imu_publisher_;
79 | tf2_ros::TransformBroadcaster tf_broadcaster_;
80 |
81 | boost::shared_ptr config_server_;
82 | ros::Timer check_topics_timer_;
83 |
84 | // **** paramaters
85 | WorldFrame::WorldFrame world_frame_;
86 | bool use_mag_;
87 | bool use_magnetic_field_msg_;
88 | bool stateless_;
89 | bool publish_tf_;
90 | bool reverse_tf_;
91 | std::string fixed_frame_;
92 | std::string imu_frame_;
93 | double constant_dt_;
94 | bool publish_debug_topics_;
95 | bool remove_gravity_vector_;
96 | geometry_msgs::Vector3 mag_bias_;
97 | double orientation_variance_;
98 |
99 | // **** state variables
100 | boost::mutex mutex_;
101 | bool initialized_;
102 | ros::Time last_time_;
103 |
104 | // **** filter implementation
105 | ImuFilter filter_;
106 |
107 | // **** member functions
108 | void imuMagCallback(const ImuMsg::ConstPtr& imu_msg_raw,
109 | const MagMsg::ConstPtr& mav_msg);
110 |
111 | void imuCallback(const ImuMsg::ConstPtr& imu_msg_raw);
112 |
113 | void imuMagVectorCallback(const MagVectorMsg::ConstPtr& mag_vector_msg);
114 |
115 | void publishFilteredMsg(const ImuMsg::ConstPtr& imu_msg_raw);
116 | void publishTransform(const ImuMsg::ConstPtr& imu_msg_raw);
117 |
118 | void publishRawMsg(const ros::Time& t,
119 | float roll, float pitch, float yaw);
120 |
121 | void reconfigCallback(FilterConfig& config, uint32_t level);
122 | void checkTopicsTimerCallback(const ros::TimerEvent&);
123 | };
124 |
125 | #endif // IMU_FILTER_IMU_MADWICK_FILTER_ROS_H
126 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/test/madgwick_test.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "test_helpers.h"
4 |
5 | #define FILTER_ITERATIONS 10000
6 |
7 |
8 | template
9 | void filterStationary(
10 | float Ax, float Ay, float Az,
11 | float Mx, float My, float Mz,
12 | double& q0, double& q1, double& q2, double& q3) {
13 | float dt = 0.1;
14 | float Gx = 0.0, Gy = 0.0, Gz = 0.0; // Stationary state => Gyro = (0,0,0)
15 |
16 | ImuFilter filter;
17 | filter.setDriftBiasGain(0.0);
18 | filter.setAlgorithmGain(0.1);
19 |
20 | // initialize with some orientation
21 | filter.setOrientation(q0,q1,q2,q3);
22 | filter.setWorldFrame(FRAME);
23 |
24 | for (int i = 0; i < FILTER_ITERATIONS; i++) {
25 | filter.madgwickAHRSupdate(Gx, Gy, Gz, Ax, Ay, Az, Mx, My, Mz, dt);
26 | }
27 |
28 | filter.getOrientation(q0,q1,q2,q3);
29 | }
30 |
31 |
32 | template
33 | void filterStationary(
34 | float Ax, float Ay, float Az,
35 | double& q0, double& q1, double& q2, double& q3) {
36 | float dt = 0.1;
37 | float Gx = 0.0, Gy = 0.0, Gz = 0.0; // Stationary state => Gyro = (0,0,0)
38 |
39 | ImuFilter filter;
40 | filter.setDriftBiasGain(0.0);
41 | filter.setAlgorithmGain(0.1);
42 |
43 | // initialize with some orientation
44 | filter.setOrientation(q0,q1,q2,q3);
45 | filter.setWorldFrame(FRAME);
46 |
47 | for (int i = 0; i < FILTER_ITERATIONS; i++) {
48 | filter.madgwickAHRSupdateIMU(Gx, Gy, Gz, Ax, Ay, Az, dt);
49 | }
50 |
51 | filter.getOrientation(q0,q1,q2,q3);
52 | }
53 |
54 |
55 | #define TEST_STATIONARY_ENU(in_am, exp_result) \
56 | TEST(MadgwickTest, Stationary_ENU_ ## in_am){ \
57 | double q0 = .5, q1 = .5, q2 = .5, q3 = .5; \
58 | filterStationary(in_am, q0, q1, q2, q3); \
59 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
60 | ASSERT_QUAT_EQUAL(q0, q1, q2, q3, exp_result); } \
61 | TEST(MadgwickTest, Stationary_ENU_NM_ ## in_am){ \
62 | double q0 = .5, q1 = .5, q2 = .5, q3 = .5; \
63 | filterStationary(ACCEL_ONLY(in_am), q0, q1, q2, q3); \
64 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
65 | ASSERT_QUAT_EQUAL_EX_Z(q0, q1, q2, q3, exp_result); }
66 |
67 | #define TEST_STATIONARY_NED(in_am, exp_result) \
68 | TEST(MadgwickTest, Stationary_NED_ ## in_am){ \
69 | double q0 = .5, q1 = .5, q2 = .5, q3 = .5; \
70 | filterStationary(in_am, q0, q1, q2, q3); \
71 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
72 | ASSERT_QUAT_EQUAL(q0, q1, q2, q3, exp_result); } \
73 | TEST(MadgwickTest, Stationary_NED_NM_ ## in_am){ \
74 | double q0 = .5, q1 = .5, q2 = .5, q3 = .5; \
75 | filterStationary(ACCEL_ONLY(in_am), q0, q1, q2, q3); \
76 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
77 | ASSERT_QUAT_EQUAL_EX_Z(q0, q1, q2, q3, exp_result); }
78 |
79 | #define TEST_STATIONARY_NWU(in_am, exp_result) \
80 | TEST(MadgwickTest, Stationary_NWU_ ## in_am){ \
81 | double q0 = .5, q1 = .5, q2 = .5, q3 = .5; \
82 | filterStationary(in_am, q0, q1, q2, q3); \
83 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
84 | ASSERT_QUAT_EQUAL(q0, q1, q2, q3, exp_result); } \
85 | TEST(MadgwickTest, Stationary_NWU_NM_ ## in_am){ \
86 | double q0 = .5, q1 = .5, q2 = .5, q3 = .5; \
87 | filterStationary(ACCEL_ONLY(in_am), q0, q1, q2, q3); \
88 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
89 | ASSERT_QUAT_EQUAL_EX_Z(q0, q1, q2, q3, exp_result); }
90 |
91 | TEST_STATIONARY_NWU(AM_NORTH_EAST_DOWN, QUAT_X_180)
92 | TEST_STATIONARY_NWU(AM_NORTH_WEST_UP, QUAT_IDENTITY)
93 | TEST_STATIONARY_NWU(AM_WEST_NORTH_DOWN_RSD, QUAT_WEST_NORTH_DOWN_RSD_NWU)
94 | TEST_STATIONARY_NWU(AM_NE_NW_UP_RSD, QUAT_NE_NW_UP_RSD_NWU)
95 |
96 | TEST_STATIONARY_ENU(AM_EAST_NORTH_UP, QUAT_IDENTITY)
97 | TEST_STATIONARY_ENU(AM_SOUTH_UP_WEST, QUAT_XMYMZ_120)
98 | TEST_STATIONARY_ENU(AM_SOUTH_EAST_UP, QUAT_MZ_90)
99 | TEST_STATIONARY_ENU(AM_WEST_NORTH_DOWN_RSD, QUAT_WEST_NORTH_DOWN_RSD_ENU)
100 | TEST_STATIONARY_ENU(AM_NE_NW_UP_RSD, QUAT_NE_NW_UP_RSD_ENU)
101 |
102 | TEST_STATIONARY_NED(AM_NORTH_EAST_DOWN, QUAT_IDENTITY)
103 | TEST_STATIONARY_NED(AM_NORTH_WEST_UP, QUAT_X_180)
104 | TEST_STATIONARY_NED(AM_WEST_NORTH_DOWN_RSD, QUAT_WEST_NORTH_DOWN_RSD_NED)
105 | TEST_STATIONARY_NED(AM_NE_NW_UP_RSD, QUAT_NE_NW_UP_RSD_NED)
106 |
107 |
108 |
109 | TEST(MadgwickTest, TestQuatEqNoZ) {
110 |
111 | ASSERT_TRUE(quat_eq_ex_z(QUAT_IDENTITY, QUAT_MZ_90));
112 | ASSERT_FALSE(quat_eq_ex_z(QUAT_IDENTITY, QUAT_X_180));
113 |
114 | }
115 |
116 |
117 |
118 | int main(int argc, char **argv){
119 | testing::InitGoogleTest(&argc, argv);
120 | return RUN_ALL_TESTS();
121 | }
122 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/test/stateless_orientation_test.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "test_helpers.h"
3 |
4 |
5 | template
6 | bool computeOrientation(
7 | float Ax, float Ay, float Az,
8 | float Mx, float My, float Mz,
9 | double& q0, double& q1, double& q2, double& q3) {
10 |
11 | geometry_msgs::Vector3 A, M;
12 | geometry_msgs::Quaternion orientation;
13 | A.x = Ax; A.y = Ay; A.z = Az;
14 | M.x = Mx; M.y = My; M.z = Mz;
15 |
16 | bool res = StatelessOrientation::computeOrientation(FRAME, A, M, orientation);
17 |
18 | q0 = orientation.w;
19 | q1 = orientation.x;
20 | q2 = orientation.y;
21 | q3 = orientation.z;
22 |
23 | return res;
24 | }
25 |
26 | template
27 | bool computeOrientation(
28 | float Ax, float Ay, float Az,
29 | double& q0, double& q1, double& q2, double& q3) {
30 |
31 | geometry_msgs::Vector3 A;
32 | geometry_msgs::Quaternion orientation;
33 | A.x = Ax; A.y = Ay; A.z = Az;
34 |
35 | bool res = StatelessOrientation::computeOrientation(FRAME, A, orientation);
36 |
37 | q0 = orientation.w;
38 | q1 = orientation.x;
39 | q2 = orientation.y;
40 | q3 = orientation.z;
41 |
42 | return res;
43 | }
44 |
45 |
46 | #define TEST_STATELESS_ENU(in_am, exp_result) \
47 | TEST(StatelessOrientationTest, Stationary_ENU_ ## in_am){ \
48 | double q0, q1, q2, q3; \
49 | ASSERT_TRUE(computeOrientation(in_am, q0, q1, q2, q3)); \
50 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
51 | ASSERT_QUAT_EQUAL(q0, q1, q2, q3, exp_result); } \
52 | TEST(StatelessOrientationTest, Stationary_ENU_NM_ ## in_am){ \
53 | double q0, q1, q2, q3; \
54 | ASSERT_TRUE(computeOrientation(ACCEL_ONLY(in_am), q0, q1, q2, q3)); \
55 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
56 | ASSERT_QUAT_EQUAL_EX_Z(q0, q1, q2, q3, exp_result); }
57 |
58 | #define TEST_STATELESS_NED(in_am, exp_result) \
59 | TEST(StatelessOrientationTest, Stationary_NED_ ## in_am){ \
60 | double q0, q1, q2, q3; \
61 | ASSERT_TRUE(computeOrientation(in_am, q0, q1, q2, q3)); \
62 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
63 | ASSERT_QUAT_EQUAL(q0, q1, q2, q3, exp_result); } \
64 | TEST(StatelessOrientationTest, Stationary_NED_NM_ ## in_am){ \
65 | double q0, q1, q2, q3; \
66 | ASSERT_TRUE(computeOrientation(ACCEL_ONLY(in_am), q0, q1, q2, q3)); \
67 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
68 | ASSERT_QUAT_EQUAL_EX_Z(q0, q1, q2, q3, exp_result); }
69 |
70 | #define TEST_STATELESS_NWU(in_am, exp_result) \
71 | TEST(StatelessOrientationTest, Stationary_NWU_ ## in_am){ \
72 | double q0, q1, q2, q3; \
73 | ASSERT_TRUE(computeOrientation(in_am, q0, q1, q2, q3)); \
74 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
75 | ASSERT_QUAT_EQUAL(q0, q1, q2, q3, exp_result); } \
76 | TEST(StatelessOrientationTest, Stationary_NWU_NM_ ## in_am){ \
77 | double q0, q1, q2, q3; \
78 | ASSERT_TRUE(computeOrientation(ACCEL_ONLY(in_am), q0, q1, q2, q3)); \
79 | ASSERT_IS_NORMALIZED(q0, q1, q2, q3); \
80 | ASSERT_QUAT_EQUAL_EX_Z(q0, q1, q2, q3, exp_result); }
81 |
82 | TEST_STATELESS_ENU(AM_EAST_NORTH_UP, QUAT_IDENTITY)
83 | TEST_STATELESS_ENU(AM_SOUTH_UP_WEST, QUAT_XMYMZ_120)
84 | TEST_STATELESS_ENU(AM_SOUTH_EAST_UP, QUAT_MZ_90)
85 | TEST_STATELESS_ENU(AM_WEST_NORTH_DOWN_RSD, QUAT_WEST_NORTH_DOWN_RSD_ENU)
86 | TEST_STATELESS_ENU(AM_NE_NW_UP_RSD, QUAT_NE_NW_UP_RSD_ENU)
87 |
88 |
89 | TEST_STATELESS_NED(AM_NORTH_EAST_DOWN, QUAT_IDENTITY)
90 | TEST_STATELESS_NED(AM_WEST_NORTH_DOWN, QUAT_MZ_90)
91 | TEST_STATELESS_NED(AM_WEST_NORTH_DOWN_RSD, QUAT_WEST_NORTH_DOWN_RSD_NED)
92 | TEST_STATELESS_NED(AM_NE_NW_UP_RSD, QUAT_NE_NW_UP_RSD_NED)
93 |
94 |
95 | TEST_STATELESS_NWU(AM_NORTH_EAST_DOWN, QUAT_X_180)
96 | TEST_STATELESS_NWU(AM_NORTH_WEST_UP, QUAT_IDENTITY)
97 | TEST_STATELESS_NWU(AM_WEST_NORTH_DOWN_RSD, QUAT_WEST_NORTH_DOWN_RSD_NWU)
98 | TEST_STATELESS_NWU(AM_NE_NW_UP_RSD, QUAT_NE_NW_UP_RSD_NWU)
99 |
100 |
101 | TEST(StatelessOrientationTest, Check_NoAccel){
102 | double q0, q1, q2, q3;
103 | ASSERT_FALSE(computeOrientation(
104 | 0.0, 0.0, 0.0,
105 | 0.0, 0.0005, -0.0005,
106 | q0, q1, q2, q3));
107 | }
108 |
109 | TEST(StatelessOrientationTest, Check_NoMag){
110 | double q0, q1, q2, q3;
111 | ASSERT_FALSE(computeOrientation(
112 | 0.0, 0.0, 9.81,
113 | 0.0, 0.0, 0.0,
114 | q0, q1, q2, q3));
115 | }
116 |
117 |
118 |
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/src/imu_axes_visual.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012, Willow Garage, Inc.
3 | * Copyright (c) 2012, Ivan Dryanovski
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the Willow Garage, Inc. nor the names of its
15 | * contributors may be used to endorse or promote products derived from
16 | * this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 | * POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #include "imu_axes_visual.h"
32 |
33 | #include
34 | #include
35 |
36 | namespace rviz
37 | {
38 |
39 | ImuAxesVisual::ImuAxesVisual(Ogre::SceneManager* scene_manager, Ogre::SceneNode* parent_node):
40 | orientation_axes_(NULL),
41 | scale_(0.15), quat_valid_(true)
42 | {
43 | scene_manager_ = scene_manager;
44 |
45 | // Ogre::SceneNode s form a tree, with each node storing the
46 | // transform (position and orientation) of itself relative to its
47 | // parent. Ogre does the math of combining those transforms when it
48 | // is time to render.
49 | //
50 | // Here we create a node to store the pose of the Imu's header frame
51 | // relative to the RViz fixed frame.
52 | frame_node_ = parent_node->createChildSceneNode();
53 | }
54 |
55 | ImuAxesVisual::~ImuAxesVisual()
56 | {
57 | hide();
58 |
59 | // Destroy the frame node since we don't need it anymore.
60 | scene_manager_->destroySceneNode(frame_node_);
61 | }
62 |
63 | void ImuAxesVisual::show()
64 | {
65 | if (!orientation_axes_)
66 | {
67 | orientation_axes_ = new Axes(scene_manager_, frame_node_);
68 | orientation_axes_->setScale(Ogre::Vector3(scale_, scale_, scale_));
69 | orientation_axes_->setOrientation(orientation_);
70 | }
71 | }
72 |
73 | void ImuAxesVisual::hide()
74 | {
75 | if (orientation_axes_)
76 | {
77 | delete orientation_axes_;
78 | orientation_axes_ = NULL;
79 | }
80 | }
81 |
82 | void ImuAxesVisual::setMessage(const sensor_msgs::Imu::ConstPtr& msg)
83 | {
84 | if (checkQuaternionValidity(msg)) {
85 | if (!quat_valid_) {
86 | ROS_INFO("rviz_imu_plugin got valid quaternion, "
87 | "displaying true orientation");
88 | quat_valid_ = true;
89 | }
90 | orientation_ = Ogre::Quaternion(msg->orientation.w,
91 | msg->orientation.x,
92 | msg->orientation.y,
93 | msg->orientation.z);
94 | } else {
95 | if (quat_valid_) {
96 | ROS_WARN("rviz_imu_plugin got invalid quaternion (%lf, %lf, %lf, %lf), "
97 | "will display neutral orientation instead", msg->orientation.w,
98 | msg->orientation.x,msg->orientation.y,msg->orientation.z);
99 | quat_valid_ = false;
100 | }
101 | // if quaternion is invalid, give a unit quat to Ogre
102 | orientation_ = Ogre::Quaternion();
103 | }
104 |
105 | if (orientation_axes_)
106 | orientation_axes_->setOrientation(orientation_);
107 | }
108 |
109 | void ImuAxesVisual::setScale(float scale)
110 | {
111 | scale_ = scale;
112 | if (orientation_axes_)
113 | orientation_axes_->setScale(Ogre::Vector3(scale_, scale_, scale_));
114 | }
115 |
116 | void ImuAxesVisual::setFramePosition(const Ogre::Vector3& position)
117 | {
118 | frame_node_->setPosition(position);
119 | }
120 |
121 | void ImuAxesVisual::setFrameOrientation(const Ogre::Quaternion& orientation)
122 | {
123 | frame_node_->setOrientation(orientation);
124 | }
125 |
126 | inline bool ImuAxesVisual::checkQuaternionValidity(
127 | const sensor_msgs::Imu::ConstPtr& msg) {
128 |
129 | double x = msg->orientation.x,
130 | y = msg->orientation.y,
131 | z = msg->orientation.z,
132 | w = msg->orientation.w;
133 | // OGRE can handle unnormalized quaternions, but quat's length extremely small;
134 | // this may indicate that invalid (0, 0, 0, 0) quat is passed, this will lead ogre
135 | // to crash unexpectly
136 | if ( std::sqrt( x*x + y*y + z*z + w*w ) < 0.0001 ) {
137 | return false;
138 | }
139 | return true;
140 | }
141 |
142 |
143 | } // end namespace rviz
144 |
145 |
--------------------------------------------------------------------------------
/imu_tool/imu_filter_madgwick/src/stateless_orientation.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010, CCNY Robotics Lab
3 | * Ivan Dryanovski
4 | *
5 | * http://robotics.ccny.cuny.edu
6 | *
7 | * Based on implementation of Madgwick's IMU and AHRS algorithms.
8 | * http://www.x-io.co.uk/node/8#open_source_ahrs_and_imu_algorithms
9 | *
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include "imu_filter_madgwick/stateless_orientation.h"
26 | #include
27 | #include
28 | #include
29 |
30 | template
31 | static inline void crossProduct(
32 | T ax, T ay, T az,
33 | T bx, T by, T bz,
34 | T& rx, T& ry, T& rz) {
35 | rx = ay*bz - az*by;
36 | ry = az*bx - ax*bz;
37 | rz = ax*by - ay*bx;
38 | }
39 |
40 |
41 | template
42 | static inline T normalizeVector(T& vx, T& vy, T& vz) {
43 | T norm = sqrt(vx*vx + vy*vy + vz*vz);
44 | T inv = 1.0 / norm;
45 | vx *= inv;
46 | vy *= inv;
47 | vz *= inv;
48 | return norm;
49 |
50 | }
51 |
52 |
53 | bool StatelessOrientation::computeOrientation(
54 | WorldFrame::WorldFrame frame,
55 | geometry_msgs::Vector3 A,
56 | geometry_msgs::Vector3 E,
57 | geometry_msgs::Quaternion& orientation) {
58 |
59 | float Hx, Hy, Hz;
60 | float Mx, My, Mz;
61 | float normH;
62 |
63 | // A: pointing up
64 | float Ax = A.x, Ay = A.y, Az = A.z;
65 |
66 | // E: pointing down/north
67 | float Ex = E.x, Ey = E.y, Ez = E.z;
68 |
69 | // H: vector horizontal, pointing east
70 | // H = E x A
71 | crossProduct(Ex, Ey, Ez, Ax, Ay, Az, Hx, Hy, Hz);
72 |
73 | // normalize H
74 | normH = normalizeVector(Hx, Hy, Hz);
75 | if (normH < 1E-7) {
76 | // device is close to free fall (or in space?), or close to
77 | // magnetic north pole.
78 | // mag in T => Threshold 1E-7, typical values are > 1E-5.
79 | return false;
80 | }
81 |
82 | // normalize A
83 | normalizeVector(Ax, Ay, Az);
84 |
85 | // M: vector horizontal, pointing north
86 | // M = A x H
87 | crossProduct(Ax, Ay, Az, Hx, Hy, Hz, Mx, My, Mz);
88 |
89 | // Create matrix for basis transformation
90 | tf2::Matrix3x3 R;
91 | switch (frame) {
92 | case WorldFrame::NED:
93 | // vector space world W:
94 | // Basis: bwx (1,0,0) north, bwy (0,1,0) east, bwz (0,0,1) down
95 | // vector space local L:
96 | // Basis: M ,H, -A
97 | // W(1,0,0) => L(M)
98 | // W(0,1,0) => L(H)
99 | // W(0,0,1) => L(-A)
100 |
101 | // R: Transform Matrix local => world equals basis of L, because basis of W is I
102 | R[0][0] = Mx; R[0][1] = Hx; R[0][2] = -Ax;
103 | R[1][0] = My; R[1][1] = Hy; R[1][2] = -Ay;
104 | R[2][0] = Mz; R[2][1] = Hz; R[2][2] = -Az;
105 | break;
106 |
107 | case WorldFrame::NWU:
108 | // vector space world W:
109 | // Basis: bwx (1,0,0) north, bwy (0,1,0) west, bwz (0,0,1) up
110 | // vector space local L:
111 | // Basis: M ,H, -A
112 | // W(1,0,0) => L(M)
113 | // W(0,1,0) => L(-H)
114 | // W(0,0,1) => L(A)
115 |
116 | // R: Transform Matrix local => world equals basis of L, because basis of W is I
117 | R[0][0] = Mx; R[0][1] = -Hx; R[0][2] = Ax;
118 | R[1][0] = My; R[1][1] = -Hy; R[1][2] = Ay;
119 | R[2][0] = Mz; R[2][1] = -Hz; R[2][2] = Az;
120 | break;
121 |
122 | default:
123 | case WorldFrame::ENU:
124 | // vector space world W:
125 | // Basis: bwx (1,0,0) east, bwy (0,1,0) north, bwz (0,0,1) up
126 | // vector space local L:
127 | // Basis: H, M , A
128 | // W(1,0,0) => L(H)
129 | // W(0,1,0) => L(M)
130 | // W(0,0,1) => L(A)
131 |
132 | // R: Transform Matrix local => world equals basis of L, because basis of W is I
133 | R[0][0] = Hx; R[0][1] = Mx; R[0][2] = Ax;
134 | R[1][0] = Hy; R[1][1] = My; R[1][2] = Ay;
135 | R[2][0] = Hz; R[2][1] = Mz; R[2][2] = Az;
136 | break;
137 | }
138 |
139 | // Matrix.getRotation assumes vector rotation, but we're using
140 | // coordinate systems. Thus negate rotation angle (inverse).
141 | tf2::Quaternion q;
142 | R.getRotation(q);
143 | tf2::convert(q.inverse(), orientation);
144 | return true;
145 | }
146 |
147 |
148 | bool StatelessOrientation::computeOrientation(
149 | WorldFrame::WorldFrame frame,
150 | geometry_msgs::Vector3 A,
151 | geometry_msgs::Quaternion& orientation) {
152 |
153 | // This implementation could be optimized regarding speed.
154 |
155 | // magnetic Field E must not be parallel to A,
156 | // choose an arbitrary orthogonal vector
157 | geometry_msgs::Vector3 E;
158 | if (fabs(A.x) > 0.1 || fabs(A.y) > 0.1) {
159 | E.x = A.y;
160 | E.y = A.x;
161 | E.z = 0.0;
162 | } else if (fabs(A.z) > 0.1) {
163 | E.x = 0.0;
164 | E.y = A.z;
165 | E.z = A.y;
166 | } else {
167 | // free fall
168 | return false;
169 | }
170 |
171 | return computeOrientation(frame, A, E, orientation);
172 | }
173 |
--------------------------------------------------------------------------------
/racecar/rviz/test_laser.rviz:
--------------------------------------------------------------------------------
1 | Panels:
2 | - Class: rviz/Displays
3 | Help Height: 78
4 | Name: Displays
5 | Property Tree Widget:
6 | Expanded:
7 | - /Global Options1
8 | - /Status1
9 | - /Grid1
10 | - /LaserScan1
11 | - /Axes1
12 | - /Axes1/Status1
13 | - /TF1/Frames1
14 | Splitter Ratio: 0.5
15 | Tree Height: 490
16 | - Class: rviz/Selection
17 | Name: Selection
18 | - Class: rviz/Tool Properties
19 | Expanded:
20 | - /2D Pose Estimate1
21 | - /2D Nav Goal1
22 | - /Publish Point1
23 | Name: Tool Properties
24 | Splitter Ratio: 0.588679016
25 | - Class: rviz/Views
26 | Expanded:
27 | - /Current View1
28 | Name: Views
29 | Splitter Ratio: 0.5
30 | - Class: rviz/Time
31 | Experimental: false
32 | Name: Time
33 | SyncMode: 0
34 | SyncSource: LaserScan
35 | Visualization Manager:
36 | Class: ""
37 | Displays:
38 | - Alpha: 0.5
39 | Cell Size: 1
40 | Class: rviz/Grid
41 | Color: 160; 160; 164
42 | Enabled: true
43 | Line Style:
44 | Line Width: 0.0299999993
45 | Value: Lines
46 | Name: Grid
47 | Normal Cell Count: 0
48 | Offset:
49 | X: 0
50 | Y: 0
51 | Z: 0
52 | Plane: XY
53 | Plane Cell Count: 26
54 | Reference Frame:
55 | Value: true
56 | - Alpha: 1
57 | Autocompute Intensity Bounds: true
58 | Autocompute Value Bounds:
59 | Max Value: 10
60 | Min Value: -10
61 | Value: true
62 | Axis: Z
63 | Channel Name: intensity
64 | Class: rviz/LaserScan
65 | Color: 255; 255; 255
66 | Color Transformer: Intensity
67 | Decay Time: 0
68 | Enabled: true
69 | Invert Rainbow: false
70 | Max Color: 255; 255; 255
71 | Max Intensity: 2319
72 | Min Color: 0; 0; 0
73 | Min Intensity: 2
74 | Name: LaserScan
75 | Position Transformer: XYZ
76 | Queue Size: 10
77 | Selectable: true
78 | Size (Pixels): 3
79 | Size (m): 0.00999999978
80 | Style: Points
81 | Topic: /scan
82 | Unreliable: false
83 | Use Fixed Frame: true
84 | Use rainbow: true
85 | Value: true
86 | - Class: rviz/Axes
87 | Enabled: true
88 | Length: 0.5
89 | Name: Axes
90 | Radius: 0.0500000007
91 | Reference Frame:
92 | Value: true
93 | - Class: rviz/TF
94 | Enabled: true
95 | Frame Timeout: 15
96 | Frames:
97 | All Enabled: true
98 | Marker Scale: 1
99 | Name: TF
100 | Show Arrows: true
101 | Show Axes: true
102 | Show Names: true
103 | Tree:
104 | {}
105 | Update Interval: 1
106 | Value: true
107 | Enabled: true
108 | Global Options:
109 | Background Color: 48; 48; 48
110 | Default Light: true
111 | Fixed Frame: laser
112 | Frame Rate: 30
113 | Name: root
114 | Tools:
115 | - Class: rviz/Interact
116 | Hide Inactive Objects: true
117 | - Class: rviz/MoveCamera
118 | - Class: rviz/Select
119 | - Class: rviz/FocusCamera
120 | - Class: rviz/Measure
121 | - Class: rviz/SetInitialPose
122 | Topic: /initialpose
123 | - Class: rviz/SetGoal
124 | Topic: /move_base_simple/goal
125 | - Class: rviz/PublishPoint
126 | Single click: true
127 | Topic: /clicked_point
128 | Value: true
129 | Views:
130 | Current:
131 | Class: rviz/Orbit
132 | Distance: 10.5115833
133 | Enable Stereo Rendering:
134 | Stereo Eye Separation: 0.0599999987
135 | Stereo Focal Distance: 1
136 | Swap Stereo Eyes: false
137 | Value: false
138 | Focal Point:
139 | X: 0
140 | Y: 0
141 | Z: 0
142 | Focal Shape Fixed Size: true
143 | Focal Shape Size: 0.0500000007
144 | Invert Z Axis: false
145 | Name: Current View
146 | Near Clip Distance: 0.00999999978
147 | Pitch: 1.06979573
148 | Target Frame:
149 | Value: Orbit (rviz)
150 | Yaw: 2.66859388
151 | Saved: ~
152 | Window Geometry:
153 | Displays:
154 | collapsed: false
155 | Height: 773
156 | Hide Left Dock: false
157 | Hide Right Dock: false
158 | QMainWindow State: 000000ff00000000fd00000004000000000000017000000279fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000006100fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000002800000279000000d700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f00000279fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000002800000279000000ad00fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000054300000040fc0100000002fb0000000800540069006d00650100000000000005430000030000fffffffb0000000800540069006d00650100000000000004500000000000000000000002b80000027900000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
159 | Selection:
160 | collapsed: false
161 | Time:
162 | collapsed: false
163 | Tool Properties:
164 | collapsed: false
165 | Views:
166 | collapsed: false
167 | Width: 1347
168 | X: 152
169 | Y: 136
170 |
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/src/imu_acc_visual.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012, Willow Garage, Inc.
3 | * Copyright (c) 2012, Ivan Dryanovski
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the Willow Garage, Inc. nor the names of its
15 | * contributors may be used to endorse or promote products derived from
16 | * this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 | * POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #include "imu_acc_visual.h"
32 |
33 | namespace rviz
34 | {
35 |
36 | ImuAccVisual::ImuAccVisual(Ogre::SceneManager* scene_manager, Ogre::SceneNode* parent_node):
37 | acc_vector_(NULL),
38 | arrow_length_(9.81),
39 | arrow_radius_(0.50),
40 | head_length_(1.00),
41 | head_radius_(1.00),
42 | scale_(0.05),
43 | alpha_(1.0),
44 | color_(1.0, 1.0, 0.0),
45 | derotated_(true)
46 | {
47 | scene_manager_ = scene_manager;
48 |
49 | // Ogre::SceneNode s form a tree, with each node storing the
50 | // transform (position and orientation) of itself relative to its
51 | // parent. Ogre does the math of combining those transforms when it
52 | // is time to render.
53 | //
54 | // Here we create a node to store the pose of the Imu's header frame
55 | // relative to the RViz fixed frame.
56 | frame_node_ = parent_node->createChildSceneNode();
57 | }
58 |
59 | ImuAccVisual::~ImuAccVisual()
60 | {
61 | hide();
62 |
63 | // Destroy the frame node since we don't need it anymore.
64 | scene_manager_->destroySceneNode(frame_node_);
65 | }
66 |
67 | void ImuAccVisual::show()
68 | {
69 | if (!acc_vector_)
70 | {
71 | acc_vector_ = new Arrow(scene_manager_, frame_node_);
72 | acc_vector_->setColor(color_.redF(), color_.greenF(), color_.blueF(), alpha_);
73 | acc_vector_->setDirection(direction_);
74 | acc_vector_->set(
75 | arrow_length_ * scale_,
76 | arrow_radius_ * scale_,
77 | head_length_ * scale_,
78 | head_radius_ * scale_);
79 | }
80 | }
81 |
82 | void ImuAccVisual::hide()
83 | {
84 | if (acc_vector_)
85 | {
86 | delete acc_vector_;
87 | acc_vector_ = NULL;
88 | }
89 | }
90 |
91 | void ImuAccVisual::setMessage(const sensor_msgs::Imu::ConstPtr& msg)
92 | {
93 | direction_ = Ogre::Vector3(msg->linear_acceleration.x,
94 | msg->linear_acceleration.y,
95 | msg->linear_acceleration.z);
96 |
97 |
98 | // Rotate the acceleration vector by the IMU orientation. This makes
99 | // sense since the visualization of the IMU is also rotated by the
100 | // orientation. In this way, both appear in the inertial frame.
101 | if (derotated_)
102 | {
103 | Ogre::Quaternion orientation(msg->orientation.w,
104 | msg->orientation.x,
105 | msg->orientation.y,
106 | msg->orientation.z);
107 |
108 | direction_ = orientation * direction_;
109 | }
110 |
111 | arrow_length_ = sqrt(
112 | msg->linear_acceleration.x * msg->linear_acceleration.x +
113 | msg->linear_acceleration.y * msg->linear_acceleration.y +
114 | msg->linear_acceleration.z * msg->linear_acceleration.z);
115 |
116 | if (acc_vector_)
117 | {
118 | acc_vector_->setDirection(direction_);
119 | acc_vector_->set(
120 | arrow_length_ * scale_,
121 | arrow_radius_ * scale_,
122 | head_length_ * scale_,
123 | head_radius_ * scale_);
124 | }
125 | }
126 |
127 | void ImuAccVisual::setScale(float scale)
128 | {
129 | scale_ = scale;
130 | if (acc_vector_)
131 | {
132 | acc_vector_->setDirection(direction_);
133 | acc_vector_->set(
134 | arrow_length_ * scale_,
135 | arrow_radius_ * scale_,
136 | head_length_ * scale_,
137 | head_radius_ * scale_);
138 | }
139 | }
140 |
141 | void ImuAccVisual::setColor(const QColor& color)
142 | {
143 | color_ = color;
144 | if (acc_vector_)
145 | acc_vector_->setColor(color_.redF(), color_.greenF(), color_.blueF(), alpha_);
146 | }
147 |
148 | void ImuAccVisual::setAlpha(float alpha)
149 | {
150 | alpha_ = alpha;
151 | if (acc_vector_)
152 | acc_vector_->setColor(color_.redF(), color_.greenF(), color_.blueF(),alpha_);
153 | }
154 |
155 | void ImuAccVisual::setDerotated(bool derotated)
156 | {
157 | derotated_ = derotated;
158 | if (acc_vector_)
159 | acc_vector_->setColor(color_.redF(), color_.greenF(), color_.blueF(),alpha_);
160 | }
161 |
162 | void ImuAccVisual::setFramePosition(const Ogre::Vector3& position)
163 | {
164 | frame_node_->setPosition(position);
165 | }
166 |
167 | void ImuAccVisual::setFrameOrientation(const Ogre::Quaternion& orientation)
168 | {
169 | frame_node_->setOrientation(orientation);
170 | }
171 |
172 | } // end namespace rviz
173 |
174 |
--------------------------------------------------------------------------------
/multi_goal/src/goal_loop.py:
--------------------------------------------------------------------------------
1 | #coding:utf-8
2 | from geometry_msgs.msg import PoseStamped, Pose
3 | #!/usr/bin/env python
4 | import rospy
5 | import string
6 | import math
7 | import time
8 | import sys
9 | import csv
10 | import numpy as np
11 | from nav_msgs.msg import Odometry
12 | from std_msgs.msg import String, Float64
13 | from move_base_msgs.msg import MoveBaseActionResult
14 | from actionlib_msgs.msg import GoalStatusArray
15 | from geometry_msgs.msg import PoseStamped, PoseWithCovarianceStamped
16 |
17 | #repeat the route use for test
18 | #功能:循环导航
19 | #csv要求 第一个点是起点下一个点,终点是起点 1230
20 | class MultiGoals:
21 | def __init__(self, goalListX, goalListY, retry, map_frame):
22 | self.retry = 1
23 | if(self.retry == 1):
24 | #self.sub = rospy.Subscriber('move_base/result', MoveBaseActionResult, self.statusCB, queue_size=1)
25 | self.pub = rospy.Publisher(
26 | 'move_base_simple/goal', PoseStamped, queue_size=10)
27 | #self.pose_ekf = rospy.Subscriber('/odometry/filtered',Odometry,self.getPose_ekf,queue_size=10)
28 | self.pose_amcl = rospy.Subscriber(
29 | "/amcl_pose", PoseWithCovarianceStamped, self.getPose_amcl, queue_size=10)
30 | # params & variables
31 | self.pub_final = rospy.Publisher('/arrfinal', Float64, queue_size=1)
32 | self.goalListX = goalListX
33 | self.goalListY = goalListY
34 | self.goalListW = goalListW
35 | self.goalListZ = goalListZ
36 | self.kx = 0
37 | self.ky = 0
38 | self.gx = 0
39 | self.gy = 0
40 | self.flag = 1
41 | self.MIN_DISTANCE = 1.5 # min distance of the judge between the goal and odometrypose
42 | self.LONG = len(self.goalListX)
43 | self.goalId = 0
44 | self.count = 0
45 | self.start_time = 0
46 | self.pubfinal = False
47 | self.goalMsg = PoseStamped()
48 | self.goalMsg.header.frame_id = map_frame
49 |
50 | time.sleep(1)
51 | self.goalMsg.header.stamp = rospy.Time.now()
52 | self.goalMsg.pose.position.x = self.goalListX[self.goalId]
53 | self.goalMsg.pose.position.y = self.goalListY[self.goalId]
54 | self.goalMsg.pose.orientation.z = self.goalListZ[self.goalId]
55 | self.goalMsg.pose.orientation.w = self.goalListW[self.goalId]
56 | self.pub.publish(self.goalMsg)
57 | # print(self.goalMsg)
58 | self.start_time = rospy.get_time()
59 | rospy.loginfo(
60 | "Initial goal published! Goal ID is: %d", self.goalId)
61 | self.goalId = self.goalId + 1
62 |
63 | def statusCB(self):
64 | if self.pubfinal == True:
65 | self.pub_final.publish(1.0)
66 | print("the final goal")
67 |
68 | self.gx = self.goalListX[self.goalId-1] if(self.goalId != 0) else self.goalListX[self.goalId]
69 | self.gy = self.goalListY[self.goalId-1] if(self.goalId != 0) else self.goalListY[self.goalId]
70 |
71 | self.dist = self.distance(self.kx, self.ky, self.gx, self.gy)
72 |
73 | if self.dist < self.MIN_DISTANCE and self.flag == 1:
74 |
75 | finish_time = rospy.get_time()
76 | interval = finish_time - self.start_time
77 | print(interval)
78 | if self.goalId == self.LONG:
79 | self.goalId = 0
80 | self.goalMsg.header.stamp = rospy.Time.now()
81 | self.goalMsg.pose.position.x = self.goalListX[self.goalId]
82 | self.goalMsg.pose.position.y = self.goalListY[self.goalId]
83 | self.goalMsg.pose.orientation.z = self.goalListZ[self.goalId]
84 | self.goalMsg.pose.orientation.w = self.goalListW[self.goalId]
85 | self.pub.publish(self.goalMsg)
86 | rospy.loginfo(
87 | "Initial goal published! Goal ID is: %d", self.goalId)
88 | rospy.loginfo("intostatusCB")
89 | self.count = self.count+1
90 | print(self.count)
91 |
92 | if self.goalId < (len(self.goalListX)):
93 | self.goalId = self.goalId + 1
94 |
95 | else:
96 | self.goalId = 0
97 | print("final")
98 |
99 | def getPose_ekf(self, data):
100 | self.kx = data.pose.pose.position.x
101 | self.ky = data.pose.pose.position.y
102 | self.statusCB()
103 |
104 | def getPose_amcl(self, data):
105 | self.kx = data.pose.pose.position.x
106 | self.ky = data.pose.pose.position.y
107 | self.statusCB()
108 |
109 | def distance(self, kx, ky, gx, gy):
110 | try:
111 | return math.sqrt((kx-gx)**2+(ky-gy)**2)
112 | except:
113 | return None
114 |
115 |
116 |
117 | if __name__ == "__main__":
118 | try:
119 | # ROS Init
120 | rospy.init_node('multi_goals', anonymous=True)
121 | retry = 1
122 | goalList = []
123 | goalListX=[]
124 | goalListY=[]
125 | goalListZ=[]
126 | goalListW=[]
127 | map_frame = rospy.get_param('~map_frame', 'map' )
128 |
129 | with open('test.csv', 'r') as f:
130 | reader = csv.reader(f)
131 |
132 | for cols in reader:
133 | goalList.append([float(value) for value in cols])
134 |
135 | goalList = np.array(goalList)
136 | print("read suc!!")
137 | goalListX = goalList[:,0]
138 | goalListY = goalList[:,1]
139 | goalListZ = goalList[:,2]
140 | goalListW = goalList[:,3]
141 |
142 |
143 | if len(goalListX) == len(goalListY) & len(goalListY) >= 1:
144 | # Constract MultiGoals Obj
145 | rospy.loginfo("Multi Goals Executing...")
146 | mg = MultiGoals(goalListX, goalListY, retry, map_frame)
147 | rospy.spin()
148 | else:
149 | rospy.loginfo("Lengths of goal lists are not the same")
150 | except KeyboardInterrupt:
151 | print("shutting down")
152 |
153 |
154 |
--------------------------------------------------------------------------------
/racecar/src/racecar_teleop.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import rospy
4 |
5 | from geometry_msgs.msg import Twist
6 |
7 | import sys, select, termios, tty
8 | import time
9 |
10 | msg = """
11 | Control Your racecar!
12 | Reading from the keyboard and Publishing to Twist!
13 | ---------------------------
14 | Moving around:
15 | u i o
16 | j k l
17 | m , .
18 |
19 | For Holonomic mode (strafing), hold down the shift key:
20 | ---------------------------
21 | U I O
22 | J K L
23 | M < >
24 |
25 | space key, k : force stop
26 | w/x: shift the middle pos of throttle by +/- 5 pwm
27 | a/d: shift the middle pos of steering by +/- 2 pwm
28 | CTRL-C to quit
29 | """
30 |
31 | moveBindings = {
32 | 'i':(1,0),
33 | 'o':(1,-1),
34 | 'j':(0,1),
35 | 'l':(0,-1),
36 | 'u':(1,1),
37 | ',':(-1,0),
38 | '.':(-1,-1),
39 | 'm':(-1,1),
40 | 'I':(1,0),
41 | 'O':(1,-1),
42 | 'J':(0,1),
43 | 'L':(0,-1),
44 | 'U':(1,1),
45 | '<':(-1,0),
46 | '>':(-1,-1),
47 | 'M':(-1,1),
48 | }
49 |
50 |
51 | def getKey():
52 | tty.setraw(sys.stdin.fileno())
53 | rlist, _, _ = select.select([sys.stdin], [], [], 0.1)
54 | if rlist:
55 | key = sys.stdin.read(1)
56 | else:
57 | key = ''
58 |
59 | termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
60 | return key
61 |
62 |
63 | def vels(speed,turn):
64 | return "currently:\tspeed %s\tturn %s " % (speed,turn)
65 |
66 | if __name__=="__main__":
67 | settings = termios.tcgetattr(sys.stdin)
68 |
69 | rospy.init_node('racecar_teleop')
70 | pub = rospy.Publisher('~/car/cmd_vel', Twist, queue_size=5)
71 |
72 | speed_start_value =150 # can roll
73 | turn_start_value = 60 # max value
74 | speed_mid = 1500
75 | turn_mid = 90
76 | speed_bias = 0
77 | turn_bias = 0
78 | speed_add_once = 5
79 | turn_add_once = 2
80 | control_speed = speed_mid
81 | control_turn = turn_mid
82 | speed_dir = 0
83 | last_speed_dir = 0
84 | last_turn_dir = 0
85 | last_control_speed = control_speed
86 | last_control_turn = control_turn
87 |
88 | run = 0
89 |
90 | try:
91 | while(1):
92 | key = getKey()
93 | twist = Twist()
94 | if key in moveBindings.keys():
95 | run = 1
96 |
97 | #print "key =",key
98 | speed_dir = moveBindings[key][0]
99 | if(speed_dir!=0 and speed_dir + last_speed_dir == 0):#Reverse
100 | control_speed = speed_mid
101 | last_speed_dir = speed_dir
102 | control_turn = turn_mid
103 | #print "Reverse"
104 | else:
105 | if(speed_dir > 0):
106 | control_speed = speed_dir * (speed_start_value + speed_bias) + speed_mid
107 | elif(speed_dir < 0):
108 | control_speed = speed_dir * (speed_start_value + speed_bias) + speed_mid - 140
109 | else:
110 | control_speed = 1500
111 |
112 | control_turn = moveBindings[key][1] * (turn_start_value + turn_bias)+ turn_mid
113 | last_speed_dir = speed_dir
114 |
115 | #print " "
116 | #print "speed_dir = ",speed_dir
117 | #print "control_speed = ",control_speed
118 | #print "control_turn = ",control_turn
119 | last_control_speed = control_speed
120 | last_control_turn = control_turn
121 | elif key == ' ' or key == 'k' :
122 | speed_dir = -speed_dir #for ESC Forward/Reverse with brake mode
123 | control_speed = last_control_speed * speed_dir
124 | control_turn = turn_mid
125 | run = 0
126 | elif key == 'w' :
127 | speed_bias += speed_add_once
128 | if(speed_bias >= 450):
129 | speed_bias = 450
130 | else:
131 | last_control_speed = last_control_speed+speed_add_once
132 | run = 0
133 | elif key == 's' :
134 | speed_bias -= speed_add_once
135 | last_control_speed = last_control_speed-speed_add_once
136 | if(speed_bias <= 0):
137 | speed_bias = 0
138 | run = 0
139 | elif key == 'a' :
140 | turn_bias += turn_add_once
141 | last_control_turn = last_control_turn+turn_add_once
142 | if(turn_bias >= 80):
143 | turn_bias = 80
144 | run = 0
145 | elif key == 'd' :
146 | turn_bias -= turn_add_once
147 | last_control_turn = last_control_turn-turn_add_once
148 | if(turn_bias <= 0):
149 | turn_bias = 0
150 | run = 0
151 | else:
152 | run = 0
153 | print (vels(control_speed,control_turn))
154 | #print "speed_dir=",speed_dir,"last_speed_dir",last_speed_dir
155 | if(run == 1):
156 | twist.linear.x = control_speed; twist.linear.y = 0; twist.linear.z = 0
157 | twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = control_turn
158 | #print "control_speed =",control_speed
159 | pub.publish(twist)
160 | else:
161 | twist.linear.x = speed_mid; twist.linear.y = 0; twist.linear.z = 0
162 | twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = turn_mid
163 | pub.publish(twist)
164 |
165 | if (key == '\x03'): #for ctrl + c exit
166 | break
167 |
168 | except:
169 | print ("error")
170 |
171 | finally:
172 | twist = Twist()
173 | twist.linear.x = speed_mid; twist.linear.y = 0; twist.linear.z = 0
174 | twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = turn_mid
175 | pub.publish(twist)
176 |
177 | termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
178 |
--------------------------------------------------------------------------------
/encoder_driver/src/imu_encoder_mix.cpp:
--------------------------------------------------------------------------------
1 | #include "ros/ros.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #define PI 3.14159
22 | using namespace std;
23 | using namespace message_filters;
24 | using namespace sensor_msgs;
25 | ros::Time current_time,last_time;
26 | double x = 0.0;
27 | double y = 0.0;
28 | double s = 0.0;
29 | double th = 0.0;
30 | double vth = 0.0;
31 | double th_init = 0.0;
32 | static double theta_first= 0.0;
33 | static bool flag = true;
34 | ros::Publisher encoder_imu_pub;
35 |
36 |
37 | //从车身姿态获取航向角
38 | double getYawFromPose(const sensor_msgs::Imu::ConstPtr &carPose) {
39 | //odom=*odom_cb;
40 | //geometry_msgs::Pose carPose = odom.pose.pose;
41 | sensor_msgs::Imu imu=(*carPose);
42 | float x = imu.orientation.x;
43 | float y = imu.orientation.y;
44 | float z = imu.orientation.z;
45 | float w = imu.orientation.w;
46 |
47 | double tmp, yaw;
48 | tf::Quaternion q(x, y, z, w);
49 | tf::Matrix3x3 quaternion(q);
50 | quaternion.getRPY(tmp, tmp, yaw);
51 |
52 | return yaw;
53 | }
54 | double getrollFromPose(const sensor_msgs::Imu::ConstPtr &carPose) {
55 | //odom=*odom_cb;
56 | //geometry_msgs::Pose carPose = odom.pose.pose;
57 | sensor_msgs::Imu imu=(*carPose);
58 | float x = imu.orientation.x;
59 | float y = imu.orientation.y;
60 | float z = imu.orientation.z;
61 | float w = imu.orientation.w;
62 |
63 | double roll,pitch, yaw;
64 | tf::Quaternion q(x, y, z, w);
65 | tf::Matrix3x3 quaternion(q);
66 | quaternion.getRPY(roll, pitch, yaw);
67 |
68 | return roll;
69 | }
70 | double getpitchFromPose(const sensor_msgs::Imu::ConstPtr &carPose) {
71 | //odom=*odom_cb;
72 | //geometry_msgs::Pose carPose = odom.pose.pose;
73 | sensor_msgs::Imu imu=(*carPose);
74 | float x = imu.orientation.x;
75 | float y = imu.orientation.y;
76 | float z = imu.orientation.z;
77 | float w = imu.orientation.w;
78 |
79 | double roll,pitch, yaw;
80 | tf::Quaternion q(x, y, z, w);
81 | tf::Matrix3x3 quaternion(q);
82 | quaternion.getRPY(roll, pitch, yaw);
83 |
84 | return pitch;
85 | }
86 | void callback(const sensor_msgs::Imu::ConstPtr& imu_data,const nav_msgs::Odometry::ConstPtr& speed)
87 | {
88 | if(flag==true)
89 | {
90 | theta_first=getYawFromPose(imu_data);
91 | flag=false;
92 | }
93 |
94 | if(flag==false)
95 | {
96 | double v=(*speed).twist.twist.linear.x;
97 | double theta=getYawFromPose(imu_data);
98 | double roll=getrollFromPose(imu_data);
99 | double pitch=getpitchFromPose(imu_data);
100 | theta = theta - theta_first;
101 |
102 | th_init = theta_first*180/PI;
103 | th = theta*180/PI;//转换成角度
104 |
105 | // if(th_init > 0) {if(th < -180) th += 360;}
106 | // if(th_init < 0) {if(th > 180 ) th -= 360;}
107 | double vx=v*cos(th/180*PI);
108 | double vy=v*sin(th/180*PI);
109 | current_time=ros::Time::now();
110 | double dt=(current_time-last_time).toSec();
111 | double delta_x = vx* dt;
112 | double delta_y = vy* dt;
113 | double delta_th = vth * dt;//0
114 | ROS_INFO("v :%.4f",v);
115 | //ROS_INFO("theta:%.4f",theta*180/PI);
116 | ROS_INFO("theta:%.4f",th);
117 |
118 |
119 | x+=delta_x;
120 | y+=delta_y;
121 | s = sqrt(x*x+y*y);
122 | ROS_INFO("lenth:%.1f",s*100);
123 | //th += delta_th;
124 | //定义odom发布需要的转换戳和位置
125 |
126 | // tf::TransformBroadcaster odom_broadcaster;
127 | // geometry_msgs::TransformStamped odom_trans;
128 | // odom_trans.header.stamp=current_time;
129 | // odom_trans.header.frame_id="odom";
130 | // odom_trans.child_frame_id="base_footprint";
131 |
132 | // odom_trans.transform.translation.x = x;
133 | // odom_trans.transform.translation.y = y;
134 | // odom_trans.transform.translation.z = 0.0;
135 | // odom_trans.transform.rotation = tf::createQuaternionMsgFromYaw(theta);
136 | // //将角度转换成旋转矩阵
137 |
138 | // odom_broadcaster.sendTransform(odom_trans);
139 |
140 | //然后发送里程计信息 发布者odom_pub
141 | nav_msgs::Odometry odom;
142 | odom.header.stamp=current_time;
143 | odom.header.frame_id="odom";
144 | odom.child_frame_id="base_footprint";
145 | geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromRollPitchYaw(roll,pitch,theta);
146 |
147 | odom.pose.pose.position.x = x;
148 | odom.pose.pose.position.y = y;
149 | odom.pose.pose.position.z = 0.0;
150 | odom.pose.pose.orientation = odom_quat;
151 |
152 | odom.twist.twist.linear.x = vx;
153 | odom.twist.twist.linear.y = vy;
154 | odom.twist.twist.angular.z = 0;
155 |
156 | encoder_imu_pub.publish(odom);
157 |
158 | last_time=current_time;
159 | }
160 | // ros::spinOnce();
161 |
162 | }
163 |
164 | int main(int argc,char** argv)
165 | {
166 | //启动节点订阅消息
167 | ros::init(argc,argv,"encoder_imu_mix");
168 | ros::NodeHandle nh;
169 | message_filters::Subscriber imu_sub(nh,"/imu_data",100);
170 | message_filters::Subscriber encoder_sub(nh,"/encoder",20);
171 | ROS_INFO("-------");
172 | //创建发布后融合的消息的节点
173 | encoder_imu_pub = nh.advertise("/encoder_imu_odom",10);
174 | //定义同步消息储存器 精确时间戳 大概时间戳
175 | //typedef sync_policies::ApproximateTime MySyncPolicy;
176 | typedef sync_policies::ApproximateTime MySyncPolicy;
177 |
178 | //typedef sync_policies::ExactTime MySyncPolicy;
179 | Synchronizer sync(MySyncPolicy(10),imu_sub,encoder_sub);
180 | sync.registerCallback(boost::bind(&callback,_1,_2));
181 | ros::spin();
182 | return 0;
183 | }
184 | //回调函数的创建 callback
185 |
186 | // biaoding
--------------------------------------------------------------------------------
/imu_tool/rviz_imu_plugin/src/imu_display.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012, Willow Garage, Inc.
3 | * Copyright (c) 2012, Ivan Dryanovski
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the Willow Garage, Inc. nor the names of its
15 | * contributors may be used to endorse or promote products derived from
16 | * this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 | * POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #ifndef RVIZ_IMU_PLUGIN_IMU_DISPLAY_H
32 | #define RVIZ_IMU_PLUGIN_IMU_DISPLAY_H
33 |
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 |
46 | #include
47 | #include
48 | #include
49 | #include
50 | #include
51 |
52 | #include "imu_axes_visual.h"
53 | #include "imu_orientation_visual.h"
54 | #include "imu_acc_visual.h"
55 |
56 | namespace Ogre
57 | {
58 | class SceneNode;
59 | }
60 |
61 | namespace rviz
62 | {
63 |
64 | class ImuDisplay: public rviz::MessageFilterDisplay
65 | {
66 | Q_OBJECT
67 | public:
68 |
69 | ImuDisplay();
70 | virtual ~ImuDisplay();
71 |
72 | virtual void onInitialize();
73 | virtual void onEnable();
74 | virtual void onDisable();
75 | virtual void reset();
76 | virtual void createProperties();
77 |
78 | void setTopic(const std::string& topic);
79 | const std::string& getTopic() { return topic_; }
80 |
81 | void setBoxEnabled(bool enabled);
82 | void setBoxScaleX(float x);
83 | void setBoxScaleY(float y);
84 | void setBoxScaleZ(float z);
85 | void setBoxColor(const Color& color);
86 | void setBoxAlpha(float alpha);
87 |
88 | void setAxesEnabled(bool enabled);
89 | void setAxesScale(float scale);
90 |
91 | void setAccEnabled(bool enabled);
92 | void setAccDerotated(bool derotated);
93 | void setAccScale(float scale);
94 | void setAccColor(const Color& color);
95 | void setAccAlpha(float alpha);
96 |
97 | bool getBoxEnabled() { return box_enabled_; }
98 | float getBoxScaleX() { return box_visual_->getScaleX(); }
99 | float getBoxScaleY() { return box_visual_->getScaleY(); }
100 | float getBoxScaleZ() { return box_visual_->getScaleZ(); }
101 | float getBoxAlpha() { return box_visual_->getAlpha(); }
102 | const QColor& getBoxColor() { return box_visual_->getColor(); }
103 |
104 | bool getAxesEnabled() { return axes_enabled_; }
105 | float getAxesScale() { return axes_visual_->getScale(); }
106 |
107 | bool getAccEnabled() { return acc_enabled_; }
108 | float getAccDerotated() { return acc_visual_->getDerotated(); }
109 | float getAccScale() { return acc_visual_->getScale(); }
110 | float getAccAlpha() { return acc_visual_->getAlpha(); }
111 | const QColor& getAccColor() { return acc_visual_->getColor(); }
112 |
113 | protected Q_SLOTS:
114 |
115 | void updateTop();
116 | void updateBox();
117 | void updateAxes();
118 | void updateAcc();
119 |
120 | private:
121 |
122 | // Property objects for user-editable properties.
123 | rviz::BoolProperty* fixed_frame_orientation_property_;
124 |
125 | rviz::Property* box_category_;
126 | rviz::Property* axes_category_;
127 | rviz::Property* acc_category_;
128 |
129 | // rviz::RosTopicProperty* topic_property_;
130 | rviz::BoolProperty* box_enabled_property_;
131 | rviz::FloatProperty* box_scale_x_property_;
132 | rviz::FloatProperty* box_scale_y_property_;
133 | rviz::FloatProperty* box_scale_z_property_;
134 | rviz::ColorProperty* box_color_property_;
135 | rviz::FloatProperty* box_alpha_property_;
136 |
137 | rviz::BoolProperty* axes_enabled_property_;
138 | rviz::FloatProperty* axes_scale_property_;
139 |
140 | rviz::BoolProperty* acc_enabled_property_;
141 | rviz::BoolProperty* acc_derotated_property_;
142 | rviz::FloatProperty* acc_scale_property_;
143 | rviz::ColorProperty* acc_color_property_;
144 | rviz::FloatProperty* acc_alpha_property_;
145 |
146 | // Differetn types of visuals
147 | ImuOrientationVisual * box_visual_;
148 | ImuAxesVisual * axes_visual_;
149 | ImuAccVisual * acc_visual_;
150 |
151 | // User-editable property variables.
152 | std::string topic_;
153 | bool fixed_frame_orientation_;
154 | bool box_enabled_;
155 | bool axes_enabled_;
156 | bool acc_enabled_;
157 |
158 | // A node in the Ogre scene tree to be the parent of all our visuals.
159 | Ogre::SceneNode* scene_node_;
160 |
161 | int messages_received_;
162 |
163 | // Function to handle an incoming ROS message.
164 | void processMessage( const sensor_msgs::Imu::ConstPtr& msg);
165 |
166 | };
167 |
168 | } // end namespace rviz
169 |
170 | #endif // IMU_DISPLAY_H
171 |
172 |
--------------------------------------------------------------------------------
/serial_imu/src/serial_imu.cpp:
--------------------------------------------------------------------------------
1 | //serial_imu.cpp
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #ifdef __cplusplus
18 | extern "C"{
19 | #endif
20 |
21 | #include
22 | #include
23 | #include "packet.h"
24 | #include "imu_data_decode.h"
25 |
26 | #define IMU_SERIAL "/dev/ttyUSB0"
27 | #define BAUD (115200)
28 | #define GRA_ACC (9.8)
29 | #define DEG_TO_RAD (0.01745329)
30 | #define BUF_SIZE 1024
31 |
32 | int imu_data_decode_init(void);
33 | typedef void (*on_data_received_event)(packet_t *ptr);
34 | void packet_decode_init(packet_t *pkt, on_data_received_event rx_handler);
35 | uint32_t packet_decode(uint8_t);
36 | void publish_0x91_data(id0x91_t *data, serial_imu::Imu_0x91_msg *data_imu);
37 | void publish_imu_data(id0x91_t *data, sensor_msgs::Imu *imu_data);
38 | void publish_0x62_data(id0x62_t *data, serial_imu::Imu_0x62_msg *data_imu);
39 |
40 |
41 | #ifdef __cplusplus
42 | }
43 | #endif
44 |
45 | static int frame_rate;
46 |
47 | static uint8_t buf[2048];
48 |
49 | void timer(int sig)
50 | {
51 | if(SIGALRM == sig)
52 | {
53 | frame_rate = frame_count;
54 | frame_count = 0;
55 | alarm(1);
56 | }
57 | }
58 |
59 | int main(int argc, char** argv)
60 | {
61 | ros::init(argc, argv, "serial_imu");
62 | ros::NodeHandle n;
63 |
64 | ros::Publisher IMU_pub = n.advertise("/IMU_data", 20);
65 | ros::Publisher Imu_0x91_pub = n.advertise("/imu_0x91_package", 10);
66 | ros::Publisher Imu_0x62_pub = n.advertise("/imu_0x62_package", 10);
67 |
68 | serial::Serial sp;
69 |
70 | serial::Timeout to = serial::Timeout::simpleTimeout(100);
71 |
72 | sp.setPort(IMU_SERIAL);
73 |
74 | sp.setBaudrate(BAUD);
75 |
76 | sp.setTimeout(to);
77 |
78 |
79 | imu_data_decode_init();
80 | signal(SIGALRM,timer);
81 |
82 | try
83 | {
84 | sp.open();
85 | }
86 | catch(serial::IOException& e)
87 | {
88 | ROS_ERROR_STREAM("Unable to open port.");
89 | return -1;
90 | }
91 |
92 | if(sp.isOpen())
93 | {
94 | ROS_INFO_STREAM("/dev/ttyUSB0 is opened.");
95 | }
96 | else
97 | {
98 | return -1;
99 | }
100 |
101 | alarm(1);
102 |
103 | ros::Rate loop_rate(500);
104 | sensor_msgs::Imu imu_data;
105 | serial_imu::Imu_0x91_msg imu_0x91_msg;
106 | serial_imu::Imu_0x62_msg imu_0x62_msg;
107 |
108 | while(ros::ok())
109 | {
110 | size_t num = sp.available();
111 | if(num!=0)
112 | {
113 | uint8_t buffer[BUF_SIZE];
114 |
115 | if(num > BUF_SIZE)
116 | num = BUF_SIZE;
117 |
118 | num = sp.read(buffer, num);
119 | if(num > 0)
120 | {
121 | for(int i = 0; i < num; i++)
122 | packet_decode(buffer[i]);
123 |
124 | if (bitmap & 0xff)
125 | {
126 |
127 | imu_data.header.stamp = ros::Time::now();
128 | imu_data.header.frame_id = "base_link";
129 |
130 | imu_0x91_msg.header.stamp = ros::Time::now();
131 | imu_0x91_msg.header.frame_id = "base_0x91_link";
132 |
133 | imu_0x62_msg.header.stamp = ros::Time::now();
134 | imu_0x62_msg.header.frame_id = "base_0x62_link";
135 |
136 | if(id0x62.tag != KItemGWSOL)
137 | {
138 | publish_0x91_data(&id0x91, &imu_0x91_msg);
139 | Imu_0x91_pub.publish(imu_0x91_msg);
140 |
141 | publish_imu_data(&id0x91, &imu_data);
142 | IMU_pub.publish(imu_data);
143 | }
144 | else
145 | {
146 |
147 | publish_0x62_data(&id0x62, &imu_0x62_msg);
148 |
149 | Imu_0x62_pub.publish(imu_0x62_msg);
150 |
151 |
152 | }
153 | }
154 | }
155 | }
156 | loop_rate.sleep();
157 | }
158 |
159 | sp.close();
160 |
161 | return 0;
162 | }
163 |
164 |
165 | //void publish_0x91_data(id0x91_t *data, serial_imu::Imu_0x91_msg *data_imu)
166 | void memcpy_imu_data_package(id0x91_t *data, serial_imu::Imu_data_package *data_imu)
167 | {
168 | data_imu->tag = data->tag;
169 | data_imu->bitmap = bitmap;
170 | if(bitmap & BIT_VALID_ID)
171 | data_imu->id = data->id;
172 |
173 | if(bitmap & BIT_VALID_TIME)
174 | data_imu->time = data->time;
175 |
176 | data_imu->frame_rate = frame_rate;
177 |
178 | //data_imu->frame_rate = crc_error_count;
179 | if(bitmap & BIT_VALID_ACC)
180 | {
181 | data_imu->acc_x = data->acc[0];
182 | data_imu->acc_y = data->acc[1];
183 | data_imu->acc_z = data->acc[2];
184 | }
185 |
186 | if(bitmap & BIT_VALID_GYR)
187 | {
188 | data_imu->gyr_x = data->gyr[0];
189 | data_imu->gyr_y = data->gyr[1];
190 | data_imu->gyr_z = data->gyr[2];
191 | }
192 |
193 | if(bitmap & BIT_VALID_MAG)
194 | {
195 | data_imu->mag_x = data->mag[0];
196 | data_imu->mag_y = data->mag[1];
197 | data_imu->mag_z = data->mag[2];
198 | }
199 |
200 | if(bitmap & BIT_VALID_EUL)
201 | {
202 | data_imu->eul_r = data->eul[0];
203 | data_imu->eul_p = data->eul[1];
204 | data_imu->eul_y = data->eul[2];
205 | }
206 |
207 | if(bitmap & BIT_VALID_QUAT)
208 | {
209 | data_imu->quat_w = data->quat[0];
210 | data_imu->quat_x = data->quat[1];
211 | data_imu->quat_y = data->quat[2];
212 | data_imu->quat_z = data->quat[3];
213 | }
214 | }
215 |
216 | void publish_imu_data(id0x91_t *data, sensor_msgs::Imu *imu_data)
217 | {
218 | imu_data->orientation.x = data->quat[1];
219 | imu_data->orientation.y = data->quat[2];
220 | imu_data->orientation.z = data->quat[3];
221 | imu_data->orientation.w = data->quat[0];
222 | imu_data->angular_velocity.x = data->gyr[0] * DEG_TO_RAD;
223 | imu_data->angular_velocity.y = data->gyr[1] * DEG_TO_RAD;
224 | imu_data->angular_velocity.z = data->gyr[2] * DEG_TO_RAD;
225 | imu_data->linear_acceleration.x = data->acc[0] * GRA_ACC;
226 | imu_data->linear_acceleration.y = data->acc[1] * GRA_ACC;
227 | imu_data->linear_acceleration.z = data->acc[2] * GRA_ACC;
228 | }
229 |
230 | void publish_0x91_data(id0x91_t *data, serial_imu::Imu_0x91_msg *data_imu)
231 | {
232 | memcpy_imu_data_package(data,&(data_imu->imu_data));
233 | }
234 |
235 | void publish_0x62_data(id0x62_t *data, serial_imu::Imu_0x62_msg *data_imu)
236 | {
237 | /* */
238 | data_imu->tag = data->tag;
239 | data_imu->gw_id = data->gw_id;
240 | data_imu->node_num = data->n;
241 |
242 | for (int i = 0; i < data_imu->node_num; i++)
243 | memcpy_imu_data_package(&(data->id0x91[i]), &(data_imu->node_data[i]));
244 |
245 |
246 | }
247 |
--------------------------------------------------------------------------------