Merge pull request 'main' (#9) from ray/RobotKernal-UESTC:main into main

合并瑞瑞提交,将不同的功能包放在pibot下面
main
詹力 2024-03-11 10:35:32 +08:00
commit 7bb2ee4d5f
1140 changed files with 9210 additions and 26660 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

View File

@ -1,93 +0,0 @@
# `PIBot_ROS`使用说明
> `pibot`是银星合作时购买的小车底盘。其包含直流电机控制、里程计、IMU和上位机通讯等功能。
## 1、远程连接`RK3588`板子
我们是通过`RK3588 & RK3566`等高性能的主板控制`PIBot`下位机(`STM32`控制板)。如果直接采用`HDMI`线和`USB`鼠标和键盘进行控制非常的不便; 采用`VNC`等远程桌面的方式对性能的损耗较大所以采用远程ssh连接一种较好的方式。这里**我们采用的`vscode`进行ssh远程连接**, 其具有远程图形显示功能以及其他强大的功能。
`ssh`连接需要知道目标机器的`ip`地址。理论上如果知道开发板的外网`IP`地址,那么就可以在任意位置连接开发板。由于外网固定`IP`难以获取,所以这里我们**采用局域网ssh连接**。由于`windows`平台的渲染窗口和`linux`不兼容,所以**windows平台的vscode是不支持ssh窗口显示的需要开启虚拟机或者`linux`主机下面的`vscode`才可以显示窗口**。我们在虚拟机`ubuntu`里面使用`vscode`远程`ssh`连接`RK3588`和虚拟机需要用同个网络,远程连接[教程](http://www.autolabor.com.cn/book/ROSTutorials/di-9-zhang-ji-qi-ren-dao-822a28-shi-4f5329/92-vscodeyuan-cheng-kai-fa.html)
1. `ip`查询方式终端: 在小车终端里输入 `ifconfig`查看小车的ip地址
2. 将教程里步骤三内容改为:
3. `ssh -X firefly@ip` -X 为远程显示图形界面需要)
4. 密码为:`firefly`
5. 连接上后选择需要打开的文件夹
## 2、小车驱动编译
#### 2.1 驱动代码位置
`PIBot`的ROS支持包的位置在[仓库]([RobotKernal-UESTC](http://logzhan.ticp.io:30000/logzhan/RobotKernal-UESTC))中,其路径为`Code\RK3588\PIbot_ROS`中。我们解压后可以把`PIBot_ROS`移动到`~/`位置,并重新命名为`pibot_ros`(命名可以按照个人习惯),下面的教程以`pibot_ros`为例。
#### 2.2 3588上编译问题主要是全覆盖部分
`PIBot_ROS/ros_ws/src/ipa_coverage_planning`(全覆盖部分的代码)
```shell
# 进入到ROS的工作空间
cd pibot_ros/ros_ws
# 在pibot_ros/ros_ws路径下执行catkin_make
# ~:/pibot_ros/ros_ws$ catkin_make
catkin_make
```
#### 2.3 根据出现的报错缺少的库问题解决
```shell
# noetic 是ubuntu20.04版本名,其他版本需要更换名字
sudo apt-get install ros-noetic-xxx
# 例如sudo apt-get install ros-noetic-opengm
sudo apt-get install ros-noetic-libdlib
sudo apt-get install ros-noetic-cob-navigation
sudo apt-get install coinor-*
```
可参考内容:
> [全覆盖规划算法Coverage Path Planning开源代码ipa_coverage_planning编译-CSDN博客](https://blog.csdn.net/ktigerhero3/article/details/121562049)
>
> [ROS全覆盖规划算法 Coverage Path Planning 采坑-CSDN博客](https://blog.csdn.net/weixin_42179076/article/details/121164350)
## 3、使用说明
#### 3.1 导航的启动
`PIBot_ROS`的文件解压或重新命名可以按照个人习惯即可,这里以解压后命名为`pibot_ros`为例,介绍命令启动导航。
```shell
# 进入到pibot_ros的工作空间
cd ~/pibot_ros/ros_ws
# 配置环境变量
source ./devel/setup.bash
# 启动导航文件
# 格式 roslaunch package_name launch_file_name
roslaunch pibot_navigation nav.launch
```
#### 3.2 更改导航地图
根据导航需求更改导航地图,地图路径在下图左下角位置`pgm`为地图格式 `yaml`为配置文件:
<img src="./Image/ROS_Using (3).png" alt="Untitled" style="zoom:80%;" />
#### 3.3 小车控制和可视化
小车的控制和可视化功能需要**开启两个新的终端,分别在终端输入命令**
```shell
# 小车的键盘控制,在任意路径执行:
pibot_control
```
```shell
# 导航可视化,在任意路径执行:
pibot_view (需要设置从主机 记不清 后面再补充)
```
在这上面可以在地图上给出目标点进行单点导航。
#### 3.4、全覆盖路径规划的使用

View File

@ -1,6 +0,0 @@
## ROS包功能说明:
> 更新时间2024/02/04@詹力
`ipa_coverage_planning` :新添加的全覆盖路径规划算法,这部分代码是原来`pibot`没有的。详细内容见包里面的`README.md`文档。

View File

@ -1,18 +0,0 @@
/*--------------------------------------------------------------
* Node Desc 1.IMU
2.IMU
3.IMU
* Review : zhanli.2024.02.28
---------------------------------------------------------------*/
#include "pibot_imu/pibot_imu.h"
int main(int argc, char **argv)
{
ros::init(argc, argv, "pibot_imu");
ros::NodeHandle nh, pnh("~");
PibotIMU pibot_imu(nh, pnh);
ros::spin();
return 0;
}

View File

@ -24,7 +24,23 @@ PIBot官方资料https://gitee.com/pibot/pibot_bringup/blob/master/doc/README
./runRoomExplorationServer.sh ./runRoomExplorationServer.sh
# 启动全覆盖地图客户端 # 启动全覆盖地图客户端
./runRoomExplorationClient.sh ./runRoomExplorationClient.sh
#自己建图(画圈)、地图的优化、跑全覆盖
#建图
UWB的
#地图优化
cd test_map
./main input_map_name output_map_name
#全覆盖客户端路径
cd pibot_ros/ros_ws
source ./devel/setup.bash
roslaunch ipa_room_exploration room_exploration_client.launch robot_env:=map_name
#修改地图路径
#优化地图
test_map 的main.cpp
#全覆盖
room_exploration_action_client.cpp 下面77行
``` ```

View File

@ -1 +0,0 @@
# This file currently only serves to mark the location of a catkin workspace for tool integration

View File

@ -1,2 +0,0 @@
/build/
/cmake-build-debug/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 296 KiB

View File

@ -1,32 +0,0 @@
# `UWB`建图指导
一、代码编译和运行
```shell
# 进入工程目录
cd Robot_ROS_Driver
# 代码的编译
catkin_make
# 环境变量引入
rosrun ros_merge_test ros_merge_test_node
```
线程在`main.cpp`中开启:
<img src=".\image\main.png" alt="image-20231212192507303" style="zoom: 67%;" />
主要功能是
uwb接收 uwb_trd
建图 map_trd
保存定位数据 align_trd
建图和保存数据需要哪个用哪个
建图在rosrun之后 出现的图片上按q开始建图再按一次q停止可以再同一幅图上重复开始和暂停
保存数据同样在rosrun之后出现的图片上按w开始保存 再按w停止

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
catkin_make

View File

@ -1 +0,0 @@
/home/luoruidi/Desktop/ros_learn/C++_Merge_Ros/merge_ros/src

View File

@ -1,2 +0,0 @@
- setup-file:
local-name: /home/luoruidi/Desktop/ros_learn/C++_Merge_Ros/merge_ros/devel/setup.sh

View File

@ -1,304 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Software License Agreement (BSD License)
#
# Copyright (c) 2012, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Willow Garage, Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""This file generates shell code for the setup.SHELL scripts to set environment variables."""
from __future__ import print_function
import argparse
import copy
import errno
import os
import platform
import sys
CATKIN_MARKER_FILE = '.catkin'
system = platform.system()
IS_DARWIN = (system == 'Darwin')
IS_WINDOWS = (system == 'Windows')
PATH_TO_ADD_SUFFIX = ['bin']
if IS_WINDOWS:
# while catkin recommends putting dll's into bin, 3rd party packages often put dll's into lib
# since Windows finds dll's via the PATH variable, prepend it with path to lib
PATH_TO_ADD_SUFFIX.extend([['lib', os.path.join('lib', 'x86_64-linux-gnu')]])
# subfolder of workspace prepended to CMAKE_PREFIX_PATH
ENV_VAR_SUBFOLDERS = {
'CMAKE_PREFIX_PATH': '',
'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': ['lib', os.path.join('lib', 'x86_64-linux-gnu')],
'PATH': PATH_TO_ADD_SUFFIX,
'PKG_CONFIG_PATH': [os.path.join('lib', 'pkgconfig'), os.path.join('lib', 'x86_64-linux-gnu', 'pkgconfig')],
'PYTHONPATH': 'lib/python3/dist-packages',
}
def rollback_env_variables(environ, env_var_subfolders):
"""
Generate shell code to reset environment variables.
by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH.
This does not cover modifications performed by environment hooks.
"""
lines = []
unmodified_environ = copy.copy(environ)
for key in sorted(env_var_subfolders.keys()):
subfolders = env_var_subfolders[key]
if not isinstance(subfolders, list):
subfolders = [subfolders]
value = _rollback_env_variable(unmodified_environ, key, subfolders)
if value is not None:
environ[key] = value
lines.append(assignment(key, value))
if lines:
lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH'))
return lines
def _rollback_env_variable(environ, name, subfolders):
"""
For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder.
:param subfolders: list of str '' or subfoldername that may start with '/'
:returns: the updated value of the environment variable.
"""
value = environ[name] if name in environ else ''
env_paths = [path for path in value.split(os.pathsep) if path]
value_modified = False
for subfolder in subfolders:
if subfolder:
if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)):
subfolder = subfolder[1:]
if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)):
subfolder = subfolder[:-1]
for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True):
path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_path
path_to_remove = None
for env_path in env_paths:
env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_path
if env_path_clean == path_to_find:
path_to_remove = env_path
break
if path_to_remove:
env_paths.remove(path_to_remove)
value_modified = True
new_value = os.pathsep.join(env_paths)
return new_value if value_modified else None
def _get_workspaces(environ, include_fuerte=False, include_non_existing=False):
"""
Based on CMAKE_PREFIX_PATH return all catkin workspaces.
:param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool``
"""
# get all cmake prefix paths
env_name = 'CMAKE_PREFIX_PATH'
value = environ[env_name] if env_name in environ else ''
paths = [path for path in value.split(os.pathsep) if path]
# remove non-workspace paths
workspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))]
return workspaces
def prepend_env_variables(environ, env_var_subfolders, workspaces):
"""Generate shell code to prepend environment variables for the all workspaces."""
lines = []
lines.append(comment('prepend folders of workspaces to environment variables'))
paths = [path for path in workspaces.split(os.pathsep) if path]
prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '')
lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix))
for key in sorted(key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH'):
subfolder = env_var_subfolders[key]
prefix = _prefix_env_variable(environ, key, paths, subfolder)
lines.append(prepend(environ, key, prefix))
return lines
def _prefix_env_variable(environ, name, paths, subfolders):
"""
Return the prefix to prepend to the environment variable NAME.
Adding any path in NEW_PATHS_STR without creating duplicate or empty items.
"""
value = environ[name] if name in environ else ''
environ_paths = [path for path in value.split(os.pathsep) if path]
checked_paths = []
for path in paths:
if not isinstance(subfolders, list):
subfolders = [subfolders]
for subfolder in subfolders:
path_tmp = path
if subfolder:
path_tmp = os.path.join(path_tmp, subfolder)
# skip nonexistent paths
if not os.path.exists(path_tmp):
continue
# exclude any path already in env and any path we already added
if path_tmp not in environ_paths and path_tmp not in checked_paths:
checked_paths.append(path_tmp)
prefix_str = os.pathsep.join(checked_paths)
if prefix_str != '' and environ_paths:
prefix_str += os.pathsep
return prefix_str
def assignment(key, value):
if not IS_WINDOWS:
return 'export %s="%s"' % (key, value)
else:
return 'set %s=%s' % (key, value)
def comment(msg):
if not IS_WINDOWS:
return '# %s' % msg
else:
return 'REM %s' % msg
def prepend(environ, key, prefix):
if key not in environ or not environ[key]:
return assignment(key, prefix)
if not IS_WINDOWS:
return 'export %s="%s$%s"' % (key, prefix, key)
else:
return 'set %s=%s%%%s%%' % (key, prefix, key)
def find_env_hooks(environ, cmake_prefix_path):
"""Generate shell code with found environment hooks for the all workspaces."""
lines = []
lines.append(comment('found environment hooks in workspaces'))
generic_env_hooks = []
generic_env_hooks_workspace = []
specific_env_hooks = []
specific_env_hooks_workspace = []
generic_env_hooks_by_filename = {}
specific_env_hooks_by_filename = {}
generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh'
specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None
# remove non-workspace paths
workspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))]
for workspace in reversed(workspaces):
env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d')
if os.path.isdir(env_hook_dir):
for filename in sorted(os.listdir(env_hook_dir)):
if filename.endswith('.%s' % generic_env_hook_ext):
# remove previous env hook with same name if present
if filename in generic_env_hooks_by_filename:
i = generic_env_hooks.index(generic_env_hooks_by_filename[filename])
generic_env_hooks.pop(i)
generic_env_hooks_workspace.pop(i)
# append env hook
generic_env_hooks.append(os.path.join(env_hook_dir, filename))
generic_env_hooks_workspace.append(workspace)
generic_env_hooks_by_filename[filename] = generic_env_hooks[-1]
elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext):
# remove previous env hook with same name if present
if filename in specific_env_hooks_by_filename:
i = specific_env_hooks.index(specific_env_hooks_by_filename[filename])
specific_env_hooks.pop(i)
specific_env_hooks_workspace.pop(i)
# append env hook
specific_env_hooks.append(os.path.join(env_hook_dir, filename))
specific_env_hooks_workspace.append(workspace)
specific_env_hooks_by_filename[filename] = specific_env_hooks[-1]
env_hooks = generic_env_hooks + specific_env_hooks
env_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspace
count = len(env_hooks)
lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count))
for i in range(count):
lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i]))
lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i]))
return lines
def _parse_arguments(args=None):
parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.')
parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context')
parser.add_argument('--local', action='store_true', help='Only consider this prefix path and ignore other prefix path in the environment')
return parser.parse_known_args(args=args)[0]
if __name__ == '__main__':
try:
try:
args = _parse_arguments()
except Exception as e:
print(e, file=sys.stderr)
sys.exit(1)
if not args.local:
# environment at generation time
CMAKE_PREFIX_PATH = r'/home/luoruidi/Desktop/ros_learn/communicat_01/src/commu_01/devel;/opt/ros/noetic'.split(';')
else:
# don't consider any other prefix path than this one
CMAKE_PREFIX_PATH = []
# prepend current workspace if not already part of CPP
base_path = os.path.dirname(__file__)
# CMAKE_PREFIX_PATH uses forward slash on all platforms, but __file__ is platform dependent
# base_path on Windows contains backward slashes, need to be converted to forward slashes before comparison
if os.path.sep != '/':
base_path = base_path.replace(os.path.sep, '/')
if base_path not in CMAKE_PREFIX_PATH:
CMAKE_PREFIX_PATH.insert(0, base_path)
CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH)
environ = dict(os.environ)
lines = []
if not args.extend:
lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS)
lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH)
lines += find_env_hooks(environ, CMAKE_PREFIX_PATH)
print('\n'.join(lines))
# need to explicitly flush the output
sys.stdout.flush()
except IOError as e:
# and catch potential "broken pipe" if stdout is not writable
# which can happen when piping the output to a file but the disk is full
if e.errno == errno.EPIPE:
print(e, file=sys.stderr)
sys.exit(2)
raise
sys.exit(0)

View File

@ -1,16 +0,0 @@
#!/usr/bin/env sh
# generated from catkin/cmake/templates/env.sh.in
if [ $# -eq 0 ] ; then
/bin/echo "Usage: env.sh COMMANDS"
/bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually."
exit 1
fi
# ensure to not use different shell type which was set before
CATKIN_SHELL=sh
# source setup.sh from same directory as this file
_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd)
. "$_CATKIN_SETUP_DIR/setup.sh"
exec "$@"

View File

@ -1,8 +0,0 @@
#!/usr/bin/env bash
# generated from catkin/cmake/templates/local_setup.bash.in
CATKIN_SHELL=bash
# source setup.sh from same directory as this file
_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)
. "$_CATKIN_SETUP_DIR/setup.sh" --extend --local

View File

@ -1,9 +0,0 @@
#!/usr/bin/env sh
# generated from catkin/cmake/template/local_setup.sh.in
# since this file is sourced either use the provided _CATKIN_SETUP_DIR
# or fall back to the destination set at configure time
: ${_CATKIN_SETUP_DIR:=/home/luoruidi/Desktop/ros_learn/C++_Merge_Ros/merge_ros/devel}
CATKIN_SETUP_UTIL_ARGS="--extend --local"
. "$_CATKIN_SETUP_DIR/setup.sh"
unset CATKIN_SETUP_UTIL_ARGS

View File

@ -1,8 +0,0 @@
#!/usr/bin/env zsh
# generated from catkin/cmake/templates/local_setup.zsh.in
CATKIN_SHELL=zsh
# source setup.sh from same directory as this file
_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd)
emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh" --extend --local'

View File

@ -1,8 +0,0 @@
#!/usr/bin/env bash
# generated from catkin/cmake/templates/setup.bash.in
CATKIN_SHELL=bash
# source setup.sh from same directory as this file
_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)
. "$_CATKIN_SETUP_DIR/setup.sh"

View File

