国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

RT-Thread+STM32實(shí)現(xiàn)智能車目標(biāo)識(shí)別系統(tǒng)的教程

發(fā)布時(shí)間:2020-5-20 16:56    發(fā)布者:嵌入式人生17

引言
這篇文檔主要介紹 RT-Thread 如何使用串口或者無(wú)線和 ROS 連接,會(huì)包含這么些內(nèi)容:
第一部分:ROS 環(huán)境搭建
第二部分:RT-Thread rosserial 軟件包
第二部分:RT-Thread 添加 USART2 和 PWM
第三部分:RT-Thread 使用 ESP8266 AT 固件聯(lián)網(wǎng)
這里先介紹一下什么是 ROS?為什么要和 ROS 連接?
機(jī)器人操作系統(tǒng) ROS (Robots Operating System) 最早是斯坦福大學(xué)的一個(gè)軟件框架,現(xiàn)在不管是工業(yè)機(jī)器人,還是娛樂(lè)用的機(jī)器人都運(yùn)行著 ROS。
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml16216\wps9.png
一個(gè)機(jī)器人通常有很多個(gè)部件、傳感器,為了保證機(jī)器人不會(huì)因?yàn)槟骋粋(gè)傳感器故障,導(dǎo)致整個(gè)系統(tǒng)癱瘓,所以采用了分布式的節(jié)點(diǎn),利用不同節(jié)點(diǎn)之間的通訊收集傳感器數(shù)據(jù)和控制指令,這篇文檔后面會(huì)使用到的通訊協(xié)議就是 rosserial。和 ROS 連接的好處在于,一方面由 ROS 管理各個(gè)機(jī)器人節(jié)點(diǎn)更穩(wěn)定,另一方面 ROS 現(xiàn)在已經(jīng)有了非常多成熟的軟件包,使用 ROS 就可以非常方便的為自己的機(jī)器人添加攝像頭圖像識(shí)別、激光雷達(dá)建圖導(dǎo)航等高級(jí)功能。不過(guò)這篇文檔只會(huì)涉及 RT-Thread 和 ROS 建立基本的連接,實(shí)現(xiàn)小車的運(yùn)動(dòng)控制,之后可能會(huì)有后續(xù)文檔介紹如何連接激光雷達(dá)建圖,并進(jìn)行全局路徑規(guī)劃。
這篇文章假定大家都已經(jīng)會(huì)用 RT-Thread 的 env 工具下載軟件包,生成項(xiàng)目上傳固件到 stm32 上,并且熟悉 Ubuntu 的基本使用。
1 ROS 簡(jiǎn)介
這里的開發(fā)環(huán)境搭建其實(shí)是需要搭建 2 份,一份是小車上的 ARM 開發(fā)板 (樹莓派,NanoPi 什么的),另一個(gè)則是自己的電腦,因?yàn)槲覀兿M央娔X作為 ROS 從節(jié)點(diǎn),連接到小車上的 ROS 主節(jié)點(diǎn),不過(guò)開發(fā)板和電腦的 ROS 安裝是一模一樣的。
既然要和 ROS 連接,那么首先就得要有一個(gè)正常運(yùn)行的 ROS。安裝 ROS 其實(shí)非常簡(jiǎn)單,這里推薦使用 Ubuntu 18 (開發(fā)板推薦系統(tǒng)用 Armbian),因?yàn)楣俜綄?duì) Ubuntu 的支持優(yōu)先級(jí)是最高的,安裝教程也可以參照 官網(wǎng):http://wiki.ros.org/melodic/Installation/Ubuntu只需要輸入下面的 4 行命令,就在 Ubuntu 上裝好了 ROS。
1sudo sh -c 'echo "deb https://mirror.tuna.tsinghua.edu.cn/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
2sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
3sudo apt update
4sudo apt install ros-melodic-ros-base
上面我使用了清華大學(xué)的鏡像源,這樣從國(guó)內(nèi)下載 ROS 會(huì)快很多,而且我只安裝了 ROS 的基本軟件包,沒(méi)有安裝圖形化軟件包 gviz,gazebo 什么的,因?yàn)楹竺嬉矝](méi)有用到。
1.2 ROS 環(huán)境初始化
ROS 安裝好之后還需要進(jìn)行初始化,不過(guò)也是只有短短幾行命令:
1sudo rosdep init
2rosdep update
3
4echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
5source ~/.bashrc

