作者归档: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运行成功

 

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盘,再重启。