@ -1,96 +0,0 @@
#!/usr/bin/env sh
# generated from catkin/cmake/template/setup.sh.in
# Sets various environment variables and sources additional environment hooks.
# It tries it's best to undo changes from a previously sourced setup file before.
# Supported command line options:
# --extend: skips the undoing of changes from a previously sourced setup file
# --local: only considers this workspace but not the chained ones
# In plain sh shell which doesn't support arguments for sourced scripts you can
# set the environment variable `CATKIN_SETUP_UTIL_ARGS=--extend/--local` instead.
# since this file is sourced either use the provided _CATKIN_SETUP_DIR
# or fall back to the destination set at configure time
: ${_CATKIN_SETUP_DIR:=/home/luoruidi/Desktop/ros_learn/C++_Merge_Ros/merge_ros/devel}
_SETUP_UTIL="$_CATKIN_SETUP_DIR/_setup_util.py"
unset _CATKIN_SETUP_DIR
if [ ! -f "$_SETUP_UTIL" ]; then
echo "Missing Python script: $_SETUP_UTIL"
return 22
fi
# detect if running on Darwin platform
_UNAME=`uname -s`
_IS_DARWIN=0
if [ "$_UNAME" = "Darwin" ]; then
_IS_DARWIN=1
fi
unset _UNAME
# make sure to export all environment variables
export CMAKE_PREFIX_PATH
if [ $_IS_DARWIN -eq 0 ]; then
export LD_LIBRARY_PATH
else
export DYLD_LIBRARY_PATH
fi
unset _IS_DARWIN
export PATH
export PKG_CONFIG_PATH
export PYTHONPATH
# remember type of shell if not already set
if [ -z "$CATKIN_SHELL" ]; then
CATKIN_SHELL=sh
fi
# invoke Python script to generate necessary exports of environment variables
# use TMPDIR if it exists, otherwise fall back to /tmp
if [ -d "${TMPDIR:-}" ]; then
_TMPDIR="${TMPDIR}"
else
_TMPDIR=/tmp
fi
_SETUP_TMP=`mktemp "${_TMPDIR}/setup.sh.XXXXXXXXXX"`
unset _TMPDIR
if [ $? -ne 0 -o ! -f "$_SETUP_TMP" ]; then
echo "Could not create temporary file: $_SETUP_TMP"
return 1
fi
CATKIN_SHELL=$CATKIN_SHELL "$_SETUP_UTIL" $@ ${CATKIN_SETUP_UTIL_ARGS:-} >> "$_SETUP_TMP"
_RC=$?
if [ $_RC -ne 0 ]; then
if [ $_RC -eq 2 ]; then
echo "Could not write the output of '$_SETUP_UTIL' to temporary file '$_SETUP_TMP': may be the disk if full?"
else
echo "Failed to run '\"$_SETUP_UTIL\" $@': return code $_RC"
fi
unset _RC
unset _SETUP_UTIL
rm -f "$_SETUP_TMP"
unset _SETUP_TMP
return 1
fi
unset _RC
unset _SETUP_UTIL
. "$_SETUP_TMP"
rm -f "$_SETUP_TMP"
unset _SETUP_TMP
# source all environment hooks
_i=0
while [ $_i -lt $_CATKIN_ENVIRONMENT_HOOKS_COUNT ]; do
eval _envfile=\$_CATKIN_ENVIRONMENT_HOOKS_$_i
unset _CATKIN_ENVIRONMENT_HOOKS_$_i
eval _envfile_workspace=\$_CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE
unset _CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE
# set workspace for environment hook
CATKIN_ENV_HOOK_WORKSPACE=$_envfile_workspace
. "$_envfile"
unset CATKIN_ENV_HOOK_WORKSPACE
_i=$((_i + 1))
done
unset _i
unset _CATKIN_ENVIRONMENT_HOOKS_COUNT

View File

@ -1,8 +0,0 @@
#!/usr/bin/env zsh
# generated from catkin/cmake/templates/setup.zsh.in
CATKIN_SHELL=zsh
# source setup.sh from same directory as this file
_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd)
emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh"'

View File

@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PublishConfigData" remoteFilesAllowedToDisappearOnAutoupload="false">
<serverData>
<paths name="Remote Host (1dce3a15-503d-4545-b5bc-e482c493c313)">
<serverdata>
<mappings>
<mapping deploy="/tmp/src" local="$PROJECT_DIR$" />
</mappings>
</serverdata>
</paths>
</serverData>
</component>
</project>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/src.iml" filepath="$PROJECT_DIR$/.idea/src.iml" />
</modules>
</component>
</project>

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

View File

@ -1 +0,0 @@
/opt/ros/noetic/share/catkin/cmake/toplevel.cmake

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,31 +0,0 @@
#include <queue>
#include <opencv2/opencv.hpp>
#include <mutex>
#include "uwb.h"
#ifndef MAPPING_H
#define MAPPING_H
namespace uwb_slam{
class Mapping
{
public:
const double PIXEL_SCALE = 5.0;
const int AREA_SIZE = 2000;
Mapping() {};
void Run();
bool check_uwb_point();
void feed_uwb_data(const cv::Point2d & data);
void process();
std::mutex mMutexMap;
std::shared_ptr<uwb_slam::Uwb> uwb_;
private:
std::queue<cv::Point2d> mv_uwb_point_;
bool read_uwb_ = false;
cv::Mat img;
cv::Point2d cur_point = {-1,-1};
};
}
#endif

View File

@ -1,29 +0,0 @@
#include <ros/ros.h>
#include <nav_msgs/Odometry.h>
#include <geometry_msgs/Point.h>
#include <geometry_msgs/Quaternion.h>
#include <tf2/LinearMath/Quaternion.h>
#include <mutex>
#include "uwb.h"
#ifndef SENDDATA_H
#define SENDDATA_H
namespace uwb_slam{
class Senddata{
public:
Senddata(){};
void publishOdometry( std::shared_ptr<uwb_slam::Uwb>uwb);
void Run(std::shared_ptr<uwb_slam::Uwb>uwb);
void odomCB(const nav_msgs::Odometry& odom);
std::mutex mMutexSend;
private:
ros::Publisher position_pub_;
ros::Subscriber odom_sub_;
ros::NodeHandle nh_;
nav_msgs::Odometry odom_;//odom的消息类型
nav_msgs::Odometry sub_odom_;//odom的消息类型
};
}
#endif

View File

@ -1,36 +0,0 @@
#include <ros/ros.h>
#include <mutex>
#include <boost/asio.hpp>
#include <iostream>
#include <string>
#include <cstdint>
#include "type.h"
#include <queue>
#include <chrono>
#ifndef __UWB_H__
#define __UWB_H__
namespace uwb_slam{
class Uwb
{
public:
Uwb();
void Run();
bool checknewdata();
void feed_imu_odom_pose_data();
void UartUSBRead();
public:
int pre_seq = -1;
int cur_seq = -1;
uint8_t tmpdata[13];
float x, y, theta, distance;
Uwb_data uwb_data_;
std::mutex mMutexUwb;
};
};
#endif

View File

@ -1,154 +0,0 @@
/******************** (C) COPYRIGHT 2023 UPBot **********************************
* File Name : align.cpp
* Current Version : V1.0
* Date of Issued : 2023.12.13 zhanli@review
* Comments :
********************************************************************************/
#include "align.h"
namespace uwb_slam{
void Align::Run()
{
tmp = ros::Time::now();
ros::Time tmp1 = ros::Time::now();
ros::Time tmp2 = ros::Time::now();
// 这个地方分别订阅了原始IMU、轮式里程计、里程计(推测是UWB)
wheel_odom_sub_= nh_.subscribe("wheel_odom",10,&Align::wheel_odomCB,this);
imu_sub_ = nh_.subscribe("raw_imu",10,&Align::imuCB,this);
odom_sub_ = nh_.subscribe("odom",10,&Align::odomCB,this);
std::ofstream outfile("data.txt",std::ofstream::out);
if(outfile.is_open())
{
img1 = cv::Mat(200, 200, CV_8UC1, cv::Scalar(255,255,255));
cv::imshow("Image1", img1);
int key2 = cv::waitKey(0);
// if(key2 =='w'){
// bool write_data_ = true;
// }
// int count=0;
// while(write_data_){
while(1){
int key3 = cv::waitKey(1);
if(key3 == 'w'){
break;
}
if(tmp!=imu_odom_.imu_data_.imu_t_)
{
// outfile <<"imu_odom_: "<< "imu_timestamp "<<"imu_linear_acc_x_y_z "<<"imu_angular_x_y_z "<<
// "odom_vxy "<<"odom_angle_v_ "<<"\n";
// if(tmp1!=uwb_->uwb_data_.uwb_t_&& tmp2!=odom_tmp_){
outfile << std::left << std::setw(12)<<"imu_odom_: "<< std::setw(10)<< imu_odom_.imu_data_.imu_t_.sec << '.' <<std::setw(11)<< imu_odom_.imu_data_.imu_t_.nsec << std::setw(11)
<<imu_odom_.imu_data_.a_[0] << std::setw(11)<<imu_odom_.imu_data_.a_[1] << std::setw(11)<<imu_odom_.imu_data_.a_[2] << std::setw(12)
<<imu_odom_.imu_data_.w_[0] << std::setw(12)<<imu_odom_.imu_data_.w_[1] << std::setw(12)<<imu_odom_.imu_data_.w_[2] << std::setw(11)
<<imu_odom_.vxy_ << std::setw(11)<<imu_odom_.angle_v_ << std::setw(7)
<<" pose: " << std::setw(1)<<(odom_tmp_-tmp2).sec<<'.'<<std::setw(12)<<(odom_tmp_-tmp2).nsec<<std::setw(11)
<<imu_odom_.pose_[0] << std::setw(12)<<imu_odom_.pose_[1] << std::setw(2)<<imu_odom_.pose_[2] << std::setw(12)
<<imu_odom_.quat_[0] << std::setw(12)<<imu_odom_.quat_[1] << std::setw(12)<<imu_odom_.quat_[2] << std::setw(12)<<imu_odom_.quat_[3] << std::setw(6)
<<" uwb: " << std::setw(1)<<(uwb_->uwb_data_.uwb_t_-tmp1).sec<<'.'<<std::setw(13)<<(uwb_->uwb_data_.uwb_t_-tmp1).nsec << std::setw(9)
<<uwb_->uwb_data_.x_ << std::setw(9)<<uwb_->uwb_data_.y_<<"\n";
tmp1 = uwb_->uwb_data_.uwb_t_;
tmp2 = odom_tmp_;
// }
// else if(tmp1!=uwb_->uwb_data_.uwb_t_){
// outfile <<"imu_odom_: "<< imu_odom_.imu_data_.imu_t_ <<"*"
// <<imu_odom_.imu_data_.a_[0]<<"*"<<imu_odom_.imu_data_.a_[1]<<"*"<<imu_odom_.imu_data_.a_[2]<<"*"
// <<imu_odom_.imu_data_.w_[0]<<"*"<<imu_odom_.imu_data_.w_[1]<<"*"<<imu_odom_.imu_data_.w_[2]<<"*"
// <<imu_odom_.vxy_<<"*"<<imu_odom_.angle_v_<<"*"
// <<"pose: "<<"****************************"
// <<"uwb: "<<uwb_->uwb_data_.uwb_t_<<"*"<<uwb_->uwb_data_.x_<<"*"<<uwb_->uwb_data_.y_<<"\n";
// tmp1 = uwb_->uwb_data_.uwb_t_;
// }
// else if(tmp2!=odom_tmp_){
// outfile <<"imu_odom_: "<< imu_odom_.imu_data_.imu_t_ <<"*"
// <<imu_odom_.imu_data_.a_[0]<<"*"<<imu_odom_.imu_data_.a_[1]<<"*"<<imu_odom_.imu_data_.a_[2]<<"*"
// <<imu_odom_.imu_data_.w_[0]<<"*"<<imu_odom_.imu_data_.w_[1]<<"*"<<imu_odom_.imu_data_.w_[2]<<"*"
// <<imu_odom_.vxy_<<"*"<<imu_odom_.angle_v_<<"*"
// <<"pose: "
// <<imu_odom_.pose_[0]<<"*"<<imu_odom_.pose_[1]<<"*"<<imu_odom_.pose_[2]<<"*"
// <<imu_odom_.quat_[0]<<"*"<<imu_odom_.quat_[1]<<"*"<<imu_odom_.quat_[2]<<"*"<<imu_odom_.quat_[3]<<"*"
// <<"uwb: "<<"****************************"<<"\n";
// tmp2 = odom_tmp_;
// }
// else {
// outfile <<"imu_odom_: "<< imu_odom_.imu_data_.imu_t_ <<"*"
// <<imu_odom_.imu_data_.a_[0]<<"*"<<imu_odom_.imu_data_.a_[1]<<"*"<<imu_odom_.imu_data_.a_[2]<<"*"
// <<imu_odom_.imu_data_.w_[0]<<"*"<<imu_odom_.imu_data_.w_[1]<<"*"<<imu_odom_.imu_data_.w_[2]<<"*"
// <<imu_odom_.vxy_<<"*"<<imu_odom_.angle_v_<<"*"
// <<"pose: "<<"****************************"
// <<"uwb: "<<"****************************"<<"\n";
// }
tmp = imu_odom_.imu_data_.imu_t_;
// tmp1 = uwb_->uwb_data_.uwb_t_;
// if(count>300)
// break;
}
}
outfile.close();
std::cout<< "Data written to file." << std::endl;
}
else{
std::cout<<"file can not open"<<std::endl;
}
}
void Align::wheel_odomCB(const nav_msgs::Odometry& wheel_odom)
{
imu_odom_.vxy_= wheel_odom.twist.twist.linear.x;
imu_odom_.angle_v_ = wheel_odom.twist.twist.angular.z;
// imu_odom_.pose_[0] = wheel_odom.pose.pose.position.x;
// imu_odom_.pose_[1] = wheel_odom.pose.pose.position.y;
// imu_odom_.pose_[2] = wheel_odom.pose.pose.position.z;
// imu_odom_.quat_[0] = wheel_odom.pose.pose.orientation.x;
// imu_odom_.quat_[1] = wheel_odom.pose.pose.orientation.y;
// imu_odom_.quat_[2] = wheel_odom.pose.pose.orientation.z;
// imu_odom_.quat_[3] = wheel_odom.pose.pose.orientation.w;
return;
}
void Align::imuCB(const ros_merge_test::RawImu& imu)
{
imu_odom_.imu_data_.imu_t_ = imu.header.stamp;
imu_odom_.imu_data_.a_[0] = imu.raw_linear_acceleration.x;
imu_odom_.imu_data_.a_[1] = imu.raw_linear_acceleration.y;
imu_odom_.imu_data_.a_[2] = imu.raw_linear_acceleration.z;
imu_odom_.imu_data_.w_[0] = imu.raw_angular_velocity.x;
imu_odom_.imu_data_.w_[1] = imu.raw_angular_velocity.y;
imu_odom_.imu_data_.w_[2] = imu.raw_angular_velocity.z;
return;
}
/**---------------------------------------------------------------------
* Function : odomCB
* Description : , ROS
*
* Input : nav_msgs::Odometry& odom :
* Date : 2023/12/13 zhanli@review
*---------------------------------------------------------------------**/
void Align::odomCB(const nav_msgs::Odometry& odom)
{
odom_tmp_ = odom.header.stamp;
imu_odom_.pose_[0] = odom.pose.pose.position.x;
imu_odom_.pose_[1] = odom.pose.pose.position.y;
imu_odom_.pose_[2] = odom.pose.pose.position.z;
imu_odom_.quat_[0] = odom.pose.pose.orientation.x;
imu_odom_.quat_[1] = odom.pose.pose.orientation.y;
imu_odom_.quat_[2] = odom.pose.pose.orientation.z;
imu_odom_.quat_[3] = odom.pose.pose.orientation.w;
}
};

View File

@ -1,53 +0,0 @@
/******************** (C) COPYRIGHT 2023 UPBot **********************************
* File Name : main.cpp
* Current Version : V1.0
* Date of Issued : 2023.12.13 zhanli@review
* Comments : UPbot
********************************************************************************/
#include "../include/system.h"
#include "../include/uwb.h"
#include <iostream>
#include <ros/ros.h>
#include <thread>
#include "senddata.h"
/**---------------------------------------------------------------------
* Function : main
* Description :
* Date : 2023/12/13 zhanli@review
*---------------------------------------------------------------------**/
int main(int argc, char** argv)
{
// Initialize the ROS node
ros::init(argc, argv, "locate_info_pub_node");
std::shared_ptr<uwb_slam::Mapping> mp = std::make_shared<uwb_slam::Mapping>();
std::shared_ptr<uwb_slam::Uwb> uwb = std::make_shared<uwb_slam::Uwb>();
std::shared_ptr<uwb_slam::Senddata> sender = std::make_shared<uwb_slam::Senddata>();
std::shared_ptr<uwb_slam::Align> align = std::make_shared<uwb_slam::Align>();
mp->uwb_ = uwb;
align->uwb_ = uwb;
// uwb serried read
std::thread uwb_trd([&uwb]() {
uwb->Run();
});
// 建图部分暂时没有使用到
/*std::thread map_trd([&mp]() {
mp->Run();
});*/
std::thread sender_trd([&sender, uwb]() {
sender->Run(uwb);
});
std::thread align_trd([&align]() {
align->Run();
});
// Start the ROS node's main loop
ros::spin();
}

View File