1.3 啟動(dòng) ROS
啟動(dòng) ROS 的話我們需要確保它是常駐后臺(tái)運(yùn)行的,所以我們可以使用 tmux:
1roscore
tmux 里啟動(dòng)了 ROS 主節(jié)點(diǎn)后,我們就可以 Ctrl + B D 退出了,而 ROS 主節(jié)點(diǎn)依舊在后臺(tái)運(yùn)行。
1.4 參考文獻(xiàn)
· Armbian:https://www.armbian.com/
· ROS Melodic 安裝:http://wiki.ros.org/melodic/Installation/Ubuntu
2 RT-Thread 串口連接 ROS

這一部分會(huì)介紹如何使用串口將運(yùn)行著 RT-Thread 的 STM32 開發(fā)板和運(yùn)行著 ROS 的 ARM 開發(fā)板連接,看起來(lái)差不多就是這樣。
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml16216\wps10.png
這里說(shuō)明一下不同開發(fā)板的分工,STM32 運(yùn)行著 RT-Thread 負(fù)責(zé)控制電機(jī),接收傳感器信息;ARM 運(yùn)行著 ROS 負(fù)責(zé)進(jìn)行全局控制,例如給小車發(fā)出前進(jìn)的指令。
2.1 RT-Thread 配置
首先我們需要打開 usart2,因?yàn)?usart1 被 msh 使用了,保留作為調(diào)試還是挺方便的。file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml16216\wps11.png
CubeMX 里我打開了 USART2,另外還打開了 4 路 PWM,因?yàn)槲液竺媸褂昧?2 個(gè)電機(jī),每個(gè)電機(jī)需要 2 路 PWM 分別控制前進(jìn)和后退。接下來(lái)還需要在 menuconfig 里面打開對(duì)應(yīng)的選項(xiàng),考慮到有的開發(fā)板默認(rèn)的 bsp 可能沒(méi)有這些選項(xiàng),可以修改 board/Kconfig 添加下面的內(nèi)容。串口的配置:
1menuconfig BSP_USING_UART
2    bool "Enable UART"
3    default y
4    select RT_USING_SERIAL
5    if BSP_USING_UART
6        config BSP_USING_UART1
7            bool "Enable UART1"
8            default y
9
10        config BSP_UART1_RX_USING_DMA
11            bool "Enable UART1 RX DMA"
12            depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA
13            default n
14
15        config BSP_USING_UART2
16            bool "Enable UART2"
17            default y
18
19        config BSP_UART2_RX_USING_DMA
20            bool "Enable UART2 RX DMA"
21            depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA
22            default n
23    endif

