-
Notifications
You must be signed in to change notification settings - Fork 0
/
rostp.tex
17972 lines (13530 loc) · 597 KB
/
rostp.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass[openany, fontset=windowsold]{ctexbook}
\usepackage{anyfontsize}
\usepackage[left=3.5cm,right=3.5cm,top=3cm,bottom=3cm,headheight=13pt]{geometry}
\ctexset{
chapter/number = \arabic{chapter},
chapter/beforeskip = {0pt},
}
\setcounter{secnumdepth}{3}
\usepackage{fancyhdr}
\fancyhf{}
\fancyhead[OC]{\kaishu\nouppercase\rightmark}
\fancyhead[OR]{\thepage}
\fancyhead[EL]{\thepage}
\fancyhead[EC]{\kaishu\nouppercase\leftmark}
\pagestyle{fancy}
\usepackage{amsmath,amssymb,amsfonts,amsthm,mathrsfs,bm}
\newtheoremstyle{kaiti}{3pt}{3pt}{\kaishu}{}{\bfseries}{}{.5em}{}
\theoremstyle{kaiti}
\newtheorem{definition}{定义}[section]
\newtheorem{theorem}{定理}[section]
\newtheorem{corollary}{推论}[section]
\newtheorem{proposition}{命题}[section]
\newtheorem{lemma}{引理}[section]
\newtheoremstyle{normal}{3pt}{3pt}{}{}{\bfseries}{}{.5em}{}
\theoremstyle{normal}
\newtheorem{example}{例}[section]
\newtheorem{remark}{注}[section]
\makeatletter
\renewenvironment{proof}[1][\proofname]{\par
\pushQED{\qed}%
\normalfont \topsep6\p@\@plus6\p@\relax
\trivlist
\item\relax
{\heiti #1}\hspace{2\labelsep}\ignorespaces
}{%
\popQED\endtrivlist\@endpefalse
}
\makeatother
\usepackage{graphicx}
\graphicspath{{./figures/}}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{cd}
\tikzcdset{
arrow style=tikz,
diagrams={>=Latex}
}
\usepackage{subfigure}
\usepackage{longtable}
\usepackage{hyperref}
\hypersetup{
breaklinks,
colorlinks = true,
citecolor = blue,
linkcolor = red,
urlcolor = magenta,
}
\usepackage{listings}
\usepackage{color}
\lstdefinestyle{lstStyleBase}{%
basicstyle=\small\ttfamily,
aboveskip=\medskipamount,
belowskip=\medskipamount,
lineskip=0pt,
boxpos=c,
showlines=false,
extendedchars=true,
upquote=true,
tabsize=2,
showtabs=false,
showspaces=false,
showstringspaces=false,
numbers=none,
linewidth=\linewidth,
xleftmargin=9.5mm,
xrightmargin=0pt,
resetmargins=false,
breaklines=true,
breakatwhitespace=false,
breakindent=0pt,
breakautoindent=true,
columns=flexible,
keepspaces=true,
gobble=2,
framesep=3pt,
rulesep=1pt,
framerule=1pt,
backgroundcolor=\color{gray!5},
stringstyle=\color{green!40!black!100},
keywordstyle=\bfseries\color{blue!50!black},
commentstyle=\slshape\color{black!60}
}
\lstdefinestyle{lstStylePython}{%
style=lstStyleBase,
frame=l,
rulecolor=\color{purple},
language=Python
}
\lstdefinestyle{lstStyleCPP}{%
style=lstStyleBase,
frame=l,
rulecolor=\color{purple},
language=C++
}
\lstdefinestyle{lstStyleBASH}{%
style=lstStyleBase,
frame=l,
rulecolor=\color{purple},
language=bash
}
\lstdefinestyle{lstStyleXML}{%
style=lstStyleBase,
frame=l,
rulecolor=\color{purple},
language=xml
}
\lstnewenvironment{python}{\lstset{style=lstStylePython}}{}
\lstnewenvironment{cpp}{\lstset{style=lstStyleCPP}}{}
\lstnewenvironment{xml}{%
\lstset{%
style=lstStyleXML,
morekeywords={remap,launch,robot,node,param,rosparam,color,link,joint,gazebo,xacro,plugin,include,sensor,ray,noise,range,scan,pose,visualize,update_rate,min,max,resolution,mean,stddev,type,topicName,frameName,xacro:include,horizontal,samples,min_angle,max_angle,camera,horizontal_fov,image,width,height,format,clip,near,far,alwaysOn,updateRate,cameraName,imageTopicName,cameraInfoTopicName,hackBaseline,distortionK1,distortionK2,distortionK3,distortionT1,distortionT2,xacro:macro,transmission,hardwareInterface,actuator,mechanicalReduction,xacro:joint_trans,rosDebugLevel,publishWheelTF,robotNamespace,publishTf,publishWheelJointState,legacyMode,leftJoint,rightJoint,wheelSeparation,wheelDiameter,broadcastTF,wheelTorque,wheelAcceleration,commandTopic,odometryFrame,odometryTopic,robotBaseFrame,arg,parent,child,origin,material,xacro:cylinder_inertial_matrix,collision,geometry,visual,cylinder,xacro:property,xacro:Box_inertial_matrix,xacro:add_support_wheel,axis,xacro:sphere_inertial_matrix,xacro:add_wheels,inertial,mass,inertia,box,xacro:wheel_func,sphere,package,name,description,maintainer,license,url,author,depend,build_depend,exec_depend,build_export_depend,buildtool_depend,test_depend,doc_depend,export,always_on,depthImageTopicName,pointCloudTopicName,depthImageCameraInfoTopicName,baseline,distortion_k1,distortion_k2,distortion_k3,distortion_t1,distortion_t2,pointCloudCutoff,library,class,xacro:small_wheel_func},
keywordstyle=\bfseries\color{blue!50!black}
}
}{}
\lstnewenvironment{bash}{%
\lstset{%
style=lstStyleBASH,
morekeywords={git,sudo,ln,mkdir,catkin_make,catkin_create_pkg,apt,apt-key,sh,roscore,rosrun,rosnode,roslaunch,rosparam,rostopic,chmod,catkin_install_python,add_executable,target_link_libraries,add_dependencies,include_directories,catkin_package,find_package,cmake_minimum_required,project,rospack,roscd,rosls,rosed,rqt_graph,rosmsg,rosservice,rossrv,rosbag,urdf_to_graphiz,check_urdf,wget,add_message_files,generate_messages,add_service_files,add_action_files,generate_dynamic_reconfigure_options,add_library,nodelet,ls,groups,rviz,ll,scp,pip,easy_install,ssh,systemctl,grep},
keywordstyle=\bfseries\color{blue!50!black}
}
}{}
% 图表索引
\usepackage{etoolbox}
\makeatletter
\patchcmd{\@caption}{\csname the#1\endcsname}{\csname fnum@#1\endcsname}{}{}
\renewcommand*\l@figure{\@dottedtocline{1}{1.5em}{3.5em}} % default for 3rd arg: 2.3em
\let\l@table\l@figure % as in article.cls
\makeatother
\renewcommand{\listfigurename}{插图索引}
\renewcommand{\listtablename}{表格索引}
\begin{document}
\title{\heiti\Huge ROS理论与实践 \vspace{0.5cm}}
\author{\LARGE\kaishu \href{http://www.autolabor.com.cn/book/ROSTutorials/index.html}{Autolabor} 编著 \vspace*{0.5cm} \\ \LARGE\kaishu 杨敬轩 \quad 排版 \vspace{1cm}}
\maketitle
\thispagestyle{empty}
\frontmatter
\pagenumbering{Roman}
\chapter*{前言}
\markboth{前言}{}
本书主要来源于 \href{http://www.autolabor.com.cn/book/ROSTutorials/index.html}{Autolabor}, 谨用 \LaTeX 排版整理, 版权归原作者所有.
\vspace*{1cm}
\hfill {\kaishu 杨敬轩}
\hfill 2023年7月于天津
\chapter*{序言}
\markboth{序言}{}
ROS (Robot Operating System, 机器人操作系统) 近几年发展迅速, 国内也有相当一部分开发人员有意向涉足 ROS, 但是苦于没有低门槛的系统性教程, 只能望之兴叹, 基于此我们设计了一套免费、零基础、理论与实践相结合的教程, 以帮助有志于机器人开发的读者方便快捷的上手 ROS, 继而推动整个行业的进步.
1. 课程内容
本教程主要由理论篇与实践篇组成, 理论篇对应的是第1到第5章, 实践篇对应的是第6章以及以后, 具体内容如下:
理论篇:
\begin{table}[!h]
\centering
\caption{理论篇内容}
\label{tab:theory_outline}
\begin{tabular}{ll}
\hline
章节 & 内容 \\
\hline
第1章 ROS概述与环境搭建 & 旨在了解 ROS 并搭建开发环境 \\
第2章 ROS通信机制 & ROS 核心实现 \\
第3章 ROS通信机制进阶 & ROS 核心实现 \\
第4章 ROS运行管理 & ROS 中零散但又常用的知识点 \\
第5章 ROS常用组件 & ROS 中比较实用的功能模块 \\
\hline
\end{tabular}
\end{table}
实践篇:
\begin{table}[!h]
\centering
\caption{实践篇内容}
\label{tab:practice_outline}
\begin{tabular}{ll}
\hline
章节 & 内容 \\
\hline
第6章~机器人系统仿真 & 机器人模型的创建, 仿真环境的创建以及使用 \\
第7章~机器人导航 (仿真) & 仿真环境下实现导航功能 \\
第8章~机器人平台设计 & 从0到1手把手教你 DIY 一台机器人 \\
第9章~机器人导航 (实体) & 将导航功能从仿真环境移植到实体机器人 \\
第10章~ROS进阶 & ROS 中的高级应用 \\
% 第11章 ROS项目 & 公司内部一些 ROS 项目 \\
\hline
\end{tabular}
\end{table}
整体而言, 理论篇侧重于理论的介绍, 是整个教程的基石, 实践篇侧重于可见的应用, 会通过一些案例将理论加以整合.
2. 项目产出
部分演示如下:
演示1: 仿真环境下的导航实现.
\begin{figure}[!ht]
\centering
\includegraphics[width=.7\textwidth]{navigation_demo.png}
\caption{仿真环境下的导航实现}
\label{fig:navigation_demo}
\end{figure}
演示2: DIY的机器人.
\begin{figure}[!ht]
\centering
\includegraphics[width=.5\textwidth]{robot_chassis_front.jpg}
\caption{机器人底盘正面}
\label{fig:robot_chassis_front_}
\end{figure}
\begin{figure}[!ht]
\centering
\includegraphics[width=.5\textwidth]{robot_arduino_board.jpg}
\caption{机器人Arduino 与电机驱动板}
\label{fig:robot_arduino_board_}
\end{figure}
\begin{figure}[!ht]
\centering
\includegraphics[width=.5\textwidth]{robot_chassis_back.jpg}
\caption{机器人底盘背面}
\label{fig:robot_chassis_back_}
\end{figure}
演示3: \href{https://www.bilibili.com/video/BV15z4y1672p}{机器人SLAM}.
演示4: \href{https://www.bilibili.com/video/BV1j5411n7Nc}{机器人多点导航}.
演示5: \href{https://www.bilibili.com/video/BV1bx411E7SC}{ROS模拟器}.
\tableofcontents
\listoffigures
\listoftables
\mainmatter
\chapter{ROS概述与环境搭建}
学习是一个循序渐进的过程, 具体到计算机领域的软件开发层面, 每当接触一个新的知识模块时, 按照一般的步骤, 我们会先去了解该模块的相关概念, 然后再安装官方软件包, 接下来再搭建其集成的开发环境等等. 这些准备工作完毕之后, 才算是叩开了新领域的大门. 学习 ROS, 我们也是遵循这一流程, 本章作为 ROS 体系的开篇主要内容如下:
\begin{itemize}
\item ROS的相关概念;
\item 怎样安装ROS;
\item 如何搭建 ROS 的集成开发环境.
\end{itemize}
该章内容学习完毕预期达成的目标如下:
\begin{itemize}
\item 了解 ROS 概念、设计目标以及发展历程;
\item 能够独立安装并运行 ROS;
\item 能够使用 C++ 或 Python 实现 ROS 版本的 HelloWorld;
\item 能够搭建 ROS 的集成开发环境;
\item 了解 ROS 架构设计.
\end{itemize}
\section{ROS简介}
\subsection{ROS概念}
ROS 全称: Robot Operating System (机器人操作系统).
\begin{itemize}
\item ROS是适用于机器人的开源元操作系统;
\item ROS集成了大量的工具, 库, 协议, 提供类似 OS 所提供的功能, 简化对机器人的控制;
\item 还提供了用于在多台计算机上获取, 构建, 编写和运行代码的工具和库, ROS在某些方面类似于机器人框架;
\item ROS设计者将 ROS 表述为 ROS = Plumbing + Tools + Capabilities + Ecosystem, 即 ROS 是通讯机制、工具软件包、机器人高层技能以及机器人生态系统的集合体.
\end{itemize}
\begin{figure}[!ht]
\centering
\includegraphics[width=.9\textwidth]{ros_intro.png}
\caption{ROS架构简介}
\label{fig:ros_intro}
\end{figure}
\subsection{ROS设计目标}
机器人开发的分工思想, 实现了不同研发团队间的共享和协作, 提升了机器人的研发效率, 为了服务分工, ROS 主要设计了如下目标:
\begin{itemize}
\item 代码复用: ROS 的目标不是成为具有最多功能的框架, ROS 的主要目标是支持机器人技术研发中的代码重用.
\item 分布式: ROS 是进程 (也称为 Nodes) 的分布式框架, ROS 中的进程可分布于不同主机, 不同主机协同工作, 从而分散计算压力
\item 松耦合: ROS 中功能模块封装于独立的功能包或元功能包, 便于分享, 功能包内的模块以节点为单位运行, 以 ROS 标准的 IO 作为接口, 开发者不需要关注模块内部实现, 只要了解接口规则就能实现复用, 实现了模块间点对点的松耦合连接
\item 精简: ROS 被设计为尽可能精简, 以便为 ROS 编写的代码可以与其他机器人软件框架一起使用. ROS 易于与其他机器人软件框架集成: ROS 已与 OpenRAVE, Orocos 和 Player 集成.
\item 语言独立性: 包括 Java, C++, Python 等. 为了支持更多应用开发和移植, ROS 设计为一种语言弱相关的框架结构, 使用简洁, 中立的定义语言描述模块间的消息接口, 在编译中再产生所使用语言的目标文件, 为消息交互提供支持, 同时允许消息接口的嵌套使用
\item 易于测试: ROS 具有称为 \verb|rostest| 的内置单元/集成测试框架, 可轻松安装和拆卸测试工具.
\item 大型应用: ROS 适用于大型运行时系统和大型开发流程.
\item 丰富的组件化工具包: ROS 可采用组件化方式集成一些工具和软件到系统中并作为一个组件直接使用, 如 RViz (3D可视化工具), 开发者根据 ROS 定义的接口在其中显示机器人模型等, 组件还包括仿真环境和消息查看工具等.
\item 免费且开源: 开发者众多, 功能包多.
\end{itemize}
\subsection{ROS发展历程}
ROS 是一个由来已久、贡献者众多的大型软件项目. 在 ROS 诞生之前, 很多学者认为, 机器人研究需要一个开放式的协作框架, 并且已经有不少类似的项目致力于实现这样的框架. 在这些工作中, 斯坦福大学在2000年年中开展了一系列相关研究项目, 如斯坦福人工智能机器人 (STandford AI Robot, STAIR) 项目、个人机器人 (Personal Robots, PR) 项目等, 在上述项目中, 在研究具有代表性、集成式人工智能系统的过程中, 创立了用于室内场景的高灵活性、动态软件系统, 其可以用于机器人学研究.
2007 年, 柳树车库 (Willow Garage) 提供了大量资源, 用于将斯坦福大学机器人项目中的软件系统进行扩展与完善, 同时, 在无数研究人员的共同努力下, ROS 的核心思想和基本软件包逐渐得到完善.
ROS 的发行版本 (ROS distribution) 指 ROS 软件包的版本, 其与 Linux 的发行版本 (如 Ubuntu) 的概念类似. 推出 ROS 发行版本的目的在于使开发人员可以使用相对稳定的代码库, 直到其准备好将所有内容进行版本升级为止. 因此, 每个发行版本推出后, ROS 开发者通常仅对这一版本的bug进行修复, 同时提供少量针对核心软件包的改进.
版本特点: 按照英文字母顺序命名, ROS 目前已经发布了ROS1 的终极版本: noetic, 并建议后期过渡至 ROS2 版本. noetic 版本之前默认使用的是 Python2, noetic 支持 Python3.
建议版本: noetic 或 melodic 或 kinetic.
\begin{figure}[!ht]
\centering
\includegraphics[width=.55\textwidth]{ros_versions.png}
\caption{ROS不同版本}
\label{fig:ros_versions}
\end{figure}
\section{ROS安装}
\subsection{安装虚拟机软件}
参考 \href{http://www.autolabor.com.cn/book/ROSTutorials/chapter1/12-roskai-fa-gong-ju-an-zhuang/121-an-zhuang-xu-ni-ji-ruan-jian.html}{安装虚拟机软件}.
\subsection{虚拟一台主机}
参考 \href{http://www.autolabor.com.cn/book/ROSTutorials/chapter1/12-roskai-fa-gong-ju-an-zhuang/122-xu-ni-yi-tai-zhu-ji.html}{虚拟一台主机}.
\subsection{安装Ubuntu}
参考 \href{http://www.autolabor.com.cn/book/ROSTutorials/chapter1/12-roskai-fa-gong-ju-an-zhuang/123-an-zhuang-ubuntu.html}{安装Ubuntu}.
\subsection{安装ROS}
Ubuntu 安装完毕后, 就可以安装 ROS 操作系统了, 大致步骤如下:
\begin{enumerate}
\item 设置安装源;
\item 设置 key;
\item 配置 Ubuntu 的软件和更新, 安装;
\item 配置环境变量.
\end{enumerate}
1. 设置安装源:
官方默认安装源:
\begin{bash}
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
\end{bash}
或来自国内清华的安装源:
\begin{bash}
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'
\end{bash}
或来自国内中科大的安装源:
\begin{bash}
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'
\end{bash}
PS: 回车后, 可能需要输入管理员密码; 建议使用国内资源, 安装速度更快.
2. 设置 key:
\begin{bash}
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
\end{bash}
3. 安装
首先需要更新 apt (以前是 apt-get, 官方建议使用 apt 而非 apt-get), apt 是用于从互联网仓库搜索、安装、升级、卸载软件或操作系统的工具.
\begin{bash}
sudo apt update
\end{bash}
等待. 然后, 再安装所需类型的 ROS: ROS 多个类型: Desktop-Full、Desktop、ROS-Base. 这里介绍较为常用的Desktop-Full (官方推荐) 安装: ROS, rqt, rviz, robot-generic libraries, 2D/3D simulators, navigation and 2D/3D perception
\begin{bash}
sudo apt install ros-noetic-desktop-full
\end{bash}
4. 配置环境变量
配置环境变量, 方便在任意终端中使用 ROS.
\begin{bash}
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
\end{bash}
卸载: 如果需要卸载 ROS 可以调用如下命令:
\begin{bash}
sudo apt remove ros-noetic-*
\end{bash}
注意: 在 ROS 版本 noetic 中无需构建软件包的依赖关系, 没有 \verb|rosdep| 的相关安装与配置.
\subsection{测试ROS}
ROS 内置了一些小程序, 可以通过运行这些小程序以检测 ROS 环境是否可以正常运行:
\begin{itemize}
\item 首先启动三个命令行 (Ctrl + Alt + T);
\item 命令行1键入:
\begin{bash}
roscore
\end{bash}
\item 命令行2键入: (此时会弹出图形化界面)
\begin{bash}
rosrun turtlesim turtlesim_node
\end{bash}
\item 命令行3键入: (在3中可以通过上下左右控制2中乌龟的运动)
\begin{bash}
rosrun turtlesim turtle_teleop_key
\end{bash}
\end{itemize}
最终结果如下所示. 注意: 光标必须聚焦在键盘控制窗口, 否则无法控制乌龟运动.
\begin{figure}[!ht]
\centering
\includegraphics[width=.9\textwidth]{ros_test_turtlesim.png}
\caption{ROS测试示例}
\label{fig:ros_test_turtlesim}
\end{figure}
\subsection{其他 ROS 版本安装}
我们的教程采用的是 ROS 的最新版本 noetic, 不过 noetic 较之于之前的 ROS 版本变动较大且部分功能包还未更新, 因此如果有需要 (比如到后期实践阶段, 由于部分重要的功能包还未更新, 需要 ROS 降级), 也会安装之前版本的 ROS, 在此, 建议选用的版本是 melodic 或 kinetic.
接下来, 就以 melodic 为例演示 ROS 历史版本安装 (当然先要准备与melodic对应的Ubuntu18.04): \href{http://www.autolabor.com.cn/book/ROSTutorials/chapter1/12-roskai-fa-gong-ju-an-zhuang/127-zi-65993a-qi-ta-ros-ban-ben-an-zhuang.html}{其他 ROS 版本安装}.
\section{ROS快速体验}
\subsection{HelloWorld实现简介}
ROS 中涉及的编程语言以 C++ 和 Python 为主, ROS 中的大多数程序两者都可以实现, 在本系列教程中, 每一个案例也都会分别使用 C++ 和 Python 两种方案演示, 大家可以根据自身情况选择合适的实现方案.
ROS 中的程序即便使用不同的编程语言, 实现流程也大致类似, 以当前 HelloWorld 程序为例, 实现流程大致如下:
\begin{enumerate}
\item 先创建一个工作空间;
\item 再创建一个功能包;
\item 编辑源文件;
\item 编辑配置文件;
\item 编译并执行.
\end{enumerate}
上述流程中, C++ 和 Python 只是在步骤3和步骤4的实现细节上存在差异, 其他流程基本一致. 本节先实现 C++ 和 Python 程序编写的通用部分步骤1与步骤2, 1.3.2节和1.3.3节再分别使用 C++ 和 Python 编写HelloWorld.
1. 创建工作空间并初始化
\begin{bash}
mkdir -p 自定义空间名称/src
cd 自定义空间名称
catkin_make
\end{bash}
上述命令, 首先会创建一个工作空间以及一个 \verb|src| 子目录, 然后再进入工作空间调用 \verb|catkin_make| 命令编译.
2. 进入 \verb|src| 创建 ROS 包并添加依赖
\begin{bash}
cd src
catkin_create_pkg your_ros_package roscpp rospy std_msgs
\end{bash}
上述命令会在工作空间下生成一个功能包, 该功能包依赖 \verb|roscpp|、\verb|rospy| 与 \verb|std_msgs|, 其中 \verb|roscpp| 是使用 C++ 实现的库, 而 \verb|rospy| 则是使用 Python 实现的库, \verb|std_msgs| 是标准消息库, 创建 ROS 功能包时, 一般都会依赖这三个库实现.
注意: 在 ROS 中, 虽然实现同一功能时, C++ 和 Python 可以互换, 但是具体选择哪种语言, 需要视需求而定, 因为两种语言相较而言: C++ 运行效率高但是编码效率低, 而 Python 则反之, 基于二者互补的特点, ROS 设计者分别设计了 \verb|roscpp| 与 \verb|rospy| 库, 前者旨在成为 ROS 的高性能库, 而后者则一般用于对性能无要求的场景, 旨在提高开发效率.
\subsection{HelloWorld 实现 (C++)}
本节内容基于1.3.1, 假设你已经创建了 ROS 的工作空间, 并且创建了 ROS 的功能包, 那么就可以进入核心步骤了, 使用 C++ 编写程序实现:
1. 进入 ROS 包的 \verb|src| 目录编辑源文件
\begin{bash}
cd 自定义的包
\end{bash}
C++ 源码实现: (文件名自定义)
\begin{cpp}
#include "ros/ros.h"
int main(int argc, char *argv[])
{
// 执行 ros 节点初始化
ros::init(argc,argv,"hello");
// 创建 ros 节点句柄 (非必须)
ros::NodeHandle n;
// 控制台输出 hello world
ROS_INFO("hello world!");
return 0;
}
\end{cpp}
2. 编辑 ROS 包下的 \verb|Cmakelists.txt| 文件
\begin{bash}
add_executable(步骤3的源文件名
src/步骤3的源文件名.cpp
)
target_link_libraries(步骤3的源文件名
${catkin_LIBRARIES}
)
\end{bash}
3. 进入工作空间目录并编译
\begin{bash}
cd 自定义空间名称
catkin_make
\end{bash}
生成 build devel ....
4. 执行
先启动命令行1:
\begin{bash}
roscore
\end{bash}
再启动命令行2:
\begin{bash}
cd 工作空间
source ./devel/setup.bash
rosrun 包名 C++节点
\end{bash}
命令行输出: \verb|HelloWorld!|.
PS: \verb|source ~/工作空间/devel/setup.bash| 可以添加进 \verb|.bashrc| 文件, 使用上更方便.
添加方式1: 直接使用 \verb|gedit| 或 \verb|vi| 编辑 \verb|.bashrc| 文件, 最后添加该内容.
添加方式2:
\begin{bash}
echo "source ~/工作空间/devel/setup.bash" >> ~/.bashrc
\end{bash}
\subsection{HelloWorld 实现 (Python)}
本节内容基于1.3.1, 假设你已经创建了 ROS 的工作空间, 并且创建了 ROS 的功能包, 那么就可以进入核心步骤了, 使用 Python 编写程序实现:
1. 进入 ROS 包添加 scripts 目录并编辑 Python 文件:
\begin{bash}
cd ros包
mkdir scripts
\end{bash}
新建 Python 文件: (文件名自定义)
\begin{python}
#! /usr/bin/env python
"""
Python 版 HelloWorld
"""
import rospy
if __name__ == "__main__":
rospy.init_node("Hello")
rospy.loginfo("Hello World!!!!")
\end{python}
2. 为 Python 文件添加可执行权限
\begin{bash}
chmod +x 自定义文件名.py
\end{bash}
3. 编辑 ROS 包下的 \verb|CmakeLists.txt| 文件
\begin{bash}
catkin_install_python(PROGRAMS scripts/自定义文件名.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
\end{bash}
4. 进入工作空间目录并编译
\begin{bash}
cd 自定义空间名称
catkin_make
\end{bash}
5. 进入工作空间目录并执行
先启动命令行1:
\begin{bash}
roscore
\end{bash}
再启动命令行2:
\begin{bash}
cd 工作空间
source ./devel/setup.bash
rosrun 包名 自定义文件名.py
\end{bash}
输出结果: \verb|Hello World!!!!|
\section{ROS集成开发环境搭建}
和大多数开发环境一样, 理论上, 在 ROS 中, 只需要记事本就可以编写基本的 ROS 程序, 但是工欲善其事必先利其器, 为了提高开发效率, 可以先安装集成开发工具和使用方便的工具: 终端、IDE 等等.
\subsection{安装终端}
在 ROS 中, 需要频繁的使用到终端, 且可能需要同时开启多个窗口, 推荐一款较为好用的终端: Terminator. 效果如下:
\begin{figure}[!ht]
\centering
\includegraphics[width=.9\textwidth]{terminator_illustration.png}
\caption{Terminator 效果}
\label{fig:ternimal_illustration}
\end{figure}
1. 安装
\begin{bash}
sudo apt install terminator
\end{bash}
2. 添加到收藏夹
显示应用程序 $\rightarrow$ 搜索 terminator $\rightarrow$ 右击 选择 \verb|添加到收藏夹|.
3. Terminator 常用快捷键
第一部份: 关于在同一个标签内的操作:
\begin{bash}
Alt+Up // 移动到上面的终端
Alt+Down // 移动到下面的终端
Alt+Left // 移动到左边的终端
Alt+Right // 移动到右边的终端
Ctrl+Shift+O // 水平分割终端
Ctrl+Shift+E // 垂直分割终端
Ctrl+Shift+Right // 在垂直分割的终端中将分割条向右移动
Ctrl+Shift+Left // 在垂直分割的终端中将分割条向左移动
Ctrl+Shift+Up // 在水平分割的终端中将分割条向上移动
Ctrl+Shift+Down // 在水平分割的终端中将分割条向下移动
Ctrl+Shift+S // 隐藏/显示滚动条
Ctrl+Shift+F // 搜索
Ctrl+Shift+C // 复制选中的内容到剪贴板
Ctrl+Shift+V // 粘贴剪贴板的内容到此处
Ctrl+Shift+W // 关闭当前终端
Ctrl+Shift+Q // 退出当前窗口, 当前窗口的所有终端都将被关闭
Ctrl+Shift+X // 最大化显示当前终端
Ctrl+Shift+Z // 最大化显示当前终端并使字体放大
Ctrl+Shift+N or Ctrl+Tab // 移动到下一个终端
Ctrl+Shift+P or Ctrl+Shift+Tab // Crtl+Shift+Tab 移动到之前的一个终端
\end{bash}
第二部份: 有关各个标签之间的操作:
\begin{bash}
F11 // 全屏开关
Ctrl+Shift+T // 打开一个新的标签
Ctrl+PageDown // 移动到下一个标签
Ctrl+PageUp // 移动到上一个标签
Ctrl+Shift+PageDown // 将当前标签与其后一个标签交换位置
Ctrl+Shift+PageUp // 将当前标签与其前一个标签交换位置
Ctrl+Plus (+) // 增大字体
Ctrl+Minus (-) // 减小字体
Ctrl+Zero (0) // 恢复字体到原始大小
Ctrl+Shift+R // 重置终端状态
Ctrl+Shift+G // 重置终端状态并clear屏幕
Super+g // 绑定所有的终端, 以便向一个输入能够输入到所有的终端
Super+Shift+G // 解除绑定
Super+t // 绑定当前标签的所有终端, 向一个终端输入的内容会自动输入到其他终端
Super+Shift+T // 解除绑定
Ctrl+Shift+I // 打开一个窗口, 新窗口与原来的窗口使用同一个进程
Super+i // 打开一个新窗口, 新窗口与原来的窗口使用不同的进程
\end{bash}
\subsection{安装VSCode}
VSCode 全称 Visual Studio Code, 是微软出的一款轻量级代码编辑器, 免费、开源而且功能强大. 它支持几乎所有主流的程序语言的语法高亮、智能代码补全、自定义热键、括号匹配、代码片段、代码对比 Diff、GIT 等特性, 支持插件扩展, 并针对网页开发和云端应用开发做了优化. 软件跨平台支持 Win、Mac 以及 Linux.
1. 下载
VSCode\href{https://code.visualstudio.com/docs?start=true}{下载}, 历史版本 \href{https://code.visualstudio.com/updates}{下载链接}.
2. VSCode 安装与卸载
2.1 安装
方式1: 双击安装即可 (或右击选择安装).
方式2:
\begin{bash}
sudo dpkg -i xxxx.deb
\end{bash}
2.2 卸载
\begin{bash}
sudo dpkg --purge code
\end{bash}
3. VSCode 集成 ROS 插件
使用 VSCode 开发 ROS 程序, 需要先安装一些插件, 常用插件如下:
4. VSCode 基本配置
4.1 创建 ROS 工作空间
\begin{bash}
mkdir -p xxx_ws/src
cd xxx_ws
catkin_make
\end{bash}
4.2 启动 VSCode
进入 \verb|xxx_ws| 启动 VSCode:
\begin{bash}
cd xxx_ws
code .
\end{bash}
4.3 VSCode 中编译 ros
快捷键 Ctrl + Shift + B 调用编译, 选择: \verb|catkin_make:build|. 可以点击配置设置为默认, 修改 \verb|.vscode/tasks.json| 文件:
\begin{bash}
{
// 有关 tasks.json 格式的文档, 请参见
// https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"label": "catkin_make:debug", // 代表提示的描述性信息
"type": "shell", // 可以选择shell或者process, 如果是shell代码是在shell里面运行一个命令, 如果是process代表作为一个进程来运行
"command": "catkin_make", // 这个是我们需要运行的命令
"args": [], // 如果需要在命令后面加一些后缀, 可以写在这里, 比如-DCATKIN_WHITELIST_PACKAGES=“pac1;pac2”
"group": {"kind":"build","isDefault":true},
"presentation": {
"reveal": "always" // 可选always或者silence, 代表是否输出信息
},
"problemMatcher": "$msCompile"
}
]
}
\end{bash}
4.4 创建 ROS 功能包
选定 \verb|src| 右击: \verb|create catkin package|.
设置包名 添加依赖
4.5 C++ 实现
在功能包的 \verb|src| 下新建 C++ 文件:
\begin{cpp}
/**
* 控制台输出 Hello VSCode !!!
*/
#include "ros/ros.h"
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
// 执行节点初始化
ros::init(argc,argv,"HelloVSCode");
// 输出日志
ROS_INFO("Hello VSCode!!!");
return 0;
}
\end{cpp}
PS1: 如果没有代码提示, 修改 \verb|.vscode/c_cpp_properties.json|, 设置:
\begin{xml}
"cppStandard": "c++17"
\end{xml}
PS2: \verb|main| 函数的参数不可以被 \verb|const| 修饰.
PS3: 当 \verb|ROS_INFO| 终端输出有中文时, 会出现乱码: \verb|INFO: ????????????????|.
解决办法: 在函数开头加入下面代码的任意一句:
\begin{cpp}
setlocale(LC_CTYPE, "zh_CN.utf8");
setlocale(LC_ALL, "");
\end{cpp}
4.6 Python 实现
在 \verb|功能包/| 下新建 \verb|scripts| 文件夹, 添加 Python 文件, 并添加可执行权限.
\begin{python}
#! /usr/bin/env python
"""
Python 版本的 Hello VSCode, 执行在控制台输出 Hello VScode
实现:
1. 导包
2. 初始化 ROS 节点
3. 日志输出 HelloWorld
"""
import rospy # 1. 导包
if __name__ == "__main__":
rospy.init_node("Hello_Vscode_p") # 2. 初始化 ROS 节点
rospy.loginfo("Hello VSCode, 我是 Python ....") # 3. 日志输出 HelloWorld
\end{python}
4.7 配置 \verb|CMakeLists.txt|
C++ 配置:
\begin{bash}
add_executable(节点名称
src/C++源文件名.cpp
)
target_link_libraries(节点名称
${catkin_LIBRARIES}
)
\end{bash}
Python 配置:
\begin{bash}
catkin_install_python(PROGRAMS scripts/自定义文件名.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
\end{bash}
4.8 编译执行
编译: Ctrl + Shift + B.
执行: 和之前一致, 只是可以在 VSCode 中添加终端, 首先执行:
\begin{bash}
source ./devel/setup.bash
\end{bash}
PS: 如果不编译直接执行 Python 文件, 会抛出异常.
1. 第一行解释器声明, 可以使用绝对路径定位到 python3 的安装路径
\begin{bash}
#! /usr/bin/python3
\end{bash}
但是不建议.
2. 建议使用 \verb|#!/usr/bin/env python| 但是会抛出异常 : \verb|/usr/bin/env: python|: 没有那个文件或目录.
3. 解决1: \verb|#!/usr/bin/env python3| 直接使用 python3 但存在问题: 不兼容之前的 ROS 相关 Python 实现.
4. 解决2: 创建一个链接符号到 Python 命令:
\begin{bash}
sudo ln -s /usr/bin/python3 /usr/bin/python
\end{bash}
\subsection{launch文件演示}
1. 需求: 一个程序中可能需要启动多个节点, 比如: ROS 内置的小乌龟案例, 如果要控制乌龟运动, 要启动多个窗口, 分别启动 \verb|roscore|、乌龟界面节点、键盘控制节点. 如果每次都调用 \verb|rosrun| 逐一启动, 显然效率低下, 如何优化? 官方给出的优化策略是使用 launch 文件, 可以一次性启动多个 ROS 节点.
2. 实现
\begin{itemize}
\item 选定功能包右击 $\rightarrow$ 添加 launch 文件夹;
\item 选定 launch 文件夹右击 $\rightarrow$ 添加 launch 文件;
\item 编辑 launch 文件内容:
\begin{xml}
<launch>
<node pkg="helloworld" type="demo_hello" name="hello" output="screen" />
<node pkg="turtlesim" type="turtlesim_node" name="t1"/>
<node pkg="turtlesim" type="turtle_teleop_key" name="key1" />
</launch>
\end{xml}
\begin{itemize}
\item \verb|node|: 包含的某个节点;
\item \verb|pkg|: 功能包;
\item \verb|type|: 被运行的节点文件;
\item \verb|name|: 为节点命名;
\item \verb|output|: 设置日志的输出目标;
\end{itemize}
\item 运行 launch 文件;
\begin{bash}
roslaunch 包名 launch文件名
\end{bash}
运行结果: 一次性启动了多个节点.
\end{itemize}
\section{ROS架构}
\subsection{ROS文件系统}
ROS 文件系统级指的是在硬盘上 ROS 源代码的组织形式, 其结构大致可以如下图所示:
\begin{figure}[!ht]
\centering
\includegraphics[width=.8\textwidth]{ros_file_system.jpg}
\caption{ROS文件系统}
\label{fig:ros_file_system}
\end{figure}
\begin{bash}
WorkSpace --- 自定义的工作空间
|--- build: 编译空间, 用于存放 CMake 和 catkin 的缓存信息、配置信息和其他中间文件.
|--- devel: 开发空间, 用于存放编译后生成的目标文件, 包括头文件、动态&静态链接库、可执行文件等.
|--- src: 源码
|-- package: 功能包 (ROS基本单元)包含多个节点、库与配置文件, 包名所有字母小写, 只能由字母、数字与下划线组成
|-- CMakeLists.txt 配置编译规则, 比如源文件、依赖项、目标文件
|-- package.xml 包信息, 比如:包名、版本、作者、依赖项等等 (以前版本是 manifest.xml)
|-- scripts 存储python文件
|-- src 存储C++源文件
|-- include 头文件
|-- msg 消息通信格式文件
|-- srv 服务通信格式文件