@ -1,89 +0,0 @@
#include "mapping.h"
#include <mutex>
#include <unistd.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
namespace uwb_slam
{
bool Mapping::check_uwb_point()
{
//std::unique_lock<std::mutex> lock(mMutexMap);
return !mv_uwb_point_.empty();
}
void Mapping::feed_uwb_data(const cv::Point2d & data)
{
//std::unique_lock<std::mutex> lock(mMutexMap);
mv_uwb_point_.push(data);
}
void Mapping::process()
{
{
//std::unique_lock<std::mutex> lock(mMutexMap);
//std::cout << "SIZE: " <<mv_uwb_point_.size() << std::endl;
cur_point= mv_uwb_point_.front();
//std::cout << "x: " <<cur_point.x << " y:" << cur_point.y << std::endl;
mv_uwb_point_.pop();
}
/*生成图*/
int pix_x = cur_point.x / PIXEL_SCALE + ( fmod(cur_point.x ,PIXEL_SCALE) != 0);
int pix_y = cur_point.y / PIXEL_SCALE + ( fmod(cur_point.y ,PIXEL_SCALE) != 0);
img.at<unsigned char>(pix_y,pix_x)= 0;
//cv::imshow("Image",img);
}
void Mapping::Run()
{
int realWidth = AREA_SIZE / PIXEL_SCALE;
int realHeight = AREA_SIZE / PIXEL_SCALE;
img = cv::Mat(realHeight, realWidth, CV_8UC1, cv::Scalar(255,255,255));
for (int j=0;j<AREA_SIZE / PIXEL_SCALE;j+=16)
for (int i=0;i<AREA_SIZE / PIXEL_SCALE;i+=16)
img.at<unsigned char>(j,i)= 128;
for (int j=199+8;j<210;j+=1)
for (int i=199+8;i<210;i+=1)
img.at<unsigned char>(j,i)= 0;
cv::imshow("Image",img);
while(1)
{
// 这个地方会持续阻塞
int key = cv::waitKey(0);
if (key == 'q') {
read_uwb_ = true;
std::cout << "non" << key << std::endl;
//cv::destroyAllWindows();
}
while(read_uwb_ ) // 按下空格键
{
int key2 = cv::waitKey(1);
if (key2 == 'q' ) {
//TODO: save
std::string pngimage = "/home/firefly/Project_Ros/src/ros_merge_test/Map/output_image.png";//保存的图片文件路径
cv::imwrite(pngimage, img);
read_uwb_ = false;
break;
}
this->feed_uwb_data(cv::Point2d(uwb_->x ,uwb_->y));
if(check_uwb_point()){
process();
}
}
}
}
} // namespace uwb_slam

View File

@ -1,83 +0,0 @@
/******************** (C) COPYRIGHT 2023 UPBot **********************************
* File Name : senddata.cpp
* Current Version : V1.0
* Date of Issued : 2023.12.13 zhanli@review
* Comments : UWB
********************************************************************************/
#include "senddata.h"
namespace uwb_slam{
/**---------------------------------------------------------------------
* Function : Senddata::Run
* Description : UWBodm
* Date : 2023/12/13 zhanli@review
*---------------------------------------------------------------------**/
void Senddata::Run(std::shared_ptr<uwb_slam::Uwb>uwb){
// 初始化了一个名为loop_rate的ros::Rate对象,频率设置为10赫兹
ros::Rate loop_rate(10);
// 初始化一个ROS发布者用于发布nav_msgs::Odometry类型的消息
// 主题被设置为"uwb_odom"队列大小为50
position_pub_ = nh_.advertise<nav_msgs::Odometry>("uwb_odom", 50);
// 初始化了一个ROS订阅者用于订阅"odom"主题。它指定了当在该主题上接收到
// 消息时将调用Senddata类的odomCB回调函数。队列大小被设置为10
odom_sub_ = nh_.subscribe("odom", 10, &Senddata::odomCB,this);
while(ros::ok()){
// 按照10Hz频率发布uwb信息
publishOdometry(uwb);
ros::spinOnce();
// 用于控制循环速率
loop_rate.sleep();
}
}
void Senddata::odomCB(const nav_msgs::Odometry& odom){
// 这个地方接收的是轮速里程计的信息
// 包含位置和姿态
sub_odom_ = odom;
return;
}
/**---------------------------------------------------------------------
* Function : Senddata::publishOdometry
* Description : UWB
* Date : 2023/12/13 zhanli@review
*---------------------------------------------------------------------**/
void Senddata::publishOdometry(std::shared_ptr<uwb_slam::Uwb> uwb)
{
std::mutex mMutexSend;
ros::Time current_time = ros::Time::now();
// 设置 Odometry 消息的头部信息
odom_.header.stamp = current_time; // 这个地方获取的时间是否会存在问题?
odom_.header.frame_id = "odom"; // 设置坐标系为 "map"
odom_.child_frame_id = "base_link"; // 设置坐标系为 "base_link"
// 填充 Odometry 消息的位置信息
odom_.pose.pose.position.x = uwb->x;
odom_.pose.pose.position.y = uwb->y;
odom_.pose.pose.position.z = 0.0;
// 填充 Odometry 消息的姿态信息(使用四元数来表示姿态)
// tf2::Quaternion quat;
// quat.setRPY(0, 0, uwb->theta);
// 设置了 yaw 角度,其他 roll 和 pitch 设置为 0
// odom.pose.pose.orientation.x = quat.x();
// odom.pose.pose.orientation.y = quat.y();
// odom.pose.pose.orientation.z = quat.z();
// odom.pose.pose.orientation.w = quat.w();
// 从里程计拿到姿态信息
odom_.pose.pose.orientation.x = sub_odom_.pose.pose.orientation.x;
odom_.pose.pose.orientation.y = sub_odom_.pose.pose.orientation.y;
odom_.pose.pose.orientation.z = sub_odom_.pose.pose.orientation.z;
odom_.pose.pose.orientation.w = sub_odom_.pose.pose.orientation.w;
// 发布 Odometry 消息
position_pub_.publish(odom_);
}
} // namespace uwb_slam

View File

@ -1,68 +0,0 @@
/******************** (C) COPYRIGHT 2023 UPBot **********************************
* File Name : uwb.cpp
* Current Version : V1.0
* Date of Issued : 2023.12.13 zhanli@review
* Comments : UWB, USB
1) serial_port 2)
3)
********************************************************************************/
#include "uwb.h"
#include <cmath>
#define PI acos(-1)
namespace uwb_slam{
//
Uwb::Uwb(){
}
void Uwb::Run() {
while(1){
// 这个地方不控制速率?
// UartUSBRead 这个地方本身就是同步读取串口,是阻塞的函数
this->UartUSBRead();
}
}
/**---------------------------------------------------------------------
* Function : UartUSBRead
* Description : 1)
*
* Date : 2023/12/13 zhanli@review
*---------------------------------------------------------------------**/
void Uwb::UartUSBRead()
{
try {
boost::asio::io_service io;
boost::asio::serial_port serial(io, "/dev/ttyUSB0"); // 替换成你的串口设备路径
serial.set_option(boost::asio::serial_port_base::baud_rate(115200)); // 设置波特率
serial.set_option(boost::asio::serial_port_base::character_size(8)); // 设置数据位
serial.set_option(boost::asio::serial_port_base::parity(boost::asio::serial_port_base::parity::none)); // 设置校验位
serial.set_option(boost::asio::serial_port_base::stop_bits(boost::asio::serial_port_base::stop_bits::one)); // 设置停止位
uint8_t tmpdata[12];
// 读取串口数据
size_t bytesRead = boost::asio::read(serial, boost::asio::buffer(tmpdata, 12));
// UWB获取的数据是半径R和角度Theta
memcpy(&this->distance, &tmpdata[3], sizeof(distance));
memcpy(&this->theta, &tmpdata[7], sizeof(theta));
// 这个地方是为了把UWB的坐标移动到图像的中心位置 2023/12/13@李瑞瑞
this->uwb_data_.x_ = cosf(theta / 180*PI)*distance + 1000;
this->uwb_data_.y_ = sinf(theta / 180*PI)*distance + 1000;
// 获取此时的系统时间戳
this->uwb_data_.uwb_t_ = ros::Time::now();
std::cout << "theta: " << theta << " distance: " << distance << std::endl;
} catch (const std::exception& ex) {
std::cerr << "[ERR]: uwb.cpp::Uart USB read data exception: "
<< ex.what() << std::endl;
}
}
};

View File

@ -1,15 +0,0 @@
使用方法:
```shell
# 进入工作目录
cd ~/obj_dec
# 编译
catkin_make
# 引入环境变量
source ./devel/setup.bash
# 启动ros核心节点
roscore
# 运行
rosrun rknn_yolov5_demo main
```

View File