PWM 的配置:
1menuconfig BSP_USING_PWM
2    bool "Enable pwm"
3    default n
4    select RT_USING_PWM
5    if BSP_USING_PWM
6    menuconfig BSP_USING_PWM3
7        bool "Enable timer3 output pwm"
8        default n
9        if BSP_USING_PWM3
10            config BSP_USING_PWM3_CH1
11                bool "Enable PWM3 channel1"
12                default n
13            config BSP_USING_PWM3_CH2
14                bool "Enable PWM3 channel2"
15                default n
16            config BSP_USING_PWM3_CH3
17                bool "Enable PWM3 channel3"
18                default n
19            config BSP_USING_PWM3_CH4
20                bool "Enable PWM3 channel4"
21                default n
22        endif
23    endif
這樣我們?cè)?/font> env 下就可以看到有對(duì)應(yīng)的配置了,
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml16216\wps12.png
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml16216\wps13.png
除此之外,我們還需要選擇 rosserial 軟件包:
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml16216\wps14.png
可以看到上面默認(rèn)的串口就是 USART2,這樣我們就可以生成對(duì)應(yīng)的工程了:
1pkgs --update
2scons --target=mdk5 -s
如果我們打開 Keil 項(xiàng)目,首先需要把 main.c 修改為 main.cpp,因?yàn)?rosserial 很多數(shù)據(jù)格式的定義都是用 C++ 寫的,所以如果要使用 rosserial 庫(kù),我們先得把后綴改為 cpp,這樣 Keil 就會(huì)用 C++ 編譯器編譯。
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml16216\wps15.png
下面是 main.cpp 的內(nèi)容,其實(shí)就是初始化了電機(jī),然后發(fā)布了 2 個(gè)話題 (topic),一個(gè)是 /vel_x 告訴 ROS 當(dāng)前小車的速度,一個(gè)是 /turn_bias 告訴 ROS 當(dāng)前小車的旋轉(zhuǎn)速度。同時(shí)又訂閱了一個(gè)話題 /cmd_vel,用來(lái)接收從 ROS 發(fā)出的控制指令。代碼不是特別長(zhǎng),我也添加了一些注釋,所以這里就不一行行分析了。
1#include
2#include
3#include
4
5#include
6#include
7#include
8#include "motors.h"
9
10ros::NodeHandle  nh;
11MotorControl mtr(1, 2, 3, 4);   //Motor
12
13bool msgRecieved = false;
14float velX = 0, turnBias = 0;
15char stat_log[200];
16
17// 接收到命令時(shí)的回調(diào)函數(shù)
18void velCB( const geometry_msgs::Twist& twist_msg)
19{
20  velX = twist_msg.linear.x;
21  turnBias = twist_msg.angular.z;
22  msgRecieved = true;
23}
24
25//Subscriber
26ros::Subscriber sub("cmd_vel", velCB );
27
28//Publisher
29std_msgs::Float64 velX_tmp;
30std_msgs::Float64 turnBias_tmp;
31ros:ublisher xv("vel_x", &velX_tmp);
32ros:ublisher xt("turn_bias", &turnBias_tmp);
33
34static void rosserial_thread_entry(void *parameter)
35{
36    //Init motors, specif>y the respective motor pins
37    mtr.initMotors();
38
39    //Init node>
40    nh.initNode();
41
42    // 訂閱了一個(gè)話題 /cmd_vel 接收控制指令
43    nh.subscribe(sub);
44
45    // 發(fā)布了一個(gè)話題 /vel_x 告訴 ROS 小車速度
46    nh.advertise(xv);
47
48    // 發(fā)布了一個(gè)話題 /turn_bias 告訴 ROS 小車的旋轉(zhuǎn)角速度
49    nh.advertise(xt);
50
51    mtr.stopMotors();
52
53    while (1)
54    {
55      // 如果接收到了控制指令
56      if (msgRecieved)
57      {
58        velX *= mtr.maxSpd;
59        mtr.moveBot(velX, turnBias);
60        msgRecieved = false;
61      }
62
63      velX_tmp.data = velX;
64      turnBias_tmp.data = turnBias/mtr.turnFactor;
65
66      // 更新話題內(nèi)容
67      xv.publish( &velX_tmp );
68      xt.publish( &turnBias_tmp );
69
70      nh.spinOnce();
71    }
72}
73
74int main(void)
75{
76    // 啟動(dòng)一個(gè)線程用來(lái)和 ROS 通信
77    rt_thread_t thread = rt_thread_create("rosserial",     rosserial_thread_entry, RT_NULL, 2048, 8, 10);
78    if(thread != RT_NULL)
79    {
80        rt_thread_startup(thread);
81        rt_kprintf("[rosserial] New thread rosserial\n");
82    }
83    else
84    {
85        rt_kprintf("[rosserial] Failed to create thread rosserial\n");
86    }
87    return RT_EOK;
88}
另外還有對(duì)應(yīng)的電機(jī)控制的代碼,不過(guò)這個(gè)大家的小車不同,驅(qū)動(dòng)應(yīng)當(dāng)也不一樣,我這里由于小車電機(jī)上沒(méi)有編碼器,所以全部是開環(huán)控制的。
motors.h
1#include
2
3class MotorControl {
4  public:
5    //Var
6    rt_uint32_t  maxSpd;
7    float moveFactor;
8    float turnFactor;
9
10    MotorControl(int fl_for, int fl_back,
11                 int fr_for, int fr_back);
12    void initMotors();
13    void rotateBot(int dir, float spd);
14    void moveBot(float spd, float bias);
15    void stopMotors();
16  private:
17    struct rt_device_pwm *pwm_dev;
18    //The pins
19    int fl_for;
20    int fl_back;
21    int fr_for;
22    int fr_back;
23    int bl_for;
24    int bl_back;
25    int br_for;
26    int br_back;
27};
motors.c
  1#include
  2#include
  3#include "motors.h"
  4
  5#define PWM_DEV_NAME "pwm3"
  6
  7MotorControl::MotorControl(int fl_for, int fl_back,
  8                           int fr_for, int fr_back)
  9{
10    this->maxSpd = 500000;
11    this->moveFactor = 1.0;
12    this->turnFactor = 3.0;
13
14    this->fl_for = fl_for;
15    this->fl_back = fl_back;
16
17    this->fr_for = fr_for;
18    this->fr_back = fr_back;
19}
20
21void MotorControl::initMotors() {
22    /* 查找設(shè)備 */
23    this->pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
24    if (pwm_dev == RT_NULL)
25    {
26        rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);
27    }
28    rt_kprintf("pwm found %s device!\n", PWM_DEV_NAME);
29    rt_pwm_set(pwm_dev, fl_for, maxSpd, 0);
30    rt_pwm_enable(pwm_dev, fl_for);
31
32    rt_pwm_set(pwm_dev, fl_back, maxSpd, 0);
33    rt_pwm_enable(pwm_dev, fl_back);
34
35    rt_pwm_set(pwm_dev, fr_for, maxSpd, 0);
36    rt_pwm_enable(pwm_dev, fr_for);
37
38    rt_pwm_set(pwm_dev, fr_back, maxSpd, 0);
39    rt_pwm_enable(pwm_dev, fr_back);
40}
41
42// 小車運(yùn)動(dòng)
43void MotorControl::moveBot(float spd, float bias) {
44    float sL = spd * maxSpd;
45    float sR = spd * maxSpd;
46    int dir = (spd > 0) ? 1 : 0;
47
48    if(bias != 0)
49    {
50        rotateBot((bias > 0) ? 1 : 0, bias);
51        return;
52    }
53
54    if( sL < -moveFactor * maxSpd)
55    {
56        sL = -moveFactor * maxSpd;
57    }
58    if( sL > moveFactor * maxSpd)
59    {
60        sL = moveFactor * maxSpd;
61    }
62
63    if( sR < -moveFactor * maxSpd)
64    {
65        sR = -moveFactor * maxSpd;
66    }
67    if( sR > moveFactor * maxSpd)
68    {
69        sR = moveFactor * maxSpd;
70    }
71
72    if (sL < 0)
73    {
74        sL *= -1;
75    }
76
77    if (sR < 0)
78    {
79        sR *= -1;
80    }
81
82    rt_kprintf("Speed Left: %ld\n", (rt_int32_t)sL);
83    rt_kprintf("Speed Right: %ld\n", (rt_int32_t)sR);
84
85    if(dir)
86    {
87        rt_pwm_set(pwm_dev, fl_for, maxSpd, (rt_int32_t)sL);
88        rt_pwm_set(pwm_dev, fl_back, maxSpd, 0);
89        rt_pwm_set(pwm_dev, fr_for, maxSpd, (rt_int32_t)sR);
90        rt_pwm_set(pwm_dev, fr_back, maxSpd, 0);
91    }
92    else
93    {
94        rt_pwm_set(pwm_dev, fl_for, maxSpd, 0);
95        rt_pwm_set(pwm_dev, fl_back, maxSpd, (rt_int32_t)sL);
96        rt_pwm_set(pwm_dev, fr_for, maxSpd, 0);
97        rt_pwm_set(pwm_dev, fr_back, maxSpd, (rt_int32_t)sR);
98    }
99
100    rt_thread_mdelay(1);
101}
102
103
104// 小車旋轉(zhuǎn)
105void MotorControl::rotateBot(int dir, float spd) {
106    float s = spd * maxSpd;
107    if (dir < 0)
108    {
109        s *= -1;
110    }
111    if(dir)
112    {
113        // Clockwise
114        rt_pwm_set(pwm_dev, fl_for, maxSpd, (rt_int32_t)s);
115        rt_pwm_set(pwm_dev, fl_back, maxSpd, 0);
116        rt_pwm_set(pwm_dev, fr_for, maxSpd, 0);
117        rt_pwm_set(pwm_dev, fr_back, maxSpd, (rt_int32_t)s);
118    }
119    else
120    {
121        // Counter Clockwise
122        rt_pwm_set(pwm_dev, fl_for, maxSpd, 0);
123        rt_pwm_set(pwm_dev, fl_back, maxSpd, (rt_int32_t)s);
124        rt_pwm_set(pwm_dev, fr_for, maxSpd, (rt_int32_t)s);
125        rt_pwm_set(pwm_dev, fr_back, maxSpd, 0);
126    }
127    rt_thread_mdelay(1);
128}
129
130//Turn off both motors
131void MotorControl::stopMotors()
132{
133    rt_pwm_set(pwm_dev, fl_for, maxSpd, 0);
134    rt_pwm_set(pwm_dev, fl_back, maxSpd, 0);
135    rt_pwm_set(pwm_dev, fr_for, maxSpd, 0);
136    rt_pwm_set(pwm_dev, fr_back, maxSpd, 0);
137}
一共只需要這么一點(diǎn)代碼就可以實(shí)現(xiàn)和 ROS 的連接了,所以其實(shí) ROS 也不是那么神秘,它就是因?yàn)楹?jiǎn)單好用所以才這么受歡迎的。既然 RT-Thread 已經(jīng)配置好了,下一步就是 ROS 的配置了。
2.2 ROS 配置
我們把上面 RT-Thread 的固件傳到板子上以后,可以用一個(gè) USB-TTL 一邊和 STM32 控制板的 USART2 連接,另一邊插到 ARM 控制板的 USB 口,接下來(lái)就可以建立連接了,在 ARM 板上輸入命令:
1$ rosrun rosserial_python serial_node.py /dev/ttyUSB0
如果看到下面的輸出,那就成功建立連接了:
1tpl@nanopineoplus2:~$ rosrun rosserial_python serial_node.py /dev/ttyUSB0
2[INFO] [1567239474.258919]: ROS Serial Python Node
3[INFO] [1567239474.288435]: Connecting to /dev/ttyUSB0 at 57600 baud
4[INFO] [1567239476.425646]: Requesting topics...
5[INFO] [1567239476.464336]: Note: publish buffer size is 512 bytes
6[INFO] [1567239476.471349]: Setup publisher on vel_x [std_msgs/Float64]
7[INFO] [1567239476.489881]: Setup publisher on turn_bias [std_msgs/Float64]
8[INFO] [1567239476.777573]: Note: subscribe buffer size is 512 bytes
9[INFO] [1567239476.785032]: Setup subscriber on cmd_vel [geometry_msgs/Twist]
2.3 ROS 控制小車
既然已經(jīng)成功建立連接了,下一步就是寫小車控制的代碼了。我們先初始化一個(gè)工作區(qū)間:
1$ mkdir catkin_workspace && cd catkin_workspace
2$ catkin_init_workspace
接下來(lái)創(chuàng)建一個(gè)軟件包:
1$ cd src
2$ catkin_create_pkg my_first_pkg rospy
這樣就會(huì)自動(dòng)在 src 目錄創(chuàng)建一個(gè) ROS 軟件包了。我們?cè)?catkin_workspace/src/my_first_pkg/src 目錄下新建一個(gè)文件 ros_cmd_vel_pub.py:
1#!/usr/bin/python
2
3import rospy
4from geometry_msgs.msg import Twist
5from pynput.keyboard import Key, Listener
6
7vel = Twist()
8vel.linear.x = 0
9
10def on_press(key):
11
12    try:
13        if(key.char == 'w'):
14            print("Forward")
15            vel.linear.x = 0.8
16            vel.angular.z = 0
17
18        if(key.char == 's'):
19            print("Backward")
20            vel.linear.x = -0.8
21            vel.angular.z = 0
22
23        if(key.char == 'a'):
24            print("Counter Clockwise")
25            vel.linear.x = 0
26            vel.angular.z = -0.8
27
28        if(key.char == 'd'):
29            print("Clockwise")
30            vel.linear.x = 0
31            vel.angular.z = 0.8
32
33        return False
34
35    except AttributeError:
36        print('special key {0} pressed'.format(key))
37        return False
38
39def on_release(key):
40    vel.linear.x = 0
41    vel.angular.z = 0
42
43    return False
44
45# Init Node
46rospy.init_node('my_cmd_vel_publisher')
47pub = rospy.Publisher('cmd_vel', Twist, queue_size=10)
48
49# Set rate
50rate = rospy.Rate(10)
51
52listener = Listener(on_release=on_release, on_press = on_press)
53
54while not rospy.is_shutdown():
55    print(vel.linear.x)
56    pub.publish(vel)
57    vel.linear.x = 0
58    vel.angular.z = 0
59    rate.sleep()
60
61    if not listener.running:
62        listener = Listener(on_release=on_release, on_press = on_press)
63        listener.start()
這就是我們的 python 控制程序了,可以使用鍵盤的 wasd 控制小車前進(jìn)后退,順時(shí)針、逆時(shí)針旋轉(zhuǎn)。我們需要給它添加可執(zhí)行權(quán)限:
1$ chmod u+x ./ros_cmd_vel_pub.py
這樣就可以編譯軟件包了,在 catkin_worspace 目錄下。
1$ catkin_make
2$ source devel/setup.bash
我們終于就可以啟動(dòng)程序從電腦上控制小車運(yùn)動(dòng)了:
1rosrun my_first_pkg ros_cmd_vel_pub.py
可以看到用 ROS 實(shí)現(xiàn)小車控制其實(shí)代碼量并不算多,只需要在自己小車原有的代碼上發(fā)布一些話題,告訴 ROS 小車當(dāng)前的狀態(tài),并且訂閱一個(gè)話題接收 ROS 的控制指令就可以了。
2.4 參考文獻(xiàn)
· ros-pibot:https://github.com/wuhanstudio/ros-pibot
3 RT-Thread 無(wú)線連接 ROS3.1 rosserial 配置
其實(shí)無(wú)線連接和有線連接幾乎是一模一樣的,只不過(guò)是先用 ESP8266 使自己的控制板能連上網(wǎng),然后用 tcp 連接和 ROS 通信,關(guān)于 RT-Thread 使用 ESP8266 上網(wǎng)的教程可以參照 官網(wǎng):https://www.rt-thread.org/document/site/application-note/components/at/an0014-at-client/,非常詳細(xì)了,我這里就不重復(fù)了。確保開發(fā)板有網(wǎng)絡(luò)連接后,我們就可以在 rosserial 里面配置為使用 tcp 連接:file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml16216\wps16.png
我們只需要在上一部分的 main.cpp 里添加一行代碼:
1// 設(shè)置 ROS 的 IP 端口號(hào)
2nh.getHardware()->setConnection("192.168.1.210", 11411);
3
4// 添加在節(jié)點(diǎn)初始化之前
5nh.initNode();
開發(fā)板就能通過(guò) tcp 連接和 ROS 通信了,非常方便。
3.2 ROS 配置
由于我們使用了 tcp 連接,所以 ROS 上自然也要開啟一個(gè)服務(wù)器了,之前是使用的串口建立連接,現(xiàn)在就是使用 tcp 了:
1$ rosrun rosserial_python serial_node.py tcp
其他的代碼完全不需要改變,這樣我們就實(shí)現(xiàn)了一個(gè) ROS 無(wú)線控制的小車了。
3.3 參考文獻(xiàn)
·
RT-Thread 使用 ESP8266 上網(wǎng):
·
https://www.rt-thread.org/document/site/application-note/components/at/an0014-at-client/
4 總結(jié)
這里再總結(jié)一下,其實(shí) RT-Thread 使用 rosserial 軟件包和 ROS 建立連接非常簡(jiǎn)單,只需要在自己小車原有代碼的基礎(chǔ)上發(fā)布一些消息,告訴 ROS 小車當(dāng)前的狀態(tài),以及訂閱來(lái)自 ROS 的控制指令就可以了。

