作者归档:Daniel Sun

使用Clion在Ubuntu 16上使用OpenMP编写C

首先,安装OpenMP

sudo apt-get install libomp-dev

然后,编辑Clion生成的CMakeLists.txt,在任意set后面加上下面的代码

find_package(OpenMP)
if (OPENMP_FOUND)
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()

下面是一个完整的例子

cmake_minimum_required(VERSION 3.13)
project(test C)

set(CMAKE_C_STANDARD 99)
find_package(OpenMP)
if (OPENMP_FOUND)
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()
add_executable(test main.c)

然后,我们编写一个测试程序

#include <stdio.h>
int main(){
#pragma omp parallel for
    for(int i=0;i<10;i++){
        printf("%i\n",i);
    }
    return 0;
}

运行后,应该可以看到乱序输出的数字,代表OpenMP运行成功

 

Turtlebot plays Robotic Cluedo Demo

Project Description

You are asked to implement a program that plays Robotic Cluedo! Robotic Cluedo is slightly different than the board game Cluedo. In our version, your robot needs to visit a room in an arena and identify the character and weapon in the room along with their location.

Project Demo

University of Leeds

Orestis Pourgourides, Chengke Sun, Antonis Simonis, Nikolay Kyorov

项目描述

机器人访问一个已知地图的房间,在该房间内寻找和识别数张不同的海报。

项目演示

(墙内观看)https://www.bilibili.com/video/av41989932/

ROS激光传感器可视化

问题描述

实验平台:TIAGo

编程语言:Python

TIAGo所使用的激光传感器在移动基座的底部,具体的描述信息如下

Laser range-finder

Located at the front of the base. This sensor measures distances in a horizontal plane. It is a valuable asset for navigation and mapping. Bad measurements can be caused by reflective or transparent surfaces.

为了获取激光数据,我们必须订阅/scan 消息,消息返回的类型为sensor_msgs/LaserScan ,该类型的文档可以访问http://docs.ros.org/indigo/api/sensor_msgs/html/msg/LaserScan.html查看,这里为了方便,我直接摘抄这个结构体的描述文档到了下面

std_msgs/Header header
float32 angle_min
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities

其中ranges是一个浮点数组,每个数组成员代表着激光传感器返回的距离,这个距离有可能是inf,因为激光传感器可能会因为没有探测到物体而返回无限远。这个我们需要在后面留意一下。intensities也是一个浮点数组,用来保存对应ranges上的强度。

所有代码如下:

#!/usr/bin/env python

import cv2
import numpy as np
import time
import rospy
from sensor_msgs.msg import LaserScan
import os

def scan_callback(data):
    distances = data.ranges
    angle_min = data.angle_min
    angle_increment = data.angle_increment

    pixels_relative_center = []
    for index in range(len(distances)):
        distance = distances[index]
        if distance == float('inf'):
            continue
        angle = angle_min + angle_increment * index
        x = np.cos(angle) * distance
        y = np.sin(angle) * distance

        pixel_x = int(round(x * 30))
        pixel_y = int(round(y * 30))
        pixels_relative_center.append((pixel_x, pixel_y))

    pixels_relative_center = list(set(pixels_relative_center))

    # create rgb image
    rgb_image = np.zeros((801, 801, 3), np.uint8)
    rgb_image.fill(255)

    pixels_relative_origin = []
    for (pixel_x, pixel_y) in pixels_relative_center:
        col = 400 + pixel_x
        row = 400 - pixel_y
        pixels_relative_origin.append((row, col))

    # draw the point
    for (row, col) in pixels_relative_origin:
        cv2.circle(rgb_image, (col, row), 2, (0, 0, 0), -1)

    # draw the point of robot
    cv2.circle(rgb_image, (400, 400), 4, (0, 255, 0), -1)

    cv2.imshow("rgb", rgb_image)
    cv2.waitKey(30)


def shutdown():
    cv2.destroyAllWindows()
    # noinspection PyProtectedMember
    os._exit(0)


rospy.on_shutdown(shutdown)
rospy.init_node('laser_image', anonymous=True)
rospy.Subscriber("/scan", LaserScan, scan_callback, queue_size=5)
while True:
    time.sleep(1)

可以持续移动机器人,将会发现数据图随着机器人的变化而变化。

代码讲解

使用循环,每次步进angle_increment 的角度,然后使用了三角函数公式来计算出激光数据点相对于机器人中心点(准确说应该是/base_laser_link,但是这里为了简便就说是中心点了)的坐标x和y。

x = np.cos(angle) * distance
y = np.sin(angle) * distance

为了能够将x,y坐标转换为像素的个数(方便显示),我将他们整体扩大了30倍。实际情况中如果有map,应该结合map的分辨率来计算这个值

pixel_x = int(round(x * 30))
pixel_y = int(round(y * 30))