@ -1,80 +0,0 @@
cmake_minimum_required(VERSION 3.0.2)
project(rknn_yolov5_demo)
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
message_generation
)
find_package(OpenCV REQUIRED)
find_package(Threads REQUIRED)
add_message_files(
FILES
dis_info.msg
dis_info_array.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
CATKIN_DEPENDS roscpp std_msgs message_runtime
)
include_directories(
include
${catkin_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
/home/firefly/obj_dec/src/runtime/RK3588/Linux/librknn_api/include
/home/firefly/obj_dec/src/3rdparty/rga/RK3588/include
)
add_library(
head
include/rknn_yolov5_demo/detection.h
include/rknn_yolov5_demo/postprocess.h
include/rknn_yolov5_demo/preprocess.h
include/rknn_yolov5_demo/ranging.h
include/rknn_yolov5_demo/Timer.h
# include/rknn_yolov5_demo/pub_info.h
src/detection.cc
src/postprocess.cc
src/preprocess.cc
src/ranging.cc
# src/pub_info.cc
)
add_dependencies(head ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(head
${catkin_LIBRARIES}
)
add_executable(main src/main.cc)
add_executable(sub_dis src/sub_dis.cc)
add_dependencies(main ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(sub_dis ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(sub_dis
${catkin_LIBRARIES}
)
target_link_libraries(main
head
${catkin_LIBRARIES}
${OpenCV_LIBS}
Threads::Threads
/home/firefly/obj_dec/src/librknnrt.so
/home/firefly/obj_dec/src/librga.so
/home/firefly/obj_dec/src/libopencv_highgui.so
)

View File

@ -1,32 +0,0 @@
#ifndef PUB_INFO_H
#define PUB_INFO_H
#include <ros/ros.h>
#include <thread>
#include "rknn_yolov5_demo/dis_info.h"
#include "rknn_yolov5_demo/dis_info_array.h"
#include "rknn_yolov5_demo/ranging.h"
class Pub_info{
public:
Pub_info(){
dis_pub_ = nh_.advertise<rknn_yolov5_demo::dis_info_array>("ceju_info",10);
thread_1 = std::thread(&Pub_info::pub_dis,this);
// thread_2 = std::thread(&Pub_info::)
};
~Pub_info(){
thread_1.join();
}
void pub_dis();
public:
ros::NodeHandle nh_;
ros::Publisher dis_pub_;
rknn_yolov5_demo::dis_info_array dis_array_;
rknn_yolov5_demo::dis_info data;
std::thread thread_1;
// std::thread thread_2;
};
#endif

View File

@ -1 +0,0 @@
rknn_yolov5_demo/dis_info[] dis

View File

@ -1,28 +0,0 @@
#include "rknn_yolov5_demo/pub_info.h"
void Pub_info::pub_dis()
{
Ranging ranging;
ros::Rate loop_rate(10);
while(ros::ok()){
std::vector<cv::Mat> result = ranging.get_range();
cv::Mat info = result[2];
for(int i=0;i<info.rows;i++)
{
data.distance = info.at<float>(i,0);
data.width = info.at<float>(i,1);
data.height = info.at<float>(i,2);
data.angle = info.at<float>(i,3);
dis_array_.dis.push_back(data);
}
dis_pub_.publish(dis_array_);
loop_rate.sleep();
}
}

View File

@ -1,6 +1,6 @@
# PIBOT ROS Workspace v2.0 # PIBOT ROS Workspace v2.0
## 安装ROS ## install ros
```shell ```shell
cd ~/pibot_ros/ cd ~/pibot_ros/
./pibot_install_ros.sh ./pibot_install_ros.sh

BIN
Code/MowingRobot/pibot_ros/a.out Executable file

Binary file not shown.

View File

@ -1,17 +1,17 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import pypibot.assistant import pypibot.assistant
import pypibot.log as Logger import pypibot.log as Logger
import pypibot.err import pypibot.err
log=Logger.log log=Logger.log
import sys import sys
def createNamedLog(name): def createNamedLog(name):
return Logger.NamedLog(name) return Logger.NamedLog(name)
class Object(): class Object():
pass pass
isDebug="-d" in sys.argv isDebug="-d" in sys.argv
import platform import platform
isWindows=False isWindows=False
if platform.system()=='Windows': if platform.system()=='Windows':
isWindows=True isWindows=True

View File

@ -1,234 +1,234 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os, sys, inspect import os, sys, inspect
import datetime import datetime
import signal import signal
import threading import threading
import time import time
# function: get directory of current script, if script is built # function: get directory of current script, if script is built
# into an executable file, get directory of the excutable file # into an executable file, get directory of the excutable file
def current_file_directory(): def current_file_directory():
path = os.path.realpath(sys.path[0]) # interpreter starter's path path = os.path.realpath(sys.path[0]) # interpreter starter's path
if os.path.isfile(path): # starter is excutable file if os.path.isfile(path): # starter is excutable file
path = os.path.dirname(path) path = os.path.dirname(path)
path = os.path.abspath(path) # return excutable file's directory path = os.path.abspath(path) # return excutable file's directory
else: # starter is python script else: # starter is python script
caller_file = inspect.stack()[0][1] # function caller's filename caller_file = inspect.stack()[0][1] # function caller's filename
path = os.path.abspath(os.path.dirname(caller_file))# return function caller's file's directory path = os.path.abspath(os.path.dirname(caller_file))# return function caller's file's directory
if path[-1]!=os.path.sep:path+=os.path.sep if path[-1]!=os.path.sep:path+=os.path.sep
return path return path
"""格式化字符串""" """格式化字符串"""
def formatString(string,*argv): def formatString(string,*argv):
string=string%argv string=string%argv
if string.find('$(scriptpath)')>=0: if string.find('$(scriptpath)')>=0:
string=string.replace('$(scriptpath)',current_file_directory()) string=string.replace('$(scriptpath)',current_file_directory())
if string.find('$(filenumber2)')>=0: if string.find('$(filenumber2)')>=0:
i=0 i=0
path="" path=""
while True: while True:
path=string.replace('$(scriptpath)',"%02d"%i) path=string.replace('$(scriptpath)',"%02d"%i)
if not os.path.lexists(path):break if not os.path.lexists(path):break
i+=1 i+=1
string=path string=path
#8位日期20140404 #8位日期20140404
if string.find('$(Date8)')>=0: if string.find('$(Date8)')>=0:
now=datetime.datetime.now() now=datetime.datetime.now()
string=string.replace('$(Date8)', now.strftime("%Y%m%d")) string=string.replace('$(Date8)', now.strftime("%Y%m%d"))
#6位日期140404 #6位日期140404
if string.find('$(Date6)')>=0: if string.find('$(Date6)')>=0:
now=datetime.datetime.now() now=datetime.datetime.now()
string=string.replace('$(Date6)', now.strftime("%y%m%d")) string=string.replace('$(Date6)', now.strftime("%y%m%d"))
#6位时间121212 #6位时间121212
if string.find('$(Time6)')>=0: if string.find('$(Time6)')>=0:
now=datetime.datetime.now() now=datetime.datetime.now()
string=string.replace('$(Time6)', now.strftime("%H%M%S")) string=string.replace('$(Time6)', now.strftime("%H%M%S"))
#4位时间1212 #4位时间1212
if string.find('$(Time4)')>=0: if string.find('$(Time4)')>=0:
now=datetime.datetime.now() now=datetime.datetime.now()
string=string.replace('$(Time4)', now.strftime("%H%M")) string=string.replace('$(Time4)', now.strftime("%H%M"))
#文件编号2位必须在最后 #文件编号2位必须在最后
if string.find('$(filenumber2)')>=0: if string.find('$(filenumber2)')>=0:
i=0 i=0
path="" path=""
while True: while True:
path=string.replace('$(filenumber2)',"%02d"%i) path=string.replace('$(filenumber2)',"%02d"%i)
if not os.path.lexists(path):break if not os.path.lexists(path):break
i+=1 i+=1
string=path string=path
#文件编号3位必须在最后 #文件编号3位必须在最后
if string.find('$(filenumber3)')>=0: if string.find('$(filenumber3)')>=0:
i=0 i=0
path="" path=""
while True: while True:
path=string.replace('$(filenumber3)',"%03d"%i) path=string.replace('$(filenumber3)',"%03d"%i)
if not os.path.lexists(path):break if not os.path.lexists(path):break
i+=1 i+=1
string=path string=path
return string return string
""" """
取得进程列表 取得进程列表
格式(PID,cmd) 格式(PID,cmd)
""" """
def getProcessList(): def getProcessList():
processList = [] processList = []
try: try:
for line in os.popen("ps xa"): for line in os.popen("ps xa"):
fields = line.split() fields = line.split()
# spid = fields[0] # spid = fields[0]
pid = 0 pid = 0
try:pid = int(fields[0]) try:pid = int(fields[0])
except:None except:None
cmd = line[27:-1] cmd = line[27:-1]
# print "PS:%d,%s"%(npid,process) # print "PS:%d,%s"%(npid,process)
if pid != 0 and len(cmd) > 0: if pid != 0 and len(cmd) > 0:
processList.append((pid, cmd)) processList.append((pid, cmd))
except Exception as e: except Exception as e:
print("getProcessList except:%s" % (e)) print("getProcessList except:%s" % (e))
return processList return processList
def killCommand(cmd): def killCommand(cmd):
try: try:
processList = getProcessList() processList = getProcessList()
for p in processList: for p in processList:
if p[1].find(cmd) != -1: if p[1].find(cmd) != -1:
pid = p[0] pid = p[0]
os.kill(pid, signal.SIGKILL) os.kill(pid, signal.SIGKILL)
except Exception as e: except Exception as e:
print("killCommand %s except:%s" % (cmd,e)) print("killCommand %s except:%s" % (cmd,e))
def check_pid(pid): def check_pid(pid):
""" Check For the existence of a unix pid. """ """ Check For the existence of a unix pid. """
if pid == 0:return False if pid == 0:return False
try: try:
os.kill(pid, 0) os.kill(pid, 0)
except OSError: except OSError:
return False return False
else: else:
return True return True
SF=formatString SF=formatString
#全局异常捕获 #全局异常捕获
def excepthook(excType, excValue, tb): def excepthook(excType, excValue, tb):
'''''write the unhandle exception to log''' '''''write the unhandle exception to log'''
from log import log from log import log
import traceback import traceback
log.e('Unhandled Error: %s',''.join(traceback.format_exception(excType, excValue, tb))) log.e('Unhandled Error: %s',''.join(traceback.format_exception(excType, excValue, tb)))
sys.exit(-1) sys.exit(-1)
#sys.__excepthook__(type, value, trace) #sys.__excepthook__(type, value, trace)
#sys.__excepthook__(excType, excValue, tb) #sys.__excepthook__(excType, excValue, tb)
_defaultGlobalExcept=sys.excepthook _defaultGlobalExcept=sys.excepthook
def enableGlobalExcept(enable=True): def enableGlobalExcept(enable=True):
if enable: if enable:
sys.excepthook = excepthook sys.excepthook = excepthook
else: else:
sys.excepthook=_defaultGlobalExcept sys.excepthook=_defaultGlobalExcept
# 默认启动全局异常处理 # 默认启动全局异常处理
enableGlobalExcept() enableGlobalExcept()
#创建线程 #创建线程
def createThread(name,target,args=(),autoRun=True,daemon=True): def createThread(name,target,args=(),autoRun=True,daemon=True):
from log import log from log import log
def threadProc(): def threadProc():
log.i("thread %s started!",name) log.i("thread %s started!",name)
try: try:
target(*args) target(*args)
log.i("thread %s ended!",name) log.i("thread %s ended!",name)
except Exception as e: except Exception as e:
log.e("thread %s crash!err=%s",name,e) log.e("thread %s crash!err=%s",name,e)
thd=threading.Thread(name=name,target=threadProc) thd=threading.Thread(name=name,target=threadProc)
thd.setDaemon(daemon) thd.setDaemon(daemon)
if autoRun:thd.start() if autoRun:thd.start()
return thd return thd
#定时器 #定时器
class Timer(): class Timer():
def __init__(self, timer_proc, args=(),first=0,period=0,name="Timer"): def __init__(self, timer_proc, args=(),first=0,period=0,name="Timer"):
self.name=name self.name=name
self.first=first self.first=first
self.period=period self.period=period
self.args=args self.args=args
self.timer_proc=timer_proc self.timer_proc=timer_proc
self.thdWork=None self.thdWork=None
self.stopFlag=False self.stopFlag=False
from log import NamedLog from log import NamedLog
self.log=NamedLog(name) self.log=NamedLog(name)
def run(self): def run(self):
if self.first>0: if self.first>0:
time.sleep(self.first) time.sleep(self.first)
try: try:
self.timer_proc(*self.args) self.timer_proc(*self.args)
except Exception as e: except Exception as e:
self.log.error("timer proc crash!err=%s",e) self.log.error("timer proc crash!err=%s",e)
while self.period>0 and not self.stopFlag: while self.period>0 and not self.stopFlag:
time.sleep(self.period) time.sleep(self.period)
try: try:
self.timer_proc(*self.args) self.timer_proc(*self.args)
except Exception as e: except Exception as e:
self.log.error("timer proc crash!err=%s",e) self.log.error("timer proc crash!err=%s",e)
def start(self): def start(self):
if self.isAlive(): if self.isAlive():
self.log.d("already running!") self.log.d("already running!")
return True return True
self.stopFlag=False self.stopFlag=False
self.thdWork=threading.Thread(name=self.name,target=self.run) self.thdWork=threading.Thread(name=self.name,target=self.run)
self.thdWork.setDaemon(True) self.thdWork.setDaemon(True)
self.thdWork.start() self.thdWork.start()
def stop(self,timeout=3): def stop(self,timeout=3):
if self.isAlive(): if self.isAlive():
self.stopFlag=True self.stopFlag=True
try: try:
self.thdWork.join(timeout) self.thdWork.join(timeout)
except Exception as e: except Exception as e:
self.log.e("stop timeout!") self.log.e("stop timeout!")
def isAlive(self): def isAlive(self):
return self.thdWork and self.thdWork.isAlive() return self.thdWork and self.thdWork.isAlive()
#计时器 #计时器
class Ticker(): class Ticker():
def __init__(self): def __init__(self):
self.reset() self.reset()
# 片段,可以判断时长是否在一个特定毫秒段内 # 片段,可以判断时长是否在一个特定毫秒段内
self.section=[] self.section=[]
def reset(self): def reset(self):
self.tick=time.time() self.tick=time.time()
self.end=0 self.end=0
def stop(self): def stop(self):
self.end=time.time() self.end=time.time()
@property @property
def ticker(self): def ticker(self):
if self.end==0: if self.end==0:
return int((time.time()-self.tick)*1000) return int((time.time()-self.tick)*1000)
else: else:
return int((self.end-self.tick)*1000) return int((self.end-self.tick)*1000)
def addSection(self,a,b): def addSection(self,a,b):
a,b=int(a),int(b) a,b=int(a),int(b)
assert a<b assert a<b
self.section.append((a,b)) self.section.append((a,b))
def removeSection(self,a,b): def removeSection(self,a,b):
a,b=int(a),int(b) a,b=int(a),int(b)
self.section.remove((a,b)) self.section.remove((a,b))
def removeAllSectioin(self): def removeAllSectioin(self):
self.section=[] self.section=[]
def inSection(self): def inSection(self):
tick=self.ticker tick=self.ticker
for (a,b) in self.section: for (a,b) in self.section:
if tick>=a and tick<=b: if tick>=a and tick<=b:
return True return True
return False return False
def __call__(self): def __call__(self):
return self.ticker return self.ticker
def waitExit(): def waitExit():
import log import log
log.log.i("start waiting to exit...") log.log.i("start waiting to exit...")
try: try:
while(True): while(True):
time.sleep(1) time.sleep(1)
except Exception as e: except Exception as e:
log.log.w("recv exit sign!") log.log.w("recv exit sign!")
def is_python3(): def is_python3():
return sys.hexversion > 0x03000000 return sys.hexversion > 0x03000000

View File

@ -1,56 +1,56 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import ConfigParser import ConfigParser
from log import PLOG from log import PLOG
import os import os
def getdefaultfilename(): def getdefaultfilename():
pass pass
def openconfiger(filename): def openconfiger(filename):
return configer(filename) return configer(filename)
class configer: class configer:
def __init__(self,fullfilepath): def __init__(self,fullfilepath):
self._filepath=fullfilepath self._filepath=fullfilepath
if not os.path.isdir(os.path.dirname(fullfilepath)): if not os.path.isdir(os.path.dirname(fullfilepath)):
os.makedirs(os.path.dirname(fullfilepath)) os.makedirs(os.path.dirname(fullfilepath))
self._conf=ConfigParser.ConfigParser() self._conf=ConfigParser.ConfigParser()
if os.path.isfile(fullfilepath): if os.path.isfile(fullfilepath):
try: try:
self._conf.readfp(open(fullfilepath,"r")) self._conf.readfp(open(fullfilepath,"r"))
except Exception,e: except Exception,e:
PLOG.error("配置文件'%s'打开失败,err=%s"%(self._filepath,e)) PLOG.error("配置文件'%s'打开失败,err=%s"%(self._filepath,e))
def save(self): def save(self):
try: try:
self._conf.write(open(self._filepath,"w")) self._conf.write(open(self._filepath,"w"))
except Exception,e: except Exception,e:
PLOG.error("配置文件'%s'保存失败,err=%s"%(self._filepath,e)) PLOG.error("配置文件'%s'保存失败,err=%s"%(self._filepath,e))
def changeConfValue(self,section,option,value): def changeConfValue(self,section,option,value):
if self._conf.has_section(section): if self._conf.has_section(section):
self._conf.set(section,option,value) self._conf.set(section,option,value)
else: else:
self._conf.add_section(section) self._conf.add_section(section)
self._conf.set(section,option,value) self._conf.set(section,option,value)
def _readvalue(self,fn,section,option,default): def _readvalue(self,fn,section,option,default):
result=default result=default
if self._conf.has_section(section): if self._conf.has_section(section):
if self._conf.has_option(section,option): if self._conf.has_option(section,option):
result=fn(section,option) result=fn(section,option)
PLOG.debug("Option[%s][%s]=%s"%(section,option,str(result))) PLOG.debug("Option[%s][%s]=%s"%(section,option,str(result)))
else: else:
self._conf.set(section,option,str(default)) self._conf.set(section,option,str(default))
result=default result=default
else: else:
self._conf.add_section(section) self._conf.add_section(section)
self._conf.set(section,option,str(default)) self._conf.set(section,option,str(default))
result=default result=default
return result return result
def getstr(self,section,option,default=""): def getstr(self,section,option,default=""):
return self._readvalue(self._conf.get, section, option, default) return self._readvalue(self._conf.get, section, option, default)
def getint(self,section,option,default=0): def getint(self,section,option,default=0):
return self._readvalue(self._conf.getint, section, option, default) return self._readvalue(self._conf.getint, section, option, default)
def getfloat(self,section,option,default=0.0): def getfloat(self,section,option,default=0.0):
return self._readvalue(self._conf.getfloat, section, option, default) return self._readvalue(self._conf.getfloat, section, option, default)
def getboolean(self,section,option,default=False): def getboolean(self,section,option,default=False):
return self._readvalue(self._conf.getboolean, section, option, default) return self._readvalue(self._conf.getboolean, section, option, default)

View File

@ -1,140 +1,140 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys, os, time, atexit import sys, os, time, atexit
from signal import SIGTERM from signal import SIGTERM
def check_pid(pid): def check_pid(pid):
""" Check For the existence of a unix pid. """ """ Check For the existence of a unix pid. """
if pid == 0:return False if pid == 0:return False
try: try:
os.kill(pid, 0) os.kill(pid, 0)
except OSError: except OSError:
return False return False
else: else:
return True return True
class daemon: class daemon:
""" """
A generic daemon class. A generic daemon class.
Usage: subclass the Daemon class and override the run() method Usage: subclass the Daemon class and override the run() method
""" """
def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
self.stdin = stdin self.stdin = stdin
self.stdout = stdout self.stdout = stdout
self.stderr = stderr self.stderr = stderr
self.pidfile = pidfile self.pidfile = pidfile
def daemonize(self): def daemonize(self):
""" """
do the UNIX double-fork magic, see Stevens' "Advanced do the UNIX double-fork magic, see Stevens' "Advanced
Programming in the UNIX Environment" for details (ISBN 0201563177) Programming in the UNIX Environment" for details (ISBN 0201563177)
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
""" """
try: try:
pid = os.fork() pid = os.fork()
if pid > 0: if pid > 0:
# exit first parent # exit first parent
sys.exit(0) sys.exit(0)
except OSError, e: except OSError, e:
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1) sys.exit(1)
# decouple from parent environment # decouple from parent environment
os.chdir("/") os.chdir("/")
os.setsid() os.setsid()
os.umask(0) os.umask(0)
# do second fork # do second fork
try: try:
pid = os.fork() pid = os.fork()
if pid > 0: if pid > 0:
# exit from second parent # exit from second parent
sys.exit(0) sys.exit(0)
except OSError, e: except OSError, e:
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1) sys.exit(1)
# redirect standard file descriptors # redirect standard file descriptors
sys.stdout.flush() sys.stdout.flush()
sys.stderr.flush() sys.stderr.flush()
si = file(self.stdin, 'r') si = file(self.stdin, 'r')
so = file(self.stdout, 'a+') so = file(self.stdout, 'a+')
se = file(self.stderr, 'a+', 0) se = file(self.stderr, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno()) os.dup2(se.fileno(), sys.stderr.fileno())
# write pidfile # write pidfile
atexit.register(self.delpid) atexit.register(self.delpid)
pid = str(os.getpid()) pid = str(os.getpid())
file(self.pidfile, 'w+').write("%s\n" % pid) file(self.pidfile, 'w+').write("%s\n" % pid)
def delpid(self): def delpid(self):
os.remove(self.pidfile) os.remove(self.pidfile)
def start(self): def start(self):
""" """
Start the daemon Start the daemon
""" """
# Check for a pidfile to see if the daemon already runs # Check for a pidfile to see if the daemon already runs
try: try:
pf = file(self.pidfile, 'r') pf = file(self.pidfile, 'r')
pid = int(pf.read().strip()) pid = int(pf.read().strip())
pf.close() pf.close()
except IOError: except IOError:
pid = None pid = None
if pid and check_pid(pid): if pid and check_pid(pid):
message = "pidfile %s already exist. Daemon already running?\n" message = "pidfile %s already exist. Daemon already running?\n"
sys.stderr.write(message % self.pidfile) sys.stderr.write(message % self.pidfile)
sys.exit(1) sys.exit(1)
print("daemon start...") print("daemon start...")
# Start the daemon # Start the daemon
self.daemonize() self.daemonize()
self.run() self.run()
def stop(self): def stop(self):
""" """
Stop the daemon Stop the daemon
""" """
# Get the pid from the pidfile # Get the pid from the pidfile
try: try:
pf = file(self.pidfile, 'r') pf = file(self.pidfile, 'r')
pid = int(pf.read().strip()) pid = int(pf.read().strip())
pf.close() pf.close()
except IOError: except IOError:
pid = None pid = None
if not pid: if not pid:
message = "pidfile %s does not exist. Daemon not running?\n" message = "pidfile %s does not exist. Daemon not running?\n"
sys.stderr.write(message % self.pidfile) sys.stderr.write(message % self.pidfile)
return # not an error in a restart return # not an error in a restart
# Try killing the daemon process # Try killing the daemon process
try: try:
while 1: while 1:
os.kill(pid, SIGTERM) os.kill(pid, SIGTERM)
time.sleep(0.1) time.sleep(0.1)
except OSError, err: except OSError, err:
err = str(err) err = str(err)
if err.find("No such process") > 0: if err.find("No such process") > 0:
if os.path.exists(self.pidfile): if os.path.exists(self.pidfile):
os.remove(self.pidfile) os.remove(self.pidfile)
else: else:
print(str(err)) print(str(err))
sys.exit(1) sys.exit(1)
def restart(self): def restart(self):
""" """
Restart the daemon Restart the daemon
""" """
self.stop() self.stop()
self.start() self.start()
def run(self): def run(self):
""" """
You should override this method when you subclass Daemon. It will be called after the process has been You should override this method when you subclass Daemon. It will be called after the process has been
daemonized by start() or restart(). daemonized by start() or restart().
""" """

View File

@ -1,58 +1,58 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# 异常类 # 异常类
class PibotError(Exception): class PibotError(Exception):
def __init__(self, errcode, errmsg): def __init__(self, errcode, errmsg):
self.errcode = errcode self.errcode = errcode
self.errmsg = errmsg self.errmsg = errmsg
#Exception.__init__(self,self.__str__()) #Exception.__init__(self,self.__str__())
def msg(self, msg): def msg(self, msg):
if not msg is None:return PibotError(self.errcode, msg) if not msg is None:return PibotError(self.errcode, msg)
return PibotError(8,"unknow error") return PibotError(8,"unknow error")
def __str__(self): def __str__(self):
return "PibotError:%s(%d)"%(self.errmsg,self.errcode) return "PibotError:%s(%d)"%(self.errmsg,self.errcode)
@property @property
def message(self): def message(self):
return str(self) return str(self)
# 声明 # 声明
# 成功 # 成功
success=PibotError(0,"null") success=PibotError(0,"null")
# 通用失败 # 通用失败
fail=PibotError(1,"fail") fail=PibotError(1,"fail")
# 参数无效 # 参数无效
invalidParameter=PibotError(2,"invalid parameter") invalidParameter=PibotError(2,"invalid parameter")
# 不支持 # 不支持
noSupport=PibotError(3,"no support") noSupport=PibotError(3,"no support")
# 不存在 # 不存在
noExist=PibotError(4,"no exist") noExist=PibotError(4,"no exist")
# 超时 # 超时
timeout=PibotError(5,"timeout") timeout=PibotError(5,"timeout")
# 繁忙 # 繁忙
busy=PibotError(6,"busy") busy=PibotError(6,"busy")
# 缺少参数 # 缺少参数
missParameter=PibotError(7,"miss parameter") missParameter=PibotError(7,"miss parameter")
# 系统错误(通用错误) # 系统错误(通用错误)
systemError=PibotError(8,"system error") systemError=PibotError(8,"system error")
# 密码错误 # 密码错误
invalidPassword=PibotError(9,"invalid password") invalidPassword=PibotError(9,"invalid password")
# 编码失败 # 编码失败
encodeFailed=PibotError(10,"encode failed") encodeFailed=PibotError(10,"encode failed")
# 数据库操作失败 # 数据库操作失败
dbOpertationFailed=PibotError(11,"db error") dbOpertationFailed=PibotError(11,"db error")
# 已占用 # 已占用
occupied=PibotError(12,"occupied") occupied=PibotError(12,"occupied")
# session不存在 # session不存在
noSession = PibotError(13,'cannot find session') noSession = PibotError(13,'cannot find session')
#没有找到 #没有找到
noFound = PibotError(14, "no found") noFound = PibotError(14, "no found")
#已经存在 #已经存在
existed = PibotError(15, "existed") existed = PibotError(15, "existed")
#已经锁定 #已经锁定
locked = PibotError(16, "locked") locked = PibotError(16, "locked")
#已经过期 #已经过期
expired = PibotError(17, "is expired") expired = PibotError(17, "is expired")
#无效的参数 #无效的参数
invalidParameter = PibotError(18, "invalid parameter") invalidParameter = PibotError(18, "invalid parameter")

View File

@ -1,259 +1,259 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys,os import sys,os
import datetime import datetime
import threading import threading
import pypibot.assistant as assistant import pypibot.assistant as assistant
import platform import platform
if assistant.is_python3(): if assistant.is_python3():
import _thread import _thread
else: else:
import thread import thread
import traceback import traceback
""" """
%a Locales abbreviated weekday name. %a Locales abbreviated weekday name.
%A Locales full weekday name. %A Locales full weekday name.
%b Locales abbreviated month name. %b Locales abbreviated month name.
%B Locales full month name. %B Locales full month name.
%c Locales appropriate date and time representation. %c Locales appropriate date and time representation.
%d Day of the month as a decimal number [01,31]. %d Day of the month as a decimal number [01,31].
%H Hour (24-hour clock) as a decimal number [00,23]. %H Hour (24-hour clock) as a decimal number [00,23].
%I Hour (12-hour clock) as a decimal number [01,12]. %I Hour (12-hour clock) as a decimal number [01,12].
%j Day of the year as a decimal number [001,366]. %j Day of the year as a decimal number [001,366].
%m Month as a decimal number [01,12]. %m Month as a decimal number [01,12].
%M Minute as a decimal number [00,59]. %M Minute as a decimal number [00,59].
%p Locales equivalent of either AM or PM. (1) %p Locales equivalent of either AM or PM. (1)
%S Second as a decimal number [00,61]. (2) %S Second as a decimal number [00,61]. (2)
%U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. (3) %U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. (3)
%w Weekday as a decimal number [0(Sunday),6]. %w Weekday as a decimal number [0(Sunday),6].
%W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (3) %W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (3)
%x Locales appropriate date representation. %x Locales appropriate date representation.
%X Locales appropriate time representation. %X Locales appropriate time representation.
%y Year without century as a decimal number [00,99]. %y Year without century as a decimal number [00,99].
%Y Year with century as a decimal number. %Y Year with century as a decimal number.
%Z Time zone name (no characters if no time zone exists). %Z Time zone name (no characters if no time zone exists).
%% A literal '%' character. %% A literal '%' character.
""" """
isWindows=False isWindows=False
if platform.system()=='Windows': if platform.system()=='Windows':
isWindows=True isWindows=True
defaultEncodeing="utf8" defaultEncodeing="utf8"
if "-utf8" in sys.argv: if "-utf8" in sys.argv:
defaultEncodeing="utf-8" defaultEncodeing="utf-8"
if "-gbk" in sys.argv: if "-gbk" in sys.argv:
defaultEncodeing="gbk" defaultEncodeing="gbk"
TRACE=5 TRACE=5
DEBUG=4 DEBUG=4
INFORMATION=3 INFORMATION=3
WARNING=2 WARNING=2
ERROR=1 ERROR=1
NONE=0 NONE=0
MAX_MSG_SIZE = 4096 MAX_MSG_SIZE = 4096
def getLevelFromString(level): def getLevelFromString(level):
level=level.lower() level=level.lower()
if level=='t' or level=='trace':return 5 if level=='t' or level=='trace':return 5
elif level=='d' or level=='debug':return 4 elif level=='d' or level=='debug':return 4
elif level=='i' or level=='info':return 3 elif level=='i' or level=='info':return 3
elif level=='w' or level=='wran':return 2 elif level=='w' or level=='wran':return 2
elif level=='e' or level=='error':return 1 elif level=='e' or level=='error':return 1
else :return 0 else :return 0
def getLevelString(level): def getLevelString(level):
if level==TRACE:return "T" if level==TRACE:return "T"
elif level==DEBUG:return "D" elif level==DEBUG:return "D"
elif level==INFORMATION:return "I" elif level==INFORMATION:return "I"
elif level==WARNING:return "W" elif level==WARNING:return "W"
elif level==ERROR:return "E" elif level==ERROR:return "E"
else:return "N" else:return "N"
class PibotLog: class PibotLog:
def __init__(self): def __init__(self):
self.isEnableControlLog=True self.isEnableControlLog=True
self.fileTemple=None self.fileTemple=None
self.filePath="" self.filePath=""
self.level=5 self.level=5
self._lock=threading.RLock() self._lock=threading.RLock()
self.fd=None self.fd=None
self.fd_day=-1 self.fd_day=-1
def setLevel(self,level): def setLevel(self,level):
self.level=getLevelFromString(level) self.level=getLevelFromString(level)
def enableControllog(self,enable): def enableControllog(self,enable):
self.isEnableControlLog=enable self.isEnableControlLog=enable
def enableFileLog(self,fileName): def enableFileLog(self,fileName):
self.fileTemple=fileName self.fileTemple=fileName
self.updateFilelog() self.updateFilelog()
def updateFilelog(self): def updateFilelog(self):
fn=assistant.SF(self.fileTemple) fn=assistant.SF(self.fileTemple)
if fn!=self.filePath: if fn!=self.filePath:
self.i("new log file:%s",fn) self.i("new log file:%s",fn)
if self.fd: if self.fd:
self.fd.close() self.fd.close()
self.fd=None self.fd=None
self.fd_day=-1 self.fd_day=-1
self.filePath="" self.filePath=""
try: try:
path=os.path.dirname(fn) path=os.path.dirname(fn)
if path!="" and not os.path.isdir(path):os.makedirs(path) if path!="" and not os.path.isdir(path):os.makedirs(path)
self.fd=open(fn,mode="w") self.fd=open(fn,mode="w")
try: try:
linkfn = fn.split(".log.", 1)[0] + ".INFO" linkfn = fn.split(".log.", 1)[0] + ".INFO"
if os.path.exists(linkfn): if os.path.exists(linkfn):
os.remove(linkfn) os.remove(linkfn)
(filepath, tempfilename) = os.path.split(fn) (filepath, tempfilename) = os.path.split(fn)
os.symlink(tempfilename, linkfn) os.symlink(tempfilename, linkfn)
except: except:
pass pass
self.fd_day=datetime.datetime.now().day self.fd_day=datetime.datetime.now().day
self.filePath=fn self.filePath=fn
except Exception as e: except Exception as e:
print("open file fail!file=%s,err=%s"%(fn,e)) print("open file fail!file=%s,err=%s"%(fn,e))
def _output(self,level,msg,args): def _output(self,level,msg,args):
if self.level<level:return if self.level<level:return
try: try:
if len(args)>0: if len(args)>0:
t=[] t=[]
for arg in args: for arg in args:
if isinstance(arg,Exception): if isinstance(arg,Exception):
t.append(traceback.format_exc(arg).decode('utf-8')) t.append(traceback.format_exc(arg).decode('utf-8'))
elif isinstance(arg,bytes) : elif isinstance(arg,bytes) :
t.append(arg.decode('utf-8')) t.append(arg.decode('utf-8'))
else: else:
t.append(arg) t.append(arg)
args=tuple(t) args=tuple(t)
try: try:
msg=msg%args msg=msg%args
except: except:
try: try:
for arg in args: for arg in args:
msg=msg+str(arg)+" " msg=msg+str(arg)+" "
except Exception as e: except Exception as e:
msg=msg+"==LOG ERROR==>%s"%(e) msg=msg+"==LOG ERROR==>%s"%(e)
if len(msg)>MAX_MSG_SIZE:msg=msg[0:MAX_MSG_SIZE] if len(msg)>MAX_MSG_SIZE:msg=msg[0:MAX_MSG_SIZE]
now=datetime.datetime.now() now=datetime.datetime.now()
msg=msg+"\r\n" msg=msg+"\r\n"
if assistant.is_python3(): if assistant.is_python3():
id = _thread.get_ident() id = _thread.get_ident()
else: else:
id = thread.get_ident() id = thread.get_ident()
s="[%s] %04d-%02d-%02d %02d:%02d:%02d.%03d (0x%04X):%s"%(getLevelString(level),now.year,now.month,now.day,now.hour,now.minute,now.second,now.microsecond/1000,(id>>8)&0xffff,msg) s="[%s] %04d-%02d-%02d %02d:%02d:%02d.%03d (0x%04X):%s"%(getLevelString(level),now.year,now.month,now.day,now.hour,now.minute,now.second,now.microsecond/1000,(id>>8)&0xffff,msg)
prefix='' prefix=''
suffix='' suffix=''
if not isWindows: if not isWindows:
suffix='\033[0m' suffix='\033[0m'
if level==TRACE: if level==TRACE:
prefix='\033[0;37m' prefix='\033[0;37m'
elif level==DEBUG: elif level==DEBUG:
prefix='\033[1m' prefix='\033[1m'
elif level==INFORMATION: elif level==INFORMATION:
prefix='\033[0;32m' prefix='\033[0;32m'
elif level==WARNING: elif level==WARNING:
prefix='\033[0;33m' prefix='\033[0;33m'
elif level==ERROR: elif level==ERROR:
prefix='\033[0;31m' prefix='\033[0;31m'
else: else:
pass pass
self._lock.acquire() self._lock.acquire()
try: try:
if self.isEnableControlLog: if self.isEnableControlLog:
sys.stdout.write((prefix+s+suffix)) sys.stdout.write((prefix+s+suffix))
if self.fd: if self.fd:
if self.fd_day!=now.day: if self.fd_day!=now.day:
self.updateFilelog() self.updateFilelog()
if assistant.is_python3(): if assistant.is_python3():
self.fd.write(s) self.fd.write(s)
else: else:
self.fd.write(s.encode('utf-8')) self.fd.write(s.encode('utf-8'))
self.fd.flush() self.fd.flush()
finally: finally:
self._lock.release() self._lock.release()
except Exception as e: except Exception as e:
if assistant.is_python3(): if assistant.is_python3():
print(e) print(e)
else: else:
print("PibotLog._output crash!err=%s"%traceback.format_exc(e)) print("PibotLog._output crash!err=%s"%traceback.format_exc(e))
def trace(self,msg,*args): def trace(self,msg,*args):
self._output(TRACE,msg,args) self._output(TRACE,msg,args)
def t(self,msg,*args): def t(self,msg,*args):
self._output(TRACE,msg,args) self._output(TRACE,msg,args)
def debug(self,msg,*args): def debug(self,msg,*args):
self._output(DEBUG, msg,args) self._output(DEBUG, msg,args)
def d(self,msg,*args): def d(self,msg,*args):
self._output(DEBUG, msg,args) self._output(DEBUG, msg,args)
def info(self,msg,*args): def info(self,msg,*args):
self._output(INFORMATION, msg,args) self._output(INFORMATION, msg,args)
def i(self,msg,*args): def i(self,msg,*args):
self._output(INFORMATION, msg,args) self._output(INFORMATION, msg,args)
def warn(self,msg,*args): def warn(self,msg,*args):
self._output(WARNING, msg,args) self._output(WARNING, msg,args)
def w(self,msg,*args): def w(self,msg,*args):
self._output(WARNING, msg,args) self._output(WARNING, msg,args)
def error(self,msg,*args): def error(self,msg,*args):
self._output(ERROR, msg,args) self._output(ERROR, msg,args)
def e(self,msg,*args): def e(self,msg,*args):
self._output(ERROR, msg,args) self._output(ERROR, msg,args)
def _log(self,level,msg,args): def _log(self,level,msg,args):
self._output(level, msg,args) self._output(level, msg,args)
def createNamedLog(self,name): def createNamedLog(self,name):
return NamedLog(name) return NamedLog(name)
log=PibotLog() log=PibotLog()
class NamedLog: class NamedLog:
def __init__(self,name=None): def __init__(self,name=None):
global log global log
self.name='' self.name=''
if name: if name:
self.name='['+name+']' self.name='['+name+']'
self.log=log self.log=log
def trace(self,msg,*args): def trace(self,msg,*args):
msg=self.name+msg msg=self.name+msg
self.log._log(TRACE,msg,args) self.log._log(TRACE,msg,args)
def t(self,msg,*args): def t(self,msg,*args):
msg=self.name+msg msg=self.name+msg
self.log._log(TRACE,msg,args) self.log._log(TRACE,msg,args)
def debug(self,msg,*args): def debug(self,msg,*args):
msg=self.name+msg msg=self.name+msg
self.log._log(DEBUG, msg,args) self.log._log(DEBUG, msg,args)
def d(self,msg,*args): def d(self,msg,*args):
msg=self.name+msg msg=self.name+msg
self.log._log(DEBUG, msg,args) self.log._log(DEBUG, msg,args)
def info(self,msg,*args): def info(self,msg,*args):
msg=self.name+msg msg=self.name+msg
self.log._log(INFORMATION, msg,args) self.log._log(INFORMATION, msg,args)
def i(self,msg,*args): def i(self,msg,*args):
msg=self.name+msg msg=self.name+msg
self.log._log(INFORMATION, msg,args) self.log._log(INFORMATION, msg,args)
def warn(self,msg,*args): def warn(self,msg,*args):
msg=self.name+msg msg=self.name+msg
self.log._log(WARNING, msg,args) self.log._log(WARNING, msg,args)
def w(self,msg,*args): def w(self,msg,*args):
msg=self.name+msg msg=self.name+msg
self.log._log(WARNING, msg,args) self.log._log(WARNING, msg,args)
def error(self,msg,*args): def error(self,msg,*args):
msg=self.name+msg msg=self.name+msg
self.log._log(ERROR, msg,args) self.log._log(ERROR, msg,args)
def e(self,msg,*args): def e(self,msg,*args):
msg=self.name+msg msg=self.name+msg
self.log._log(ERROR, msg,args) self.log._log(ERROR, msg,args)
if __name__ == "__main__": if __name__ == "__main__":
log.trace("1%s","hello") log.trace("1%s","hello")
log.debug("2%d",12) log.debug("2%d",12)
try: try:
raise Exception("EXC") raise Exception("EXC")
except Exception as e: except Exception as e:
log.info("3%s",e) log.info("3%s",e)
log.warn("1") log.warn("1")
log.error("1") log.error("1")
#log.enableFileLog("$(scriptpath)test_$(Date8)_$(filenumber2).log") #log.enableFileLog("$(scriptpath)test_$(Date8)_$(filenumber2).log")
log.trace("1") log.trace("1")
log.debug("1") log.debug("1")
log.info("1") log.info("1")
log.warn("1") log.warn("1")
log.error("1") log.error("1")
log=NamedLog("test") log=NamedLog("test")
log.d("1") log.d("1")
log.i("1") log.i("1")
log.warn("1") log.warn("1")
log.error("1=%d,%s",100,e) log.error("1=%d,%s",100,e)

View File

@ -1,240 +1,240 @@
import struct import struct
params_size=29 params_size=29
# main board # main board
class MessageID: class MessageID:
ID_GET_VERSION = 0 ID_GET_VERSION = 0
ID_SET_ROBOT_PARAMETER = 1 ID_SET_ROBOT_PARAMETER = 1
ID_GET_ROBOT_PARAMETER = 2 ID_GET_ROBOT_PARAMETER = 2
ID_INIT_ODOM = 3 ID_INIT_ODOM = 3
ID_SET_VEL = 4 ID_SET_VEL = 4
ID_GET_ODOM = 5 ID_GET_ODOM = 5
ID_GET_PID_DEBUG = 6 ID_GET_PID_DEBUG = 6
ID_GET_IMU = 7 ID_GET_IMU = 7
ID_GET_ENCODER_COUNT = 8 ID_GET_ENCODER_COUNT = 8
ID_SET_MOTOR_PWM = 9 ID_SET_MOTOR_PWM = 9
class RobotMessage: class RobotMessage:
def pack(self): def pack(self):
return b'' return b''
def unpack(self): def unpack(self):
return True return True
class RobotFirmwareInfo(RobotMessage): class RobotFirmwareInfo(RobotMessage):
def __init__(self): def __init__(self):
self.version = '' self.version = ''
self.build_time = '' self.build_time = ''
def unpack(self, data): def unpack(self, data):
try: try:
upk = struct.unpack('16s16s', bytes(data)) upk = struct.unpack('16s16s', bytes(data))
except: except:
return False return False
[self.version, self.build_time] = upk [self.version, self.build_time] = upk
return True return True
class RobotImuType: class RobotImuType:
IMU_TYPE_GY65 = 49 IMU_TYPE_GY65 = 49
IMU_TYPE_GY85 = 69 IMU_TYPE_GY85 = 69
IMU_TYPE_GY87 = 71 IMU_TYPE_GY87 = 71
class RobotModelType: class RobotModelType:
MODEL_TYPE_2WD_DIFF = 1 MODEL_TYPE_2WD_DIFF = 1
MODEL_TYPE_4WD_DIFF = 2 MODEL_TYPE_4WD_DIFF = 2
MODEL_TYPE_3WD_OMNI = 101 MODEL_TYPE_3WD_OMNI = 101
MODEL_TYPE_4WD_OMNI = 102 MODEL_TYPE_4WD_OMNI = 102
MODEL_TYPE_4WD_MECANUM = 201 MODEL_TYPE_4WD_MECANUM = 201
class RobotParameters(): class RobotParameters():
def __init__(self, wheel_diameter=0, \ def __init__(self, wheel_diameter=0, \
wheel_track=0, \ wheel_track=0, \
encoder_resolution=0, \ encoder_resolution=0, \
do_pid_interval=0, \ do_pid_interval=0, \
kp=0, \ kp=0, \
ki=0, \ ki=0, \
kd=0, \ kd=0, \
ko=0, \ ko=0, \
cmd_last_time=0, \ cmd_last_time=0, \
max_v_liner_x=0, \ max_v_liner_x=0, \
max_v_liner_y=0, \ max_v_liner_y=0, \
max_v_angular_z=0, \ max_v_angular_z=0, \
imu_type=0, \ imu_type=0, \
motor_ratio=0, \ motor_ratio=0, \
model_type=0, \ model_type=0, \
motor_nonexchange_flag=255, \ motor_nonexchange_flag=255, \
encoder_nonexchange_flag=255, \ encoder_nonexchange_flag=255, \
): ):
self.wheel_diameter = wheel_diameter self.wheel_diameter = wheel_diameter
self.wheel_track = wheel_track self.wheel_track = wheel_track
self.encoder_resolution = encoder_resolution self.encoder_resolution = encoder_resolution
self.do_pid_interval = do_pid_interval self.do_pid_interval = do_pid_interval
self.kp = kp self.kp = kp
self.ki = ki self.ki = ki
self.kd = kd self.kd = kd
self.ko = ko self.ko = ko
self.cmd_last_time = cmd_last_time self.cmd_last_time = cmd_last_time
self.max_v_liner_x = max_v_liner_x self.max_v_liner_x = max_v_liner_x
self.max_v_liner_y = max_v_liner_y self.max_v_liner_y = max_v_liner_y
self.max_v_angular_z = max_v_angular_z self.max_v_angular_z = max_v_angular_z
self.imu_type = imu_type self.imu_type = imu_type
self.motor_ratio = motor_ratio self.motor_ratio = motor_ratio
self.model_type = model_type self.model_type = model_type
self.motor_nonexchange_flag = motor_nonexchange_flag self.motor_nonexchange_flag = motor_nonexchange_flag
self.encoder_nonexchange_flag = encoder_nonexchange_flag self.encoder_nonexchange_flag = encoder_nonexchange_flag
reserve=b'\xff' reserve=b'\xff'
self.reserve=b'' self.reserve=b''
for i in range(64-params_size): for i in range(64-params_size):
self.reserve+=reserve self.reserve+=reserve
robotParam = RobotParameters() robotParam = RobotParameters()
class GetRobotParameters(RobotMessage): class GetRobotParameters(RobotMessage):
def __init__(self): def __init__(self):
self.param = robotParam self.param = robotParam
def unpack(self, data): def unpack(self, data):
#print(bytes(data), len(bytes(data))) #print(bytes(data), len(bytes(data)))
upk = struct.unpack('<3H1B8H1B1H3B%ds'%(64-params_size), bytes(data)) upk = struct.unpack('<3H1B8H1B1H3B%ds'%(64-params_size), bytes(data))
[self.param.wheel_diameter, [self.param.wheel_diameter,
self.param.wheel_track, self.param.wheel_track,
self.param.encoder_resolution, self.param.encoder_resolution,
self.param.do_pid_interval, self.param.do_pid_interval,
self.param.kp, self.param.kp,
self.param.ki, self.param.ki,
self.param.kd, self.param.kd,
self.param.ko, self.param.ko,
self.param.cmd_last_time, self.param.cmd_last_time,
self.param.max_v_liner_x, self.param.max_v_liner_x,
self.param.max_v_liner_y, self.param.max_v_liner_y,
self.param.max_v_angular_z, self.param.max_v_angular_z,
self.param.imu_type, self.param.imu_type,
self.param.motor_ratio, self.param.motor_ratio,
self.param.model_type, self.param.model_type,
self.param.motor_nonexchange_flag, self.param.motor_nonexchange_flag,
self.param.encoder_nonexchange_flag, self.param.encoder_nonexchange_flag,
self.param.reserve] = upk self.param.reserve] = upk
return True return True
class SetRobotParameters(RobotMessage): class SetRobotParameters(RobotMessage):
def __init__(self): def __init__(self):
self.param = robotParam self.param = robotParam
def pack(self): def pack(self):
data = [self.param.wheel_diameter, data = [self.param.wheel_diameter,
self.param.wheel_track, self.param.wheel_track,
self.param.encoder_resolution, self.param.encoder_resolution,
self.param.do_pid_interval, self.param.do_pid_interval,
self.param.kp, self.param.kp,
self.param.ki, self.param.ki,
self.param.kd, self.param.kd,
self.param.ko, self.param.ko,
self.param.cmd_last_time, self.param.cmd_last_time,
self.param.max_v_liner_x, self.param.max_v_liner_x,
self.param.max_v_liner_y, self.param.max_v_liner_y,
self.param.max_v_angular_z, self.param.max_v_angular_z,
self.param.imu_type, self.param.imu_type,
self.param.motor_ratio, self.param.motor_ratio,
self.param.model_type, self.param.model_type,
self.param.motor_nonexchange_flag, self.param.motor_nonexchange_flag,
self.param.encoder_nonexchange_flag, self.param.encoder_nonexchange_flag,
self.param.reserve] self.param.reserve]
print(data) print(data)
pk = struct.pack('<3H1B8H1B1H3B%ds'%(64-(3*2+1+8*2+1+2+3)), *data) pk = struct.pack('<3H1B8H1B1H3B%ds'%(64-(3*2+1+8*2+1+2+3)), *data)
return pk return pk
def unpack(self, data): def unpack(self, data):
return True return True
class RobotVel(RobotMessage): class RobotVel(RobotMessage):
def __init__(self): def __init__(self):
self.v_liner_x = 0 self.v_liner_x = 0
self.v_liner_y = 0 self.v_liner_y = 0
self.v_angular_z = 0 self.v_angular_z = 0
def pack(self): def pack(self):
data = [self.v_liner_x, data = [self.v_liner_x,
self.v_liner_y, self.v_liner_y,
self.v_angular_z] self.v_angular_z]
pk = struct.pack('3h', *data) pk = struct.pack('3h', *data)
return pk return pk
def unpack(self, data): def unpack(self, data):
return True return True
#todo the rest of the message classes #todo the rest of the message classes
class RobotOdom(RobotMessage): class RobotOdom(RobotMessage):
def __init__(self): def __init__(self):
self.v_liner_x = 0 self.v_liner_x = 0
self.v_liner_y = 0 self.v_liner_y = 0
self.v_angular_z = 0 self.v_angular_z = 0
self.x = 0 self.x = 0
self.y = 0 self.y = 0
self.yaw = 0 self.yaw = 0
def unpack(self, data): def unpack(self, data):
try: try:
upk = struct.unpack('<3H2l1H', bytes(data)) upk = struct.unpack('<3H2l1H', bytes(data))
except: except:
return False return False
[self.v_liner_x, [self.v_liner_x,
self.v_liner_y, self.v_liner_y,
self.v_angular_z, self.v_angular_z,
self.x, self.x,
self.y, self.y,
self.yaw] = upk self.yaw] = upk
return True return True
class RobotPIDData(RobotMessage): class RobotPIDData(RobotMessage):
pass pass
class RobotIMU(RobotMessage): class RobotIMU(RobotMessage):
def __init__(self): def __init__(self):
self.imu = [0]*9 self.imu = [0]*9
def unpack(self, data): def unpack(self, data):
try: try:
upk = struct.unpack('<9f', bytes(data)) upk = struct.unpack('<9f', bytes(data))
except: except:
return False return False
self.imu = upk self.imu = upk
return True return True
class RobotEncoderCount(RobotMessage): class RobotEncoderCount(RobotMessage):
def __init__(self): def __init__(self):
self.encoder = [0]*4 self.encoder = [0]*4
def unpack(self, data): def unpack(self, data):
try: try:
upk = struct.unpack('<4f', bytes(data)) upk = struct.unpack('<4f', bytes(data))
except: except:
return False return False
self.encoder = upk self.encoder = upk
return True return True
class RobotMotorPWM(RobotMessage): class RobotMotorPWM(RobotMessage):
def __init__(self): def __init__(self):
self.pwm = [0]*4 self.pwm = [0]*4
def pack(self): def pack(self):
pk = struct.pack('4h', *self.pwm) pk = struct.pack('4h', *self.pwm)
return pk return pk
def unpack(self, data): def unpack(self, data):
return True return True
BoardDataDict = {MessageID.ID_GET_VERSION:RobotFirmwareInfo(), BoardDataDict = {MessageID.ID_GET_VERSION:RobotFirmwareInfo(),
MessageID.ID_GET_ROBOT_PARAMETER:GetRobotParameters(), MessageID.ID_GET_ROBOT_PARAMETER:GetRobotParameters(),
MessageID.ID_SET_ROBOT_PARAMETER:SetRobotParameters(), MessageID.ID_SET_ROBOT_PARAMETER:SetRobotParameters(),
MessageID.ID_SET_VEL:RobotVel(), MessageID.ID_SET_VEL:RobotVel(),
MessageID.ID_GET_ODOM:RobotOdom(), MessageID.ID_GET_ODOM:RobotOdom(),
MessageID.ID_GET_PID_DEBUG: RobotPIDData(), MessageID.ID_GET_PID_DEBUG: RobotPIDData(),
MessageID.ID_GET_IMU: RobotIMU(), MessageID.ID_GET_IMU: RobotIMU(),
MessageID.ID_GET_ENCODER_COUNT: RobotEncoderCount(), MessageID.ID_GET_ENCODER_COUNT: RobotEncoderCount(),
MessageID.ID_SET_MOTOR_PWM: RobotMotorPWM(), MessageID.ID_SET_MOTOR_PWM: RobotMotorPWM(),
} }

View File

@ -1,115 +1,115 @@
import platform import platform
import sys import sys
sys.path.append("..") sys.path.append("..")
import pypibot import pypibot
from pypibot import log from pypibot import log
from transport import Transport from transport import Transport
from dataholder import MessageID from dataholder import MessageID
import params import params
import time import time
import signal import signal
#for linux #for linux
port="/dev/pibot" port="/dev/pibot"
#for windows #for windows
#port="com3" #port="com3"
pypibot.assistant.enableGlobalExcept() pypibot.assistant.enableGlobalExcept()
#log.enableFileLog(log_dir + "ros_$(Date8)_$(filenumber2).log") #log.enableFileLog(log_dir + "ros_$(Date8)_$(filenumber2).log")
log.setLevel("i") log.setLevel("i")
run_flag = True run_flag = True
def exit(signum, frame): def exit(signum, frame):
global run_flag global run_flag
run_flag = False run_flag = False
if __name__ == '__main__': if __name__ == '__main__':
signal.signal(signal.SIGINT, exit) signal.signal(signal.SIGINT, exit)
mboard = Transport(port, params.pibotBaud) mboard = Transport(port, params.pibotBaud)
if not mboard.start(): if not mboard.start():
log.error("can not open %s"%port) log.error("can not open %s"%port)
sys.exit() sys.exit()
DataHolder = mboard.getDataHolder() DataHolder = mboard.getDataHolder()
for num in range(0,3): for num in range(0,3):
log.info("****************get robot version*****************") log.info("****************get robot version*****************")
boardVersion = DataHolder[MessageID.ID_GET_VERSION] boardVersion = DataHolder[MessageID.ID_GET_VERSION]
p = mboard.request(MessageID.ID_GET_VERSION) p = mboard.request(MessageID.ID_GET_VERSION)
if p: if p:
log.info("firmware version:%s buildtime:%s\r\n"%(boardVersion.version.decode(), boardVersion.build_time.decode())) log.info("firmware version:%s buildtime:%s\r\n"%(boardVersion.version.decode(), boardVersion.build_time.decode()))
break break
else: else:
log.error('read firmware version err\r\n') log.error('read firmware version err\r\n')
import time import time
time.sleep(1) time.sleep(1)
if num == 2: if num == 2:
log.error('please check connection or baudrate\r\n') log.error('please check connection or baudrate\r\n')
sys.exit() sys.exit()
# get robot parameter # get robot parameter
robotParam = DataHolder[MessageID.ID_GET_ROBOT_PARAMETER] robotParam = DataHolder[MessageID.ID_GET_ROBOT_PARAMETER]
p = mboard.request(MessageID.ID_GET_ROBOT_PARAMETER) p = mboard.request(MessageID.ID_GET_ROBOT_PARAMETER)
if p: if p:
log.info("model_type:%d wheel_diameter:%d wheel_track:%d encoder_resolution:%d" \ log.info("model_type:%d wheel_diameter:%d wheel_track:%d encoder_resolution:%d" \
%(robotParam.param.model_type, \ %(robotParam.param.model_type, \
robotParam.param.wheel_diameter, \ robotParam.param.wheel_diameter, \
robotParam.param.wheel_track, \ robotParam.param.wheel_track, \
robotParam.param.encoder_resolution robotParam.param.encoder_resolution
)) ))
log.info("do_pid_interval:%d kp:%d ki:%d kd:%d ko:%d" \ log.info("do_pid_interval:%d kp:%d ki:%d kd:%d ko:%d" \
%(robotParam.param.do_pid_interval, \ %(robotParam.param.do_pid_interval, \
robotParam.param.kp, \ robotParam.param.kp, \
robotParam.param.ki, \ robotParam.param.ki, \
robotParam.param.kd, \ robotParam.param.kd, \
robotParam.param.ko)) robotParam.param.ko))
log.info("cmd_last_time:%d imu_type:%d" \ log.info("cmd_last_time:%d imu_type:%d" \
%(robotParam.param.cmd_last_time,\ %(robotParam.param.cmd_last_time,\
robotParam.param.imu_type robotParam.param.imu_type
)) ))
log.info("max_v:%d %d %d\r\n" \ log.info("max_v:%d %d %d\r\n" \
%(robotParam.param.max_v_liner_x,\ %(robotParam.param.max_v_liner_x,\
robotParam.param.max_v_liner_y, \ robotParam.param.max_v_liner_y, \
robotParam.param.max_v_angular_z robotParam.param.max_v_angular_z
)) ))
log.info("motor flag:%d encoder flag: %d\r\n" \ log.info("motor flag:%d encoder flag: %d\r\n" \
%(robotParam.param.motor_nonexchange_flag,\ %(robotParam.param.motor_nonexchange_flag,\
robotParam.param.encoder_nonexchange_flag robotParam.param.encoder_nonexchange_flag
)) ))
else: else:
log.error('get params err\r\n') log.error('get params err\r\n')
quit(1) quit(1)
log.info("****************get odom&imu*****************") log.info("****************get odom&imu*****************")
while run_flag: while run_flag:
robotOdom = DataHolder[MessageID.ID_GET_ODOM] robotOdom = DataHolder[MessageID.ID_GET_ODOM]
p = mboard.request(MessageID.ID_GET_ODOM) p = mboard.request(MessageID.ID_GET_ODOM)
if p: if p:
log.info('request get odom success, vx=%d vy=%d vangular=%d, x=%d y=%d yaw=%d'%(robotOdom.v_liner_x, \ log.info('request get odom success, vx=%d vy=%d vangular=%d, x=%d y=%d yaw=%d'%(robotOdom.v_liner_x, \
robotOdom.v_liner_y, \ robotOdom.v_liner_y, \
robotOdom.v_angular_z, \ robotOdom.v_angular_z, \
robotOdom.x, \ robotOdom.x, \
robotOdom.y, \ robotOdom.y, \
robotOdom.yaw)) robotOdom.yaw))
else: else:
log.error('get odom err') log.error('get odom err')
quit(1) quit(1)
robotIMU = DataHolder[MessageID.ID_GET_IMU].imu robotIMU = DataHolder[MessageID.ID_GET_IMU].imu
p = mboard.request(MessageID.ID_GET_IMU) p = mboard.request(MessageID.ID_GET_IMU)
if p: if p:
log.info('get imu success, imu=[%f %f %f %f %f %f %f %f %f]'%(robotIMU[0], robotIMU[1], robotIMU[2], \ log.info('get imu success, imu=[%f %f %f %f %f %f %f %f %f]'%(robotIMU[0], robotIMU[1], robotIMU[2], \
robotIMU[3], robotIMU[4], robotIMU[5], \ robotIMU[3], robotIMU[4], robotIMU[5], \
robotIMU[6], robotIMU[7], robotIMU[8])) robotIMU[6], robotIMU[7], robotIMU[8]))
else: else:
log.error('get imu err') log.error('get imu err')
quit(1) quit(1)
time.sleep(0.1) time.sleep(0.1)

View File

@ -1,75 +1,75 @@
import dataholder import dataholder
import os import os
from dataholder import RobotImuType from dataholder import RobotImuType
from dataholder import RobotModelType from dataholder import RobotModelType
pibotModel = os.environ['PIBOT_MODEL'] pibotModel = os.environ['PIBOT_MODEL']
boardType = os.environ['PIBOT_BOARD'] boardType = os.environ['PIBOT_BOARD']
pibotBaud = os.environ['PIBOT_DRIVER_BAUDRATE'] pibotBaud = os.environ['PIBOT_DRIVER_BAUDRATE']
print(pibotModel) print(pibotModel)
print(boardType) print(boardType)
print(pibotBaud) print(pibotBaud)
pibotParam = dataholder.RobotParameters() pibotParam = dataholder.RobotParameters()
if pibotModel == "apollo" and boardType == "arduino": if pibotModel == "apollo" and boardType == "arduino":
pibotParam = dataholder.RobotParameters(65, 175, 44, 10, \ pibotParam = dataholder.RobotParameters(65, 175, 44, 10, \
75, 2500, 0, 10, \ 75, 2500, 0, 10, \
250, 40, 0, 200, \ 250, 40, 0, 200, \
RobotImuType.IMU_TYPE_GY85, 90, \ RobotImuType.IMU_TYPE_GY85, 90, \
RobotModelType.MODEL_TYPE_2WD_DIFF) RobotModelType.MODEL_TYPE_2WD_DIFF)
elif pibotModel == "apollo" and boardType == "stm32f1": elif pibotModel == "apollo" and boardType == "stm32f1":
pibotParam = dataholder.RobotParameters(65, 175, 44, 10, \ pibotParam = dataholder.RobotParameters(65, 175, 44, 10, \
320, 2700, 0, 10, \ 320, 2700, 0, 10, \
250, 50, 0, 200, \ 250, 50, 0, 200, \
RobotImuType.IMU_TYPE_GY87, 90, \ RobotImuType.IMU_TYPE_GY87, 90, \
RobotModelType.MODEL_TYPE_2WD_DIFF) RobotModelType.MODEL_TYPE_2WD_DIFF)
elif pibotModel == "apollo" and boardType == "stm32f4": elif pibotModel == "apollo" and boardType == "stm32f4":
pibotParam = dataholder.RobotParameters(65, 175, 44, 10, \ pibotParam = dataholder.RobotParameters(65, 175, 44, 10, \
320, 2700, 0, 10, \ 320, 2700, 0, 10, \
250, 40, 0, 200, \ 250, 40, 0, 200, \
RobotImuType.IMU_TYPE_GY87, 90, \ RobotImuType.IMU_TYPE_GY87, 90, \
RobotModelType.MODEL_TYPE_2WD_DIFF) RobotModelType.MODEL_TYPE_2WD_DIFF)
elif pibotModel == "zeus" and boardType == "stm32f4": elif pibotModel == "zeus" and boardType == "stm32f4":
pibotParam = dataholder.RobotParameters(58, 230, 44, 10, \ pibotParam = dataholder.RobotParameters(58, 230, 44, 10, \
320, 2700, 0, 10, \ 320, 2700, 0, 10, \
250, 50, 50, 250, \ 250, 50, 50, 250, \
RobotImuType.IMU_TYPE_GY87, 90, \ RobotImuType.IMU_TYPE_GY87, 90, \
RobotModelType.MODEL_TYPE_3WD_OMNI) RobotModelType.MODEL_TYPE_3WD_OMNI)
elif pibotModel == "hades" and boardType == "stm32f4": elif pibotModel == "hades" and boardType == "stm32f4":
pibotParam = dataholder.RobotParameters(76, 470, 44, 10, \ pibotParam = dataholder.RobotParameters(76, 470, 44, 10, \
320, 2700, 0, 10, \ 320, 2700, 0, 10, \
250, 50, 50, 250, \ 250, 50, 50, 250, \
RobotImuType.IMU_TYPE_GY87, 90, \ RobotImuType.IMU_TYPE_GY87, 90, \
RobotModelType.MODEL_TYPE_4WD_MECANUM) RobotModelType.MODEL_TYPE_4WD_MECANUM)
elif pibotModel == "hadesX" and boardType == "stm32f4": elif pibotModel == "hadesX" and boardType == "stm32f4":
pibotParam = dataholder.RobotParameters(150, 565, 44, 10, \ pibotParam = dataholder.RobotParameters(150, 565, 44, 10, \
250, 2750, 0, 10, \ 250, 2750, 0, 10, \
250, 50, 50, 250, \ 250, 50, 50, 250, \
RobotImuType.IMU_TYPE_GY87, 72, \ RobotImuType.IMU_TYPE_GY87, 72, \
RobotModelType.MODEL_TYPE_4WD_MECANUM) RobotModelType.MODEL_TYPE_4WD_MECANUM)
elif pibotModel == "hera" and boardType == "stm32f4": elif pibotModel == "hera" and boardType == "stm32f4":
pibotParam = dataholder.RobotParameters(82, 338, 44, 10, \ pibotParam = dataholder.RobotParameters(82, 338, 44, 10, \
320, 2700, 0, 10, \ 320, 2700, 0, 10, \
250, 50, 50, 250, \ 250, 50, 50, 250, \
RobotImuType.IMU_TYPE_GY87, 90, \ RobotImuType.IMU_TYPE_GY87, 90, \
RobotModelType.MODEL_TYPE_4WD_DIFF) RobotModelType.MODEL_TYPE_4WD_DIFF)
elif pibotModel == "apolloX" and boardType == "arduino": elif pibotModel == "apolloX" and boardType == "arduino":
pibotParam = dataholder.RobotParameters(96, 350, 68, 10, \ pibotParam = dataholder.RobotParameters(96, 350, 68, 10, \
75, 2500, 0, 10, \ 75, 2500, 0, 10, \
250, 40, 0, 200, \ 250, 40, 0, 200, \
RobotImuType.IMU_TYPE_GY85, 90, \ RobotImuType.IMU_TYPE_GY85, 90, \
RobotModelType.MODEL_TYPE_2WD_DIFF) RobotModelType.MODEL_TYPE_2WD_DIFF)
elif pibotModel == "apolloX" and boardType == "stm32f1": elif pibotModel == "apolloX" and boardType == "stm32f1":
pibotParam = dataholder.RobotParameters(96, 350, 68, 10, \ pibotParam = dataholder.RobotParameters(96, 350, 68, 10, \
250, 1200, 0, 10, \ 250, 1200, 0, 10, \
250, 50, 0, 200, \ 250, 50, 0, 200, \
RobotImuType.IMU_TYPE_GY87, 90, \ RobotImuType.IMU_TYPE_GY87, 90, \
RobotModelType.MODEL_TYPE_2WD_DIFF) RobotModelType.MODEL_TYPE_2WD_DIFF)
elif pibotModel == "apolloX" and boardType == "stm32f4": elif pibotModel == "apolloX" and boardType == "stm32f4":
pibotParam = dataholder.RobotParameters(96, 350, 68, 10, \ pibotParam = dataholder.RobotParameters(96, 350, 68, 10, \
250, 1200, 0, 10, \ 250, 1200, 0, 10, \
250, 50, 0, 200, \ 250, 50, 0, 200, \
RobotImuType.IMU_TYPE_GY87, 90, \ RobotImuType.IMU_TYPE_GY87, 90, \
RobotModelType.MODEL_TYPE_2WD_DIFF) RobotModelType.MODEL_TYPE_2WD_DIFF)

View File

@ -1,90 +1,90 @@
import platform import platform
import sys import sys
sys.path.append("..") sys.path.append("..")
import pypibot import pypibot
from pypibot import log from pypibot import log
from transport import Transport from transport import Transport
from dataholder import MessageID from dataholder import MessageID
import params import params
#for linux #for linux
port="/dev/pibot" port="/dev/pibot"
#for windows #for windows
#port="com3" #port="com3"
pypibot.assistant.enableGlobalExcept() pypibot.assistant.enableGlobalExcept()
#log.enableFileLog(log_dir + "ros_$(Date8)_$(filenumber2).log") #log.enableFileLog(log_dir + "ros_$(Date8)_$(filenumber2).log")
log.setLevel("i") log.setLevel("i")
if __name__ == '__main__': if __name__ == '__main__':
mboard = Transport(port, params.pibotBaud) mboard = Transport(port, params.pibotBaud)
if not mboard.start(): if not mboard.start():
log.error("can not open %s"%port) log.error("can not open %s"%port)
sys.exit() sys.exit()
DataHolder = mboard.getDataHolder() DataHolder = mboard.getDataHolder()
for num in range(0,3): for num in range(0,3):
log.info("****************get robot version*****************") log.info("****************get robot version*****************")
boardVersion = DataHolder[MessageID.ID_GET_VERSION] boardVersion = DataHolder[MessageID.ID_GET_VERSION]
p = mboard.request(MessageID.ID_GET_VERSION) p = mboard.request(MessageID.ID_GET_VERSION)
if p: if p:
log.info("firmware version:%s buildtime:%s\r\n"%(boardVersion.version.decode(), boardVersion.build_time.decode())) log.info("firmware version:%s buildtime:%s\r\n"%(boardVersion.version.decode(), boardVersion.build_time.decode()))
break break
else: else:
log.error('read firmware version err\r\n') log.error('read firmware version err\r\n')
import time import time
time.sleep(1) time.sleep(1)
if num == 2: if num == 2:
log.error('please check connection or baudrate\r\n') log.error('please check connection or baudrate\r\n')
sys.exit() sys.exit()
# set robot parameter # set robot parameter
log.info("****************set robot parameter*****************") log.info("****************set robot parameter*****************")
DataHolder[MessageID.ID_SET_ROBOT_PARAMETER].param = params.pibotParam DataHolder[MessageID.ID_SET_ROBOT_PARAMETER].param = params.pibotParam
p = mboard.request(MessageID.ID_SET_ROBOT_PARAMETER) p = mboard.request(MessageID.ID_SET_ROBOT_PARAMETER)
if p: if p:
log.info('set parameter success') log.info('set parameter success')
else: else:
log.error('set parameter err') log.error('set parameter err')
quit(1) quit(1)
# get robot parameter # get robot parameter
robotParam = DataHolder[MessageID.ID_GET_ROBOT_PARAMETER] robotParam = DataHolder[MessageID.ID_GET_ROBOT_PARAMETER]
p = mboard.request(MessageID.ID_GET_ROBOT_PARAMETER) p = mboard.request(MessageID.ID_GET_ROBOT_PARAMETER)
if p: if p:
log.info("model_type:%d wheel_diameter:%d wheel_track:%d encoder_resolution:%d" \ log.info("model_type:%d wheel_diameter:%d wheel_track:%d encoder_resolution:%d" \
%(robotParam.param.model_type, \ %(robotParam.param.model_type, \
robotParam.param.wheel_diameter, \ robotParam.param.wheel_diameter, \
robotParam.param.wheel_track, \ robotParam.param.wheel_track, \
robotParam.param.encoder_resolution robotParam.param.encoder_resolution
)) ))
log.info("do_pid_interval:%d kp:%d ki:%d kd:%d ko:%d" \ log.info("do_pid_interval:%d kp:%d ki:%d kd:%d ko:%d" \
%(robotParam.param.do_pid_interval, \ %(robotParam.param.do_pid_interval, \
robotParam.param.kp, \ robotParam.param.kp, \
robotParam.param.ki, \ robotParam.param.ki, \
robotParam.param.kd, \ robotParam.param.kd, \
robotParam.param.ko)) robotParam.param.ko))
log.info("cmd_last_time:%d imu_type:%d" \ log.info("cmd_last_time:%d imu_type:%d" \
%(robotParam.param.cmd_last_time,\ %(robotParam.param.cmd_last_time,\
robotParam.param.imu_type robotParam.param.imu_type
)) ))
log.info("max_v:%d %d %d\r\n" \ log.info("max_v:%d %d %d\r\n" \
%(robotParam.param.max_v_liner_x,\ %(robotParam.param.max_v_liner_x,\
robotParam.param.max_v_liner_y, \ robotParam.param.max_v_liner_y, \
robotParam.param.max_v_angular_z robotParam.param.max_v_angular_z
)) ))
log.info("motor flag:%d encoder flag: %d\r\n" \ log.info("motor flag:%d encoder flag: %d\r\n" \
%(robotParam.param.motor_nonexchange_flag,\ %(robotParam.param.motor_nonexchange_flag,\
robotParam.param.encoder_nonexchange_flag robotParam.param.encoder_nonexchange_flag
)) ))
else: else:
log.error('get param err\r\n') log.error('get param err\r\n')
quit(1) quit(1)

View File

@ -1,122 +1,122 @@
import platform import platform
import sys import sys
sys.path.append("..") sys.path.append("..")
import pypibot import pypibot
from pypibot import log from pypibot import log
from transport import Transport from transport import Transport
from dataholder import MessageID from dataholder import MessageID
import params import params
import signal import signal
#for linux #for linux
port="/dev/pibot" port="/dev/pibot"
#for windows #for windows
#port="com3" #port="com3"
pypibot.assistant.enableGlobalExcept() pypibot.assistant.enableGlobalExcept()
#log.enableFileLog(log_dir + "ros_$(Date8)_$(filenumber2).log") #log.enableFileLog(log_dir + "ros_$(Date8)_$(filenumber2).log")
log.setLevel("i") log.setLevel("i")
run_flag = True run_flag = True
def exit(signum, frame): def exit(signum, frame):
global run_flag global run_flag
run_flag = False run_flag = False
if __name__ == '__main__': if __name__ == '__main__':
signal.signal(signal.SIGINT, exit) signal.signal(signal.SIGINT, exit)
mboard = Transport(port, params.pibotBaud) mboard = Transport(port, params.pibotBaud)
if not mboard.start(): if not mboard.start():
log.error("can not open %s"%port) log.error("can not open %s"%port)
sys.exit() sys.exit()
pwm=[0]*4 pwm=[0]*4
for i in range(len(sys.argv)-1): for i in range(len(sys.argv)-1):
pwm[i] = int(sys.argv[i+1]) pwm[i] = int(sys.argv[i+1])
DataHolder = mboard.getDataHolder() DataHolder = mboard.getDataHolder()
for num in range(0,3): for num in range(0,3):
log.info("****************get robot version*****************") log.info("****************get robot version*****************")
boardVersion = DataHolder[MessageID.ID_GET_VERSION] boardVersion = DataHolder[MessageID.ID_GET_VERSION]
p = mboard.request(MessageID.ID_GET_VERSION) p = mboard.request(MessageID.ID_GET_VERSION)
if p: if p:
log.info("firmware version:%s buildtime:%s\r\n"%(boardVersion.version.decode(), boardVersion.build_time.decode())) log.info("firmware version:%s buildtime:%s\r\n"%(boardVersion.version.decode(), boardVersion.build_time.decode()))
break break
else: else:
log.error('read firmware version err\r\n') log.error('read firmware version err\r\n')
import time import time
time.sleep(1) time.sleep(1)
if num == 2: if num == 2:
log.error('please check connection or baudrate\r\n') log.error('please check connection or baudrate\r\n')
sys.exit() sys.exit()
# get robot parameter # get robot parameter
robotParam = DataHolder[MessageID.ID_GET_ROBOT_PARAMETER] robotParam = DataHolder[MessageID.ID_GET_ROBOT_PARAMETER]
p = mboard.request(MessageID.ID_GET_ROBOT_PARAMETER) p = mboard.request(MessageID.ID_GET_ROBOT_PARAMETER)
if p: if p:
log.info("model_type:%d wheel_diameter:%d wheel_track:%d encoder_resolution:%d" \ log.info("model_type:%d wheel_diameter:%d wheel_track:%d encoder_resolution:%d" \
%(robotParam.param.model_type, \ %(robotParam.param.model_type, \
robotParam.param.wheel_diameter, \ robotParam.param.wheel_diameter, \
robotParam.param.wheel_track, \ robotParam.param.wheel_track, \
robotParam.param.encoder_resolution robotParam.param.encoder_resolution
)) ))
log.info("do_pid_interval:%d kp:%d ki:%d kd:%d ko:%d" \ log.info("do_pid_interval:%d kp:%d ki:%d kd:%d ko:%d" \
%(robotParam.param.do_pid_interval, \ %(robotParam.param.do_pid_interval, \
robotParam.param.kp, \ robotParam.param.kp, \
robotParam.param.ki, \ robotParam.param.ki, \
robotParam.param.kd, \ robotParam.param.kd, \
robotParam.param.ko)) robotParam.param.ko))
log.info("cmd_last_time:%d imu_type:%d" \ log.info("cmd_last_time:%d imu_type:%d" \
%(robotParam.param.cmd_last_time,\ %(robotParam.param.cmd_last_time,\
robotParam.param.imu_type robotParam.param.imu_type
)) ))
log.info("max_v:%d %d %d\r\n" \ log.info("max_v:%d %d %d\r\n" \
%(robotParam.param.max_v_liner_x,\ %(robotParam.param.max_v_liner_x,\
robotParam.param.max_v_liner_y, \ robotParam.param.max_v_liner_y, \
robotParam.param.max_v_angular_z robotParam.param.max_v_angular_z
)) ))
log.info("motor flag:%d encoder flag: %d\r\n" \ log.info("motor flag:%d encoder flag: %d\r\n" \
%(robotParam.param.motor_nonexchange_flag,\ %(robotParam.param.motor_nonexchange_flag,\
robotParam.param.encoder_nonexchange_flag robotParam.param.encoder_nonexchange_flag
)) ))
else: else:
log.error('get params err\r\n') log.error('get params err\r\n')
quit(1) quit(1)
DataHolder[MessageID.ID_SET_MOTOR_PWM].pwm = pwm DataHolder[MessageID.ID_SET_MOTOR_PWM].pwm = pwm
p = mboard.request(MessageID.ID_SET_MOTOR_PWM) p = mboard.request(MessageID.ID_SET_MOTOR_PWM)
if p: if p:
log.info('set pwm success') log.info('set pwm success')
else: else:
log.error('set pwm err') log.error('set pwm err')
quit(1) quit(1)
log.info("****************get encoder count*****************") log.info("****************get encoder count*****************")
while run_flag: while run_flag:
robotEncoder = DataHolder[MessageID.ID_GET_ENCODER_COUNT].encoder robotEncoder = DataHolder[MessageID.ID_GET_ENCODER_COUNT].encoder
p = mboard.request(MessageID.ID_GET_ENCODER_COUNT) p = mboard.request(MessageID.ID_GET_ENCODER_COUNT)
if p: if p:
log.info('encoder count: %s'%(('\t\t').join([str(x) for x in robotEncoder]))) log.info('encoder count: %s'%(('\t\t').join([str(x) for x in robotEncoder])))
else: else:
log.error('get encoder count err') log.error('get encoder count err')
quit(1) quit(1)
import time import time
time.sleep(0.5) time.sleep(0.5)
DataHolder[MessageID.ID_SET_MOTOR_PWM].pwm = [0]*4 DataHolder[MessageID.ID_SET_MOTOR_PWM].pwm = [0]*4
p = mboard.request(MessageID.ID_SET_MOTOR_PWM) p = mboard.request(MessageID.ID_SET_MOTOR_PWM)
if p: if p:
log.info('set pwm success') log.info('set pwm success')
else: else:
log.error('set pwm err') log.error('set pwm err')
quit(1) quit(1)

View File

@ -1,197 +1,197 @@
import sys import sys
sys.path.append("..") sys.path.append("..")
import pypibot import pypibot
from pypibot import log from pypibot import log
from pypibot import assistant from pypibot import assistant
import serial import serial
import threading import threading
import struct import struct
import time import time
from dataholder import MessageID, BoardDataDict from dataholder import MessageID, BoardDataDict
FIX_HEAD = 0x5a FIX_HEAD = 0x5a
class Recstate(): class Recstate():
WAITING_HD = 0 WAITING_HD = 0
WAITING_MSG_ID = 1 WAITING_MSG_ID = 1
RECEIVE_LEN = 2 RECEIVE_LEN = 2
RECEIVE_PACKAGE = 3 RECEIVE_PACKAGE = 3
RECEIVE_CHECK = 4 RECEIVE_CHECK = 4
def checksum(d): def checksum(d):
sum = 0 sum = 0
if assistant.is_python3(): if assistant.is_python3():
for i in d: for i in d:
sum += i sum += i
sum = sum&0xff sum = sum&0xff
else: else:
for i in d: for i in d:
sum += ord(i) sum += ord(i)
sum = sum&0xff sum = sum&0xff
return sum return sum
class Transport: class Transport:
def __init__(self, port, baudrate=921600): def __init__(self, port, baudrate=921600):
self._Port = port self._Port = port
self._Baudrate = baudrate self._Baudrate = baudrate
self._KeepRunning = False self._KeepRunning = False
self.receive_state = Recstate.WAITING_HD self.receive_state = Recstate.WAITING_HD
self.rev_msg = [] self.rev_msg = []
self.rev_data = [] self.rev_data = []
self.wait_event = threading.Event() self.wait_event = threading.Event()
def getDataHolder(self): def getDataHolder(self):
return BoardDataDict return BoardDataDict
def start(self): def start(self):
try: try:
self._Serial = serial.Serial(port=self._Port, baudrate=self._Baudrate, timeout=0.2) self._Serial = serial.Serial(port=self._Port, baudrate=self._Baudrate, timeout=0.2)
self._KeepRunning = True self._KeepRunning = True
self._ReceiverThread = threading.Thread(target=self._Listen) self._ReceiverThread = threading.Thread(target=self._Listen)
self._ReceiverThread.setDaemon(True) self._ReceiverThread.setDaemon(True)
self._ReceiverThread.start() self._ReceiverThread.start()
return True return True
except: except:
return False return False
def Stop(self): def Stop(self):
self._KeepRunning = False self._KeepRunning = False
time.sleep(0.1) time.sleep(0.1)
self._Serial.close() self._Serial.close()
def _Listen(self): def _Listen(self):
while self._KeepRunning: while self._KeepRunning:
if self.receiveFiniteStates(self._Serial.read()): if self.receiveFiniteStates(self._Serial.read()):
self.packageAnalysis() self.packageAnalysis()
def receiveFiniteStates(self, s): def receiveFiniteStates(self, s):
if len(s) == 0: if len(s) == 0:
return False return False
val = s[0] val = s[0]
val_int = val val_int = val
if not assistant.is_python3(): if not assistant.is_python3():
val_int = ord(val) val_int = ord(val)
if self.receive_state == Recstate.WAITING_HD: if self.receive_state == Recstate.WAITING_HD:
if val_int == FIX_HEAD: if val_int == FIX_HEAD:
log.trace('got head') log.trace('got head')
self.rev_msg = [] self.rev_msg = []
self.rev_data =[] self.rev_data =[]
self.rev_msg.append(val) self.rev_msg.append(val)
self.receive_state = Recstate.WAITING_MSG_ID self.receive_state = Recstate.WAITING_MSG_ID
elif self.receive_state == Recstate.WAITING_MSG_ID: elif self.receive_state == Recstate.WAITING_MSG_ID:
log.trace('got msg id') log.trace('got msg id')
self.rev_msg.append(val) self.rev_msg.append(val)
self.receive_state = Recstate.RECEIVE_LEN self.receive_state = Recstate.RECEIVE_LEN
elif self.receive_state == Recstate.RECEIVE_LEN: elif self.receive_state == Recstate.RECEIVE_LEN:
log.trace('got len:%d', val_int) log.trace('got len:%d', val_int)
self.rev_msg.append(val) self.rev_msg.append(val)
if val_int == 0: if val_int == 0:
self.receive_state = Recstate.RECEIVE_CHECK self.receive_state = Recstate.RECEIVE_CHECK
else: else:
self.receive_state = Recstate.RECEIVE_PACKAGE self.receive_state = Recstate.RECEIVE_PACKAGE
elif self.receive_state == Recstate.RECEIVE_PACKAGE: elif self.receive_state == Recstate.RECEIVE_PACKAGE:
# if assistant.is_python3(): # if assistant.is_python3():
# self.rev_data.append((chr(val)).encode('latin1')) # self.rev_data.append((chr(val)).encode('latin1'))
# else: # else:
self.rev_data.append(val) self.rev_data.append(val)
r = False r = False
if assistant.is_python3(): if assistant.is_python3():
r = len(self.rev_data) == int(self.rev_msg[-1]) r = len(self.rev_data) == int(self.rev_msg[-1])
else: else:
r = len(self.rev_data) == ord(self.rev_msg[-1]) r = len(self.rev_data) == ord(self.rev_msg[-1])
if r: if r:
self.rev_msg.extend(self.rev_data) self.rev_msg.extend(self.rev_data)
self.receive_state = Recstate.RECEIVE_CHECK self.receive_state = Recstate.RECEIVE_CHECK
elif self.receive_state == Recstate.RECEIVE_CHECK: elif self.receive_state == Recstate.RECEIVE_CHECK:
log.trace('got check') log.trace('got check')
self.receive_state = Recstate.WAITING_HD self.receive_state = Recstate.WAITING_HD
if val_int == checksum(self.rev_msg): if val_int == checksum(self.rev_msg):
log.trace('got a complete message') log.trace('got a complete message')
return True return True
else: else:
self.receive_state = Recstate.WAITING_HD self.receive_state = Recstate.WAITING_HD
# continue receiving # continue receiving
return False return False
def packageAnalysis(self): def packageAnalysis(self):
if assistant.is_python3(): if assistant.is_python3():
in_msg_id = int(self.rev_msg[1]) in_msg_id = int(self.rev_msg[1])
else: else:
in_msg_id = ord(self.rev_msg[1]) in_msg_id = ord(self.rev_msg[1])
if assistant.is_python3(): if assistant.is_python3():
log.debug("recv body:" + " ".join("{:02x}".format(c) for c in self.rev_data)) log.debug("recv body:" + " ".join("{:02x}".format(c) for c in self.rev_data))
r = BoardDataDict[in_msg_id].unpack(bytes(self.rev_data)) r = BoardDataDict[in_msg_id].unpack(bytes(self.rev_data))
else: else:
log.debug("recv body:" + " ".join("{:02x}".format(ord(c)) for c in self.rev_data)) log.debug("recv body:" + " ".join("{:02x}".format(ord(c)) for c in self.rev_data))
r = BoardDataDict[in_msg_id].unpack(''.join(self.rev_data)) r = BoardDataDict[in_msg_id].unpack(''.join(self.rev_data))
if r: if r:
self.res_id = in_msg_id self.res_id = in_msg_id
if in_msg_id<100: if in_msg_id<100:
self.set_response() self.set_response()
else:#notify else:#notify
log.debug('msg %d'%self.rev_msg[4],'data incoming') log.debug('msg %d'%self.rev_msg[4],'data incoming')
pass pass
else: else:
log.debug ('error unpacking pkg') log.debug ('error unpacking pkg')
def request(self, id, timeout=0.5): def request(self, id, timeout=0.5):
if not self.write(id): if not self.write(id):
log.debug ('Serial send error!') log.debug ('Serial send error!')
return False return False
if self.wait_for_response(timeout): if self.wait_for_response(timeout):
if id == self.res_id: if id == self.res_id:
log.trace ('OK') log.trace ('OK')
else: else:
log.error ('Got unmatched response!') log.error ('Got unmatched response!')
else: else:
log.error ('Request got no response!') log.error ('Request got no response!')
return False return False
# clear response # clear response
self.res_id = None self.res_id = None
return True return True
def write(self, id): def write(self, id):
cmd = self.make_command(id) cmd = self.make_command(id)
if assistant.is_python3(): if assistant.is_python3():
log.d("write:" + " ".join("{:02x}".format(c) for c in cmd)) log.d("write:" + " ".join("{:02x}".format(c) for c in cmd))
else: else:
log.d("write:" + " ".join("{:02x}".format(ord(c)) for c in cmd)) log.d("write:" + " ".join("{:02x}".format(ord(c)) for c in cmd))
self._Serial.write(cmd) self._Serial.write(cmd)
return True return True
def wait_for_response(self, timeout): def wait_for_response(self, timeout):
self.wait_event.clear() self.wait_event.clear()
return self.wait_event.wait(timeout) return self.wait_event.wait(timeout)
def set_response(self): def set_response(self):
self.wait_event.set() self.wait_event.set()
def make_command(self, id): def make_command(self, id):
#print(DataDict[id]) #print(DataDict[id])
data = BoardDataDict[id].pack() data = BoardDataDict[id].pack()
l = [FIX_HEAD, id, len(data)] l = [FIX_HEAD, id, len(data)]
head = struct.pack("3B", *l) head = struct.pack("3B", *l)
body = head + data body = head + data
if assistant.is_python3(): if assistant.is_python3():
return body + chr(checksum(body)).encode('latin1') return body + chr(checksum(body)).encode('latin1')
else: else:
return body + chr(checksum(body)) return body + chr(checksum(body))
if __name__ == '__main__': if __name__ == '__main__':
mboard = Transport('com10') mboard = Transport('com10')
if not mboard.start(): if not mboard.start():
import sys import sys
sys.exit() sys.exit()
p = mboard.request(MessageID.ID_GET_VERSION) p = mboard.request(MessageID.ID_GET_VERSION)
log.i("result=%s"%p) log.i("result=%s"%p)
print('Version =[',mboard.getDataHolder()[MessageID.ID_GET_VERSION].version.decode(), mboard.getDataHolder()[MessageID.ID_GET_VERSION].build_time.decode(),"]\r\n") print('Version =[',mboard.getDataHolder()[MessageID.ID_GET_VERSION].version.decode(), mboard.getDataHolder()[MessageID.ID_GET_VERSION].build_time.decode(),"]\r\n")

View File

@ -0,0 +1,60 @@
cmake_minimum_required(VERSION 3.0.2)
project(FollowingCar)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
geometry_msgs
)
# OpenCV
find_package(OpenCV REQUIRED)
# Boost
find_package(Boost REQUIRED)
# catkin_package(
# # INCLUDE_DIRS include
# # LIBRARIES FollowingCar
# # CATKIN_DEPENDS roscpp rospy std_msgs
# # DEPENDS system_lib
# CATKIN_DEPENDS message_runtime std_msgs geometry_msgs
# )
include_directories(
# include
${OpenCV_INCLUDE_DIRS}
${catkin_INCLUDE_DIRS}
include
)
add_library(${PROJECT_NAME} SHARED
src/system.cpp
src/uwb.cpp
src/mapping.cpp
src/align.cpp
src/Mat.cpp
src/lighthouse.cpp
# src/read_sensor_data.cpp
include/senddata.h src/senddata.cpp)
add_message_files(
DIRECTORY msg
FILES
RawImu.msg
dis_info_array.msg
dis_info.msg
)
generate_messages(DEPENDENCIES std_msgs geometry_msgs)
catkin_package(CATKIN_DEPENDS message_runtime std_msgs geometry_msgs)
add_executable(${PROJECT_NAME}_node src/main.cpp)
target_link_libraries(${PROJECT_NAME}_node ${catkin_LIBRARIES} ${OpenCV_LIBS} ${Boost_LIBRARIES} pthread ${PROJECT_NAME})

View File

@ -0,0 +1,83 @@
/******************** (C) COPYRIGHT 2022 Geek************************************
* File Name : Mat.h
* Current Version : V1.0
* Author : logzhan
* Date of Issued : 2022.09.14
* Comments : <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
********************************************************************************/
/* Header File Including -----------------------------------------------------*/
#ifndef _H_MAT_
#define _H_MAT_
#define MAT_MAX 15 //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܴ<EFBFBD><DCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include <string.h>
#define _USE_MATH_DEFINES
#include <math.h>
class Mat
{
public:
Mat();
Mat(int setm,int setn,int kind);//kind=1<><31>λ<EFBFBD><CEBB>kind=0<><30><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD>
void Init(int setm,int setn,int kind);//kind=1<><31>λ<EFBFBD><CEBB>kind=0<><30><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD>
void Zero(void);
//<2F><>Щ<EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>Ϊprivate<74>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>˷<EFBFBD><CBB7><EFBFBD><E3A3AC>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>public
int m;//<2F><><EFBFBD><EFBFBD>
int n;//<2F><><EFBFBD><EFBFBD>
double mat[MAT_MAX][MAT_MAX];//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>ľ<EFBFBD><C4BE><EFBFBD>
Mat SubMat(int a,int b,int lm,int ln);//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
void FillSubMat(int a,int b,Mat s);//<2F><><EFBFBD><EFBFBD>Ӿ<EFBFBD><D3BE><EFBFBD>
//<2F><><EFBFBD><EFBFBD>ר<EFBFBD><D7A8>
double absvec();//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><C4B3>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD>Ԫ<EFBFBD>صľ<D8B5><C4BE><EFBFBD>ֵ<EFBFBD><D6B5>
double Sqrt();//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD>ƽ<EFBFBD><C6BD>
friend Mat operator ^(Mat a,Mat b);//<2F><><EFBFBD>
//<2F><><EFBFBD><EFBFBD>
friend Mat operator *(double k,Mat a);
friend Mat operator *(Mat a,double k);
friend Mat operator /(Mat a,double k);
friend Mat operator *(Mat a,Mat b);
friend Mat operator +(Mat a,Mat b);
friend Mat operator -(Mat a,Mat b);
friend Mat operator ~(Mat a);//ת<><D7AA>
friend Mat operator /(Mat a,Mat b);//a*inv(b)
friend Mat operator %(Mat a,Mat b);//inv(a)*b
//MAT inv();//<2F><><EFBFBD><EFBFBD><EFBFBD>
private:
// Ϊ<><CEAA><EFBFBD>ø<EFBFBD>˹<EFBFBD><CBB9>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һЩ<D2BB><D0A9><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void RowExchange(int a, int b);
// ijһ<C4B3>г<EFBFBD><D0B3><EFBFBD>ϵ<EFBFBD><CFB5>
void RowMul(int a,double k);
// <20><>ijһ<C4B3>мӼ<D0BC><D3BC><EFBFBD>һ<EFBFBD>еı<D0B5><C4B1><EFBFBD>
void RowAdd(int a,int b, double k);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ColExchange(int a, int b);
// ijһ<C4B3>г<EFBFBD><D0B3><EFBFBD>ϵ<EFBFBD><CFB5>
void ColMul(int a,double k);
// <20><>ijһ<C4B3>мӼ<D0BC><D3BC><EFBFBD>һ<EFBFBD>еı<D0B5><C4B1><EFBFBD>
void ColAdd(int a,int b,double k);
};
#endif

View File

@ -1,41 +1,44 @@
#include <cmath> #include <cmath>
#include <ros/ros.h> #include <ros/ros.h>
#include <nav_msgs/Odometry.h> #include <opencv2/opencv.hpp>
#include <utility> #include <nav_msgs/Odometry.h>
#include <queue> #include <utility>
#include <fstream> #include <queue>
#include "ros_merge_test/RawImu.h" #include <fstream>
#include "type.h" #include "FollowingCar/RawImu.h"
#include "uwb.h" #include "type.h"
#include <opencv2/opencv.hpp> #include "uwb.h"
#include "lighthouse.h"
#ifndef ALIGN_H #include "Mat.h"
#define AlIGN_H
namespace uwb_slam{ #ifndef ALIGN_H
class Align #define AlIGN_H
{ namespace uwb_slam{
public: class Align
Align(){}; {
void Run(); public:
void wheel_odomCB(const nav_msgs::Odometry& wheel_odom); Align(){
void imuCB(const ros_merge_test::RawImu& imu);
void odomCB(const nav_msgs::Odometry& odom); };
void Run();
public: void wheel_odomCB(const nav_msgs::Odometry& wheel_odom);
ros::NodeHandle nh_; void imuCB(const FollowingCar::RawImu& imu);
ros::Subscriber wheel_odom_sub_; void odomCB(const nav_msgs::Odometry& odom);
ros::Subscriber imu_sub_;
ros::Subscriber odom_sub_; public:
ros::NodeHandle nh_;
Imu_odom_pose_data imu_odom_; ros::Subscriber wheel_odom_sub_;
Uwb_data uwb_data_; ros::Subscriber imu_sub_;
ros::Time tmp ; ros::Subscriber odom_sub_;
Imu_odom_pose_data imu_odom_;
ros::Time odom_tmp_ ; Uwb_data uwb_data_;
bool write_data_ = false; ros::Time imuDataRxTime, uwbDataRxTime, odomDataRxTime;
cv::Mat img1; ros::Time odom_tmp_ ;
std::queue<std::pair<Imu_odom_pose_data,Uwb_data>> data_queue; bool write_data_ = false;
std::shared_ptr<uwb_slam::Uwb> uwb_; cv::Mat img1;
}; std::queue<std::pair<Imu_odom_pose_data,Uwb_data>> data_queue;
}; std::shared_ptr<uwb_slam::Uwb> uwb_;
#endif std::shared_ptr<uwb_slam::Lighthouse> lighthouse_;
};
};
#endif

View File

@ -0,0 +1,29 @@
#include <ros/ros.h>
#include <mutex>
#include <boost/asio.hpp>
#include <iostream>
#include <string>
#include <cstdint>
#include "type.h"
#include <queue>
#include <chrono>
#ifndef __LIGHTHOUSE_H__
#define __LIGHTHOUSE_H__
namespace uwb_slam{
class Lighthouse{
public:
Lighthouse();
~Lighthouse();
void Run();
void UDPRead();
// Listen PORT
int PORT = 12345;
int UdpSocket = -1;
LightHouseData data;
std::mutex mMutexLighthouse;
};
};
#endif

Some files were not shown because too many files have changed in this diff Show More