本文地址:http://m.qingdxww.cn/thread-589444-1-1.html     【打印本頁(yè)】

本站部分文章為轉(zhuǎn)載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀點(diǎn)和對(duì)其真實(shí)性負(fù)責(zé);文章版權(quán)歸原作者及原出處所有,如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,我們將根據(jù)著作權(quán)人的要求,第一時(shí)間更正或刪除。
您需要登錄后才可以發(fā)表評(píng)論 登錄 | 立即注冊(cè)

廠商推薦

  • Microchip視頻專區(qū)
  • 探索PIC16F13145 MCU系列——快速概覽
  • PIC32CM LS00 Curiosity Pro評(píng)估工具包
  • dsPIC® DSC集成電機(jī)驅(qū)動(dòng)器:非常適合在緊湊空間內(nèi)進(jìn)行實(shí)時(shí)控制
  • PIC32CK SG單片機(jī)——輕松滿足新型網(wǎng)絡(luò)安全要求
  • 貿(mào)澤電子(Mouser)專區(qū)
關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲欧洲国产成人精品| 亚洲国产精品lv| 亚洲无线乱码高清在线观看一区 | 亚洲网站大全| 日韩欧美中文字幕在线视频| 亚洲成人免费看| 欧美成人免费在线| 亚洲欧美日韩高清| 亚洲一级在线| 欧美午夜在线视频| 亚洲精品国产综合久久一线| 手机免费看a| 三级免费网| 日本片免费观看一区二区| 青青久操视频| 午夜视频啪啪| 午夜视频在线观看一区| 日韩一级在线播放| 亚洲欧美精品久久| 一级毛片一级毛片一级毛片aa| 特级一级全黄毛片免费| 一级片视频免费| 亚洲欧美色图小说| 午夜激情免费| 日韩一区二区三区四区五区| 午夜一区二区在线观看| 亚洲精国产一区二区三区| 欧美性野久久久久久久久| 日本人视频jizz4| 一二三区乱码一区二区三区码| 欧美国产人妖另类色视频| 亚洲欧美男人天堂| 亚洲人和日本人jzz护士| 杨幂国产精品福利在线观看| 亚洲最大成人网 色香蕉| 四虎精品久久久久影院| 青青青青青国产免费观看| 一级爱片| 四虎影视在线永久免费看黄| 日本三级一区二区| 亚洲成人一区在线|