然后,我们新建了一个801×801的空白画布。这个画布大小是我自己定义的,足够容纳我实验环境下激光传感器返回的所有点。pixels_relative_center 数组保存的是相对于机器人中心点,激光数据点的像素坐标。在后面的循环中,我们将这些数据点转换为相对于画布原点的像素坐标,并将他们放在pixels_relative_origin 数组中。这里需要注意的是,opencv画布坐标轴的位置和方向是不一样的。400就是我们的画布中心点,所以转换方式如下

col = 400 + pixel_x
row = 400 - pixel_y

最后,我们将这些点画出来即可

cv2.circle(rgb_image, (col, row), 2, (0, 0, 0), -1)

 

更改MySQL的数据存储(datadir)目录

步骤很简单,在开始之前,不要忘了先停止mysql服务。

service mysql stop

 

然后,拷贝之前旧的数据文件夹到新的位置

cp -rp /data/lib/mysql /mnt

上面的命令会把/data/lib/mysql这个文件夹的所有内容(包括权限),拷贝到/mnt/mysql

 

然后,修改/etc/mysql/my.cnf ,如果是Ubuntu使用mysql的apt源安装的,应该修改/etc/mysql/mysql.conf.d/mysqld.cnf

把datadir改成你需要的位置

 

下一步我们一般不会注意到,但是如果我们不修改这步,会造成mysql无法启动

编辑/etc/apparmor.d/usr.sbin.mysqld ,找到# Allow data dir access ,把他下面的旧数据目录替换成你的新的

然后,执行下面的命令即可

/etc/init.d/apparmor restart
service mysql start

 

参考:http://www.jianshu.com/p/5fb55e313f8c

在openwrt中,使用mwan3等工具来创建虚拟wan口实现带宽叠加

首先安装我们要用的环境

opkg update
opkg install kmod-macvlan luci-app-mwan3

 

然后,我们在/etc/rc.local 添加如下的脚本用来生成虚拟WAN口,这里我生成了4个。注意,每一个虚拟WAN口要使用不同的名字。如果你不想给你的虚拟WAN口指定一个MAC地址,可以去掉所有的ifconfig vth1 hw ether 这一行,这样每次这个脚本运行的时候,都会生成一个新的MAC地址。

ip link add link eth0.2 name vth1 type macvlan
ifconfig vth1 hw ether 3A:33:35:52:22:3D
ifconfig vth1 up

ip link add link eth0.2 name vth2 type macvlan
ifconfig vth2 hw ether B2:7F:8A:45:ED:9E
ifconfig vth2 up

ip link add link eth0.2 name vth3 type macvlan
ifconfig vth3 hw ether EE:56:25:F1:8D:9F
ifconfig vth3 up

ip link add link eth0.2 name vth4 type macvlan
ifconfig vth4 hw ether FA:CD:E3:FC:F0:21
ifconfig vth4 up

 

然后到网络->接口中为你刚才添加vth1-4添加接口。名字我们命名为wan1-4,这样可以对应。因为我这里是自动获取IP上网,所以协议选择是DHCP,可以根据你的需要进行变化。注意,每一个接口需要有不同的网络跃点。为了让网关认为我们是不同的电脑,也可以定义一个主机名。接口要选择正确。别忘了添加进防火墙

 

然后,我们到mwan3的设置页面。删除里面原先所有的接口。然后对应好我们之前创建好的wan1-4,在这里创建mwan的接口。Tracking IP要填写一个永远能访问的,比如8.8.8.8。

 

 

 

然后,到members里,删除里面所有的内容,对应我们之前创建的wan1-4,创建对应的member。接口要选对

 

 

然后我们转到policies,清空里面所有的内容,创建一个名字为balanced的策略。选择上我们所有的members

 

 

 

最后,我们可以返回总览,看一下是否出现了4个绿色wan。出现则代表正常

如何挂载U盘到openwrt并扩容根分区

先安装必要环境

opkg update
opkg install block-mount kmod-fs-ext4 kmod-usb-ohci kmod-usb2 kmod-usb-storage e2fsprogs blkid

然后在dev中找到你的U盘(一般是sdax,这里假设为sda1)

格式化U盘

mkfs.ext4 /dev/sda1

 

由于我们要挂载到/,所以我们先要拷贝原来的文件到U盘中,执行下面的命令

mkdir -p /tmp/introot
mkdir -p /tmp/extroot
mount --bind / /tmp/introot
mount /dev/sda1 /tmp/extroot
tar -C /tmp/introot -cvf - . | tar -C /tmp/extroot -xf -
umount /tmp/introot
umount /tmp/extroot

 

然后,使用blkid 命令来查看sda1的UUID,显示结果类似于下面

/dev/mtdblock5: TYPE="squashfs"
/dev/sda1: UUID="c91d06ce-8781-4255-b635-610bd6beef7e" TYPE="ext4"

 

然后,把下面的UUID替换成你的,把这段文本拷贝到/etc/config/fstab 文件的后面

config 'mount'  
        option  target  '/'  
        option  uuid    'c91d06ce-8781-4255-b635-610bd6beef7e'  
        option  enabled '1'

现在,重启路由器。使用df -h 来查看是否挂载成功。如果重启失败,可以尝试取下U盘,再重启。