




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
機器人操作系統(ROS)機器人操作系統(ROS)ROS初識1.1機器人操作系統(ROS)1.1.1ROS是什么ROS是機器人操作系統(RobotOperatingSystem)的英文縮寫。ROS起源于2007年斯坦福大學人工智能實驗室的STAIR項目與機器人技術公司WillowGarage的個人機器人項目(PR)之間的合作,2008年之后就由WillowGarage來進行推動。最初人們希望設計一個可以像人一樣能夠感知,并實現自我控制從而完成一些復雜工作的機器人。隨著機器人領域的快速發展,代碼的復用性和模塊化的需求原來越強烈,急需一個能夠整合現有資源的框架和接口。2010年WillowGarage公司發布了開源機器人操作系統ROS,很快在機器人研究領域展開了學習和使用ROS的熱潮。ROS起源發展機器人操作系統(ROS)1.1.1ROS是什么ROS是用于機器人編程的開放、靈活的軟件框架。它提供類似操作系統所提供的功能,包含硬件抽象描述、底層驅動程序管理、共用功能的執行、程序間的消息傳遞、程序發行包管理等,它也提供一些可視化和調試機器人數據的軟件工具。ROS框架的核心是消息傳遞,即使在不同的機器上運行,進程之間也可以相互通信和交換數據。ROS消息傳遞可以是同步的,也可以是異步的。事實上,ROS的主要目的就是為機器人研究和開發提供代碼復用的支持。ROS是一種分布式處理框架,這使可執行文件能被單獨設計,并且在運行時松散耦合。這些過程可以封裝到數據包(Packages)和堆棧(Stacks)中,以便于共享和分發。ROS還支持代碼庫的聯合系統,使得協作亦能被分發。上述所有功能都能由ROS的基礎工具實現。設計者將ROS表述為“ROS=Plumbing+Tools+Capabilities+Ecosystem”,即ROS是通訊機制、工具軟件包、機器人高層技能以及機器人生態系統的集合體。ROS的表述機器人操作系統(ROS)1.1.2ROS的特點點對點的設計:節點是ROS編程基礎中一個重要的概念,在ROS中每個進程都以一個節點的形式運行,可以分布于多個不同的主機。節點間的消息通過一個帶有發布和訂閱功能的傳輸系統從發布節點傳送到接收節點。這種點對點的設計可以分散實現復雜功能時帶來的實時計算的壓力。多語言支持:為了支持更多應用的移植和開發,ROS通信框架可以輕松地以各種現有的編程語言實現。ROS中使用簡潔、中立的定義語言描述模塊之間的消息接口,同時也允許消息接口的嵌套使用。目前已經支持Python、C++、Java、Octave和LISP等多種不同的語言。庫集成:ROS具有許多第三方機器人庫的接口,如開源計算機視覺(Open-CV)、點云庫(PCL)、Open-NI、Open-Rave和Orocos。開發人員可以沒有顧慮的使用這些庫。組件化工具包豐富:ROS可采用組件化方式集成一些工具和軟件到系統中并作為一個組件直接使用,如RVIZ(3D可視化工具),開發者根據ROS定義的接口在其中顯示機器人模型等,組件還包括仿真環境和消息查看工具等。協作開發:ROS是開源的,遵照的BSD許可給使用者較大的自由,允許修改和重新發布其中的應用代碼,開發人員可以通過添加功能包來擴展ROS的功能。幾乎所有的ROS包都在硬件抽象層上工作,可以輕松地為其他機器人所用。機器人操作系統(ROS)1.1.3ROS的發行版ROS的發行版本ROS發行版是一組版本化的ROS包,這些類似于Linux發行版(例如Ubuntu)。ROS發行版的目的是讓開發人員在相對穩定的代碼庫上工作,直到他們準備好推進所有事情。因此,一旦發布發行版,我們就會嘗試限制對核心包(ros-desktop-full下的所有內容)的錯誤修復和非破壞性改進的更改。到2022年為止,ROS已經發布了如表1-1所示的多個版本。本書選擇的ROS版本是2018年發布的長期支持版本ROSMelodicMorenia,這也是ROS發布的第12個版本,ROS官方稱將為該版本提供長達5年的支持與服務,并保證其與Ubuntu18.04長期支持版的生命周期同步。機器人操作系統(ROS)本書的ROS資源1.2機器人操作系統(ROS)1.2本書的ROS資源本書涉及到的代碼以及相關資料均放在GitHub中托管,鏈接:/FieldRoboticsLaboratory/ROS_book可以使用以下命令下載源碼以開始后續的學習。$gitclone/FieldRoboticsLaboratory/ROS_book.git機器人操作系統(ROS)本章小結1.3機器人操作系統(ROS)1.3本章小結本章介紹了ROS的起源背景、設計目的和框架特點。本書還提供所有實踐的源碼,可以幫助讀者用ROS搭建豐富的機器人應用功能。機器人操作系統(ROS)機器人操作系統(ROS)編程基礎知識2機器人操作系統(ROS)2.編程基礎知識在整個機器人行業中,程序是連接機器人與人的中間橋梁。通過程序,人才能夠讓機器人從裝飾品變成生產工具。在當今機械控制日漸自動化與智能化的大趨勢下,一段程序的優劣對整個生產過程顯得尤為重要,任何涉及到自動控制或是智能控制的領域都離不開程序的編寫。而編程語言作為編寫程序的工具,是搭建中間橋梁的橋墩。專注于機器人控制的ROS平臺自然也是離不開編程語言的。相較于其他編程語言,在ROS中使用的編程語言主要是C++和Python,因此我們將通過兩個章節的篇幅為讀者簡單介紹這兩種編程語言及其最重要的特點。建議有C++與Python基礎的讀者也仍然閱讀一下這兩部分,熟悉一下這兩種語言在ROS中的運用。本章首先簡單介紹C++,主要講解C++最重要的一些基礎概念以及C++基本使用方法,然后介紹Python的相關知識和使用方法。機器人操作系統(ROS)2.1面向對象編程(object-orientedprogramming)與C++簡介首先我們先來描述一下面向過程編程與面向對象編程的區別。面向過程程序的控制流程由程序中預定順序來決定;面向對象程序的控制流程由運行時各種事件的實際發生來觸發,而不再由預定順序來決定,更符合實際需要。打個比方,假如我們要設計一款圍棋游戲,如果使用面向過程語言,那么我們的編程思路就應當是第一步白棋可以下在哪里,結束以后第二步由黑棋來下,可以下在哪里,每一步下完之后判斷是否有圍殺或是勝敗,以此類推。可以見得,如果將存在棋盤下滿和棋的情況考慮在內,那么就會需要許多行代碼去完成這個游戲的開發。而換成面向對象編程,我們的編程思路就會轉換成,白棋作為一個模塊,編寫好白棋的使用程序,黑棋作為一個模塊,由另一個人完成黑棋的使用程序,兩者再結合勝敗判定程序即可完成,將一整個連續性的程序框架拆解成各個模塊,這就是面向對象編程。接下來在介紹C++前,我們先對C++的基礎C語言做一個簡單概括。C語言是面向過程的結構化和模塊化的語言。在處理較小規模的程序時,程序員用C語言較為得心應手。但是當問題比較復雜、程序的規模比較大時,結構化程序設計方法就顯出它的不足。C程序的設計者必須細致地設計程序中的每一個細節,準確地考慮程序運行時每一時刻發生的事情,例如各個變量的值是如何變化的,什么時候應該進行哪些輸入,在顯示器上應該輸出什么等,如上一段所舉的圍棋例子。這對程序員的要求是比較高的,如果面對的是一個復雜問題,程序員往往感到力不從心。當初提出結構化程序設計方法的目的是解決軟件設計危機,但是這個目標并未完全實現。機器人操作系統(ROS)2.1面向對象編程(object-orientedprogramming)與C++簡介而C++正是為了解決這個問題而從C語言的基礎上改進出來的編程語言。在20世紀80年代提出了面向對象的程序設計(object-orientedprogramming,面向對象編程)思想,這就需要設計出能支持面向對象的程序設計方法的新語言。Smalltalk就是當時問世的一種面向對象的語言。而在實踐中,人們發現由于C語言是如此深入人心,使用如此廣泛,以至最好的辦法不是另外發明一種新的語言去代替它,而是在它原有的基礎上加以發展。在這種形勢下,C++應運而生,并且在C的后面添加自加符號++來表示這是C語言的增強版,我們也可以稱C++為帶類的C語言。由于C++面向對象編程的便捷性更加符合機器人開發的要求,因此ROS作為以普適性為目的的機器人平臺自然也就將C++作為主要的編程語言之一。接下來就將為讀者介紹一些C++編程語言的基礎知識。機器人操作系統(ROS)2.2在Linux中使用C++UbuntuLinux系統自帶一個內置的C/C++編譯器,叫做GCC/G++。GCC即為GNUCompilerCollection,譯為GNU編譯器套件,它包括C、C++、Objective-C、Fortran、Ada和Go的編譯器,以及這些語言的庫。GCC是RichardStallman為GNU項目(/gnu/thegnuproject)編寫的。本章代碼需要在電腦中預裝Linux系統才能運行,請讀者參考第五章內容,安裝相應版本的ubuntu系統或虛擬機。機器人操作系統(ROS)2.2.1GCC和G++編譯器介紹讓我們從GCC/G++編譯器開始認識C++。最新的UbuntuLinux系統預裝了C和C++編譯,其中C語言的編譯器是GCC,C++的編譯器是G++。。在桌面或是文件夾空白處右擊,然后選中在終端中打開,或是使用快捷鍵Ctrl+Alt+t,即可打開一個終端。終端(Terminal)也是Linux系統操作的重要工具,希望讀者可以牢記該操作,以方便之后的學習使用。在打開的終端中先輸入gcc然后回車,接著再輸入g++然后回車,出現的界面如圖所示。機器人操作系統(ROS)2.2.1GCC和G++編譯器介紹讓我們從GCC/G++編譯器開始認識C++。最新的UbuntuLinux系統預裝了C和C++編譯,其中C語言的編譯器是GCC,C++的編譯器是G++。。在桌面或是文件夾空白處右擊,然后選中在終端中打開,或是使用快捷鍵Ctrl+Alt+t,即可打開一個終端。終端(Terminal)也是Linux系統操作的重要工具,希望讀者可以牢記該操作,以方便之后的學習使用。在打開的終端中先輸入gcc然后回車,接著再輸入g++然后回車,出現的界面如圖所示。如果沒有得到圖2-1中的信息,則代表系統沒有預裝這些編譯器,可以使用Linux系統中安裝軟件的apt-get命令來安裝這些編譯器,下一小節我們將進行詳細介紹。機器人操作系統(ROS)2.2.2安裝C/C++編譯器首先,需要打開終端并使用如下命令從軟件庫中更新Ubuntu軟件包列表:$sudoapt-getupdate然后安裝C/C++編譯器需要的兩個依賴包:$sudoapt-getinstallbuild-essentialmanpages-devbuild-essential包和許多其他基礎包有關,它們共同用于UbuntuLinux中的軟件開發。最后安裝C/C++編譯器,指令如下:$sudoapt-getinstallgccg++機器人操作系統(ROS)2.2.3驗證安裝安裝完前面的包之后,可以在終端中使用如下指令查看編譯器的安裝路徑、使用說明頁:$whereisgcc$whereisg++使用下面命令可以查看GCC編譯器的版本號:$gcc--version$g++--version下圖顯示了以上命令的輸出。機器人操作系統(ROS)2.2.4GNU項目調試器GDB簡介下面我們看一看C/C++的調試器。什么是調試器呢?調試器是一個可以運行和控制另一個程序的程序,通過檢查每一行代碼來檢查程序的問題或bug。UbuntuLinux自帶一個名為GNUDebugger的調試器,簡稱GDB(/software/gdb/),它是Linux系統中最流行的C和C++程序調試器之一。機器人操作系統(ROS)2.2.5在UbuntuLinux中安裝GDB最新版本的Ubuntu中已經安裝了GDB。如果用戶正在使用其他版本,可以使用如下命令安裝GDB:$sudoapt-getinstallgdb機器人操作系統(ROS)2.2.6驗證安裝可以使用如下命令檢查GDB是否已經準確安裝在計算機中:$gdb如果安裝成功,則會顯示圖中的信息。機器人操作系統(ROS)2.2.6驗證安裝圖的界面中,可以發現最后一行并不是正常終端操作命令執行后的初始行,也就是并沒有出現之前操作命令回車執行后界面中綠色字體的標識符。這是因為當前操作命令仍然在執行,并沒有結束,此時讀者輸入quit并敲擊回車結束gdb命令的執行,如圖所示。在下一小節中,我們將在Ubuntu中編寫我們的第一個c++代碼,然后編譯并調試它,以找到代碼中的錯誤。機器人操作系統(ROS)2.2.7編寫第一行代碼下面我們開始在UbuntuLinux中編寫第一個程序。用戶可以使用Ubuntu中的gedit,或nano終端文本編輯器來編寫代碼。gedit是ubuntu中一個常用的GUI文本編輯器,更加符合長期使用Windows系統下的Office操作模式的人的使用習慣,因此這里我們使用gedit來編寫UbuntuLinux中的第一條程序代碼。在Ubuntu搜索中查找gedit(見圖),然后單擊打開該文本編輯器。機器人操作系統(ROS)2.2.7編寫第一行代碼或者也可以在終端中直接輸入gedit然后敲擊回車打開gedit,如圖所示。可見終端在Linux系統中的重要性,為了養成習慣,建議讀者使用終端打開gedit。機器人操作系統(ROS)2.2.7編寫第一行代碼gedit文本編輯器打開后,可看到如圖所示的窗口。機器人操作系統(ROS)2.2.7編寫第一行代碼這個編輯器非常類似于Windows中的Notepad或者WordPad,頁面十分簡潔,除了少數幾個文件保存打開按鈕外就只有書寫界面,我們就將在這個文本編輯器中編寫第一個C++程序。將下列內容輸入到我們打開的gedit界面中:#include<iostream>usingnamespacestd;intmain(){cout<<”Nicetomeetyou,ROS.”<<endl;return0;}機器人操作系統(ROS)2.2.7編寫第一行代碼在文本編輯器中編寫完成后,保存為HelloROS.cpp。需要注意的是,這里的.cpp必須由讀者自己手動輸入,而不是像Windows中有下拉菜單可以選擇文件的保存格式,這也是Linux系統的文件命名特點。機器人操作系統(ROS)2.2.7編寫第一行代碼保存完畢后,我們可以發現gedit界面中我們剛才輸入的程序變成了彩色,如圖2-10所示,這就表明該文件已經被成功保存為.cpp格式。機器人操作系統(ROS)2.2.8解釋代碼HelloROS.cpp里代碼的功能是將消息“Nicetomeetyou,ROS.”打印到顯示器上。代碼中的第一行“#include<iostream>”是一個C++頭文件,其中包含的最常用的就是輸入/輸出函數,例如從鍵盤輸入一段字符或者將指定內容輸出到顯示器上的cin與cout函數就是最典型的代表。在這個程序中,我們只使用了cout函數來輸出消息,所以有iostream作為頭文件就足夠了。接下來的第二行則是聲明了使用namespacestd即命名空間。命名空間(/namespacc/)是C++中的一個特性,用于對一組實體進行分組。iostream庫中使用std定義命名空間。當我們使用命名空間namespacestd時,我們可以訪問std命名空間中包含的所有函數或其他實體,例如cout和cin等函數。如果我們不使用這行代碼,則必須在函數前面添加std::用于訪問該名字空間中的函數;例如,std::cout是一個打印消息的函數。在討論了頭文件和其他代碼之后,我們可以討論主函數中包含的內容了。我們使用cout<<"Nicetomeetyou,ROS."<<endl打印出一條消息。endl表明在打印消息后換行,消息打印完畢后,函數返回0并退出程序。在本章稍后的小節中我們會更加詳細地分析C++的一些基礎知識在ROS中的使用。機器人操作系統(ROS)2.2.9編譯代碼保存代碼之后,我們的.cpp文件仍然只是個文本文檔,并不是可執行的程序,因此需要對這個文檔進行編譯,將里面的代碼生成可執行文件。下面的例程將幫助各位讀者完成代碼編譯的步驟。可以重新打開一個新終端,并使用如下命令將終端路徑切換到保存代碼的文件夾下。在本例中,我們將代碼保存到/home/桌面文件夾中。在終端中使用如下命令切換目錄和代碼編譯,編譯結果如圖所示:$cd桌面$g++HelloROS.cpp機器人操作系統(ROS)2.2.9編譯代碼在當前文件夾中可以看到生成了一個新的文件a.out,這是編譯生成的可執行文件,文件名稱由系統默認生成,如需生成特定名稱的可執行文件,我們可以使用如下指令:$g++HelloROS.cpp-ohello_ROS此時在文件夾中就會生成hello_ROS.out的可執行文件。如圖所示:機器人操作系統(ROS)2.2.9編譯代碼在終端中輸入以下命令運行生成好的可執行文件:$./hello_ROS此時顯示器上會輸出“Nicetomeetyou,ROS”的字符串,表示程序運行成果,如圖2-13所示:機器人操作系統(ROS)2.2.10調試代碼使用調試器,可以遍歷每一行代碼并檢查每個變量的值。將下面的代碼按照之前的方法通過gedit來生成相應的.cpp文件,輸入代碼后保存為SUM.cpp文件。#include<iostream>usingnamespacestd;intmain(){intNum1=1;intNum2=2;intSum=Num1+Num2;cout<<”Sum=”<<Sum<<endl;return0;}機器人操作系統(ROS)2.2.10調試代碼生成.cpp文件后就要對進行編譯了,而為了要調試/檢查每一行代碼,我們編譯的時候必須使用調試符號編譯代碼,并使其能適用于GDB調試。具體的編譯命令如下:$g++-gSUM.cpp-oSUM編譯后,可以通過運行命令$./SUM執行它。運行結果如圖所示。機器人操作系統(ROS)2.2.10調試代碼可執行文件創建成功之后,可以通過以下的命令對其進行調試:$gdbSUM其中,SUM是可執行文件的名稱,輸入命令后,需使用GDB的操作指令進行代碼調試。以下是常用的幾個GDB命令,具體解釋如下:?bline_numer:在給定行號處創建斷點。在調試時,調試器會在這個斷點處停止。?n:運行下一行代碼。?r:運行程序到斷點位置。?pvariable_name:打印變量的值。?q:退出調試器。讓我們來嘗試一下這些命令,每個命令的輸出結果如圖所示。機器人操作系統(ROS)2.2.10調試代碼接下來就要介紹C++最大的特點,面向對象編程,也是與C語言最大的區別。機器人操作系統(ROS)2.3從實例中學習C++中OOP的概念如果用戶已經知道C的結構體,那么了解OOP概念將不會花費太多時間。在C的結構體中,我們可以將不同的數據類型(如整數、浮點數和字符串)封裝到一個用戶定義的數據類型中。與C的結構體類似,C++有一個增強版的結構體,它增加了定義函數的功能。這個增強版本的結構體稱為C++類。C++類的每個實例都被稱為對象。對象只是實際類的一個副本。有幾個與對象相關的屬性,稱為面向對象編程概念。接下來我們用C++代碼解釋主要的OOP概念。機器人操作系統(ROS)2.3.1類和結構體之間的區別在學習OOP概念之前,讓我們先來看看結構體和類之間的區別。首先創建名為class_struct.cpp的示例代碼文件,將如下內容添加到文件中:#include"iostream"
#include"string"
usingnamespacestd;
structRobot_Struct
{
intid;
intno_wheels;
stringrobot_name;
};
classRobot_Class
{
public:
intid;
intno_wheels;
stringrobot_name;
voidmove_robot();
voidstop_robot();
};
voidRobot_Class::move_robot()
{
cout<<"MovingRobot!"<<endl;
}
voidRobot_Class::stop_robot()
{
cout<<"StoppingRobot!"<<endl;
}
intmain()
{
Robot_Structrobot_1;
Robot_Classrobot_2;
robot_1.id=2;
robot_1.robot_name="Mobilerobot";
robot_2.id=3;
robot_2.robot_name="NoWheelsrobot";
cout<<"ID="<<robot_1.id<<"\t"<<"RobotName="<<robot_1.robot_name<<endl;
cout<<"ID="<<robot_2.id<<"\t"<<"RobotName="<<robot_2.robot_name<<endl;
robot_2.move_robot();
robot_2.stop_robot();
return0;
}機器人操作系統(ROS)2.3.1類和結構體之間的區別這段代碼定義了一個類和結構體。結構體名稱是Robot_struct,類名是Robot_Class。下面部分展示了如何定義一個結構體。該結構體定義了若干變量,比如機器人的編號id、名稱robot_name和輪子的數量no_wheels。structRobot_Struct
{
intid;
intno_wheels;
stringrobot_name;
};機器人操作系統(ROS)2.3.1類和結構體之間的區別如大家所知,每個結構體都有一個名字,所有變量的聲明都在里面。下面部分是類的定義:classRobot_Class{public:intid;intno_wheels;stringrobot_name;voidmove_robot();voidstop_robot();};機器人操作系統(ROS)2.3.1類和結構體之間的區別所以,這兩者之間到底有什么區別呢?結構體只能定義不同的成員變量,但是類除了可以定義多個成員變量之外還可以聲明不同成員函數。那么每個函數定義在哪里呢?我們可以在類的內部或外部定義函數。標準的做法是在類的外部定義函數,以保證類定義的簡潔性。下面的程序顯示了類中所聲明的函數在類外部的定義。voidRobot_Class::move_robot(){cout<<"MovingRobot!"<<endl;}voidRobot_Class::stop_robot(){cout<<"StoppingRobot!"<<endl;}機器人操作系統(ROS)2.3.1類和結構體之間的區別在函數定義中,第一項是返回數據的類型,然后是類名,再然后是用::連接的函數名。表明函數是包含在類中的。在函數定義中,我們可以輸入我們的代碼,函數中這段特定的代碼打印了一條信息。你已經看到類的函數定義。下一步是學習如何讀/寫變量和使用函數。機器人操作系統(ROS)2.3.2C++的類和對象本節將解釋如何讀/寫結構體和類中的變量。下面程序是創建結構體和類的代碼:Robot_Structrobot_1;Robot_Classrobot_2;robot_1.id=2;robot_1.robot_name="Mobilerobot";robot_2.id=3;robot_2.robot_name="NoWheelsrobot";機器人操作系統(ROS)2.3.2C++的類和對象與結構體實例類似,我們可以創建一個類的實例,稱之為對象。讓我們來看看Robot_Classrobot_2;在這里,robot_2是一個對象,而robot1是結構體的一個實例。使用這個實例或對象,我們可以訪問每一個變量和函數。我們可以使用.操作符去訪問每一個變量。結構體和類中的變量都可以使用.操作符進行訪問。如果是使用結構體或類的指針,則必須使用->操作符來訪問每個變量。如下所示:Robot_Class*robot_3;robot_3=newRobot_Class;robot_3->id=4;robot_3->robot_name="Rosrobot";機器人操作系統(ROS)2.3.2C++的類和對象其中,new操作符為C++變量分配內存。我們可以使用操作符調用類中的函數和打印變量,程序如下所示:cout<<"ID="<<robot_1.id<<"\t"<<"RobotName="<<robot_1.robot_name<<endl;cout<<"ID="<<robot_2.id<<"\t"<<"RobotName="<<robot_2.robot_name<<endl;robot_2.move_robot();robot_2.stop_robot();機器人操作系統(ROS)2.3.2C++的類和對象我們使用命令$g++class_struct.cpp-oclass_struct和$./class_struct編譯它。圖2-16顯示了這段代碼的輸出。可訪問/cplusplus/cpp_classes_objects.htm,以便進一步參考。機器人操作系統(ROS)2.3.3類訪問修飾符在類中,用戶也許已經看到了一個叫做public:的關鍵字,它被稱為成員訪問限定符。下面代碼部分是使用訪問修飾符的代碼。classRobot_Class{public:intid;intno_wheels;...};機器人操作系統(ROS)2.3.3類訪問修飾符這一功能也稱為數據隱藏,通過設置成員訪問修飾符,我們可以限制在類內部定義的函數的使用范圍。類中有三種訪問修飾符:public:一個public成員可以從類之外的任何地方訪問。我們可以直接訪問公共變量,而不需要編寫其他輔助函數。private:使用該修飾符號的成員變量或函數,不能從類外部被查看或訪問。只有類和友元函數可以訪問私有成員。protected:訪問非常類似于private成員,但是不同的是它的子類可以訪問其成員。子類/派生類的概念將在下一節進行討論。訪問修飾符可以幫助你將變量分組,這些變量可以在類中保持可見或隱藏。機器人操作系統(ROS)2.3.4C++中繼承的使用繼承(Inheritance)是OOP中的另一個重要概念。如果你有兩個或多個類,并且希望在一個新類中擁有這些類中的函數,那么可以使用繼承屬性。通過使用繼承屬性,你可以在新類中重用現有類中的函數。我們將要繼承現有類的新類稱為派生類,已有的類稱為基類。類可以通過public、private或protected來繼承。下面將解釋每種繼承類型。publicinheritance:當我們派生自public基類時,基類的public成員成為派生類的public成員,并且基類的protected成員成為派生類的protected成員。基類的private成員不能在派生類中訪問,但可以通過對基類的public和protected成員函數的調用來訪問。protectedinheritance:當我們使用protected基類繼承時,基類的public和protected成員成為派生類的protected成員。privateinheritance:當我們派生自private基類時,基類的public和protected成員成為派生類的private成員。機器人操作系統(ROS)2.3.4C++中繼承的使用我們創建一個public繼承的簡單示例代碼class_inheritance.cpp,并填入如下內容:#include<iostream>#include<string>usingnamespacestd;classRobot_Class{public: intid; intno_wheels; stringrobot_name; voidmove_robot(); voidstop_robot();};classRobot_Class_Derived:publicRobot_Class{public: voidturn_left(); voidturn_right();};voidRobot_Class::move_robot(){ cout<<"MovingRobot"<<endl;}voidRobot_Class::stop_robot(){ cout<<"StoppingRobot"<<endl;}voidRobot_Class_Derived::turn_left(){ cout<<"RobotTurnleft"<<endl;}voidRobot_Class_Derived::turn_right(){ cout<<"RobotTurnRight"<<endl;}intmain(){ Robot_Class_Derivedrobot; robot.id=2; robot.robot_name="Mobilerobot"; cout<<"RobotID="<<robot.id<<endl; cout<<"RobotName="<<robot.robot_name<<endl; robot.move_robot(); robot.stop_robot(); robot.turn_left(); robot.turn_right(); return0;}機器人操作系統(ROS)2.3.4C++中繼承的使用在本例中,我們創建了一個名為Robot_Class_Derived的新類,它派生自一個名為Robot_Class的基類。公共繼承是通過使用public關鍵字加后邊的基類名實現的,即在派生類名之后緊接著是一個public關鍵字和一個基類名。classRobot_Class_Derived:publicRobot_Class{public: voidturn_left(); voidturn_right();};機器人操作系統(ROS)2.3.4C++中繼承的使用Robot_Class在這種情況下,如果選擇公共繼承,則可以訪問基類的public和protected修飾的變量和函數。我們使用的類與第一個示例中使用的類相同。派生類中每個函數的定義如下所示:voidRobot_Class_Derived::turn_left(){ cout<<"RobotTurnleft"<<endl;}voidRobot_Class_Derived::turn_right(){ cout<<"RobotTurnRight"<<endl;}機器人操作系統(ROS)2.3.4C++中繼承的使用現在讓我們看看如何訪問派生類中的函數:Robot_Class_Derivedrobot; robot.id=2; robot.robot_name="Mobilerobot"; cout<<"RobotID="<<robot.id<<endl; cout<<"RobotName="<<robot.robot_name<<endl; robot.move_robot(); robot.stop_robot(); robot.turn_left(); robot.turn_right();機器人操作系統(ROS)2.3.4C++中繼承的使用在這里,我們創建了一個名為“robot”的“Robo_Class_Derived”對象。如果用戶仔細閱讀代碼,便可以理解,在Robo_Class_Derived中,我們沒有聲明id和robot_name變量,它是在Robo_Class中定義的。通過使用inheritance屬性,我們可以在派生類Robo_Class_Derived中訪問Robo_Class的變量。下面讓我們看一下代碼的輸出,通過使用下面的命令來編譯class_inheritance.cpp文件:$g++class_inherit.cpp-oclass_inherit$./class_inherit這將得到如圖2-17所示的輸出,沒有顯示任何錯誤。這意味著此公共繼承運行良好。機器人操作系統(ROS)2.3.4C++中繼承的使用根據輸出可以觀察到,我們從基類和派生類中定義的函數中獲取了所有消息。此外,我們還可以訪問基類變量并設置它的值我們已經介紹了一些重要的OOP概念。如果需要了解更多的概念,請參考/cplusplus.機器人操作系統(ROS)2.3.5C++文件和流下面讓我們來一起討論C++中的文件操作以及文件讀寫。我們已經討論了用于執行文件操作的iostream頭文件,我們還需要另一個標準的C++庫fstream。在fstream中有以下三種數據類型。ofstream:表示輸出文件流。它用于創建文件并將數據寫入其中。ifstream:表示輸入文件流。它用于從文件中讀取數據。fstream:同時具有讀/寫能力。機器人操作系統(ROS)2.3.5C++文件和流下面代碼展示了如何使用C++函數讀/寫文件:#include<iostream>#include<fstream>#include<string>usingnamespacestd;intmain(){ ofstreamout_file; stringdata="Robot_ID=0"; cout<<"Writedata:"<<data<<endl; out_file.open("Config.txt"); out_file<<data<<endl; out_file.close(); ifstreamin_file; in_file.open("Config.txt"); in_file>>data; cout<<"Readdata:"<<data<<endl; in_file.close(); return0;}機器人操作系統(ROS)2.3.5C++文件和流代碼必須包含fstream頭,以獲得C++中的讀/寫數據類型。我們已經創建了一個ofstream類對象,其中包含一個名為open()的函數,用于打開文件。打開文件后,我們可以使用<<運算符對其進行寫入。寫完數據后,我們關閉文件為讀取操作做準備。為了讀入數據,我們在C++中使用ifstream類對象,并使用ifstream類中的open(“file_name”)函數打開文件。打開文件后,我們可以使用>>操作符從文件中讀取數據。讀取完畢后,在終端中打印。我們要寫的文件名是Config.txt并且數據是一個機器人相關的參數。圖2-18顯示了編譯并運行代碼后的輸出結果。你可以看到Config.txt已經在桌面文件夾中被創建了出來。相關詳細信息,請訪問/cplusplus/cpp_files_streams.htm。機器人操作系統(ROS)2.3.6C++中的命名空間在此之前,HelloWorld代碼中提到了命名空間的概念。在本節中,你將學習如何創建、在何處使用以及如何訪問命名空間。下面代碼提供了一個創建和使用兩個命名空間的示例:#include<iostream>usingnamespacestd;namespacerobot{ voidprocess(void) { cout<<"ProcessingbyRobot"<<endl; }}namespacemachine{ voidprocess(void) { cout<<"ProcessingbyMachine"<<endl; }}intmain(){ robot::process(); machine::process();}機器人操作系統(ROS)2.3.6C++中的命名空間創建命名空間時,要使用關鍵詞namespace,后面緊跟這個命名空間的名字。其中我們定義了兩個命名空間。如果查看代碼,你會發現在每個命名空間里都定義了相同的函數。這些命名空間用來對實現某一特定操作的一系列函數或類進行分組。通過使用這個命名空間的名稱,后跟::加函數名的方式,我們可以訪問命名空間里的成員。在這段代碼中,我們在命名空間里調用了兩個函數,分別是robot和machine。圖展示了代碼里代碼的輸出。這段代碼被保存為namespace.cpp。更多的參考,可以訪問/cplusplus/cpp_exceptions_handling.htm。機器人操作系統(ROS)2.3.7C++的異常處理異常處理Exceptionhandling是C++中的的一種新特性,它可以用來處理當用戶輸入后產生非預期的輸出響應的情況。下面是C++異常處理特性的一個例子:#include<iostream>usingnamespacestd;intmain(){ try { intno_1=1; intno_2=0; if(no_2==0) { throwno_1; } }
catch(inte) { cout<<"Exceptionfound:"<<e<<endl; }}機器人操作系統(ROS)2.3.7C++的異常處理異常處理Exceptionhandling是C++中的的一種新特性,它可以用來處理當用戶輸入后產生非預期的輸出響應的情況。下面是C++異常處理特性的一個例子:#include<iostream>usingnamespacestd;intmain(){try{intno_1=1;intno_2=0;if(no_2==0) { throwno_1; }}
catch(inte){ cout<<"Exceptionfound:"<<e<<endl;}}機器人操作系統(ROS)2.3.7C++的異常處理我們主要用三個關鍵詞來處理異常情況。try:在try后面的測試塊中編寫可能會引發異常的代碼。catch:如果try后的測試塊中出現了異常,則catch后面的代碼塊會捕捉這個異常。然后我們可以決定如何處理這個異常情況。throw:當開始出現問題時,我們可以從測試塊中拋出一個異常。該異常可以被后邊的catch塊捕捉到。機器人操作系統(ROS)2.3.7C++的異常處理下面代碼展示了異常處理的基本結構:try{ //Ourcodesnippets}catch(Exceptionname){ //Exceptionhandlingblock}機器人操作系統(ROS)2.3.7C++的異常處理這個代碼是在查詢num_2是否為0。當num_2為0時,就會拋出一個由throw關鍵詞num_1引發的異常,然后catch塊會捕捉該異常并檢查num_1的值。圖展示了代碼編譯和輸出結果。我們可以在catch塊中打印異常值(也就是num_1的值,也就是1)。異常處理被廣泛地運用于簡單的程序調試。更多的參考,可以訪問/exception-handling-c/。機器人操作系統(ROS)2.3.8C++的標準模板庫如果你想使用一些數據結構,比如列表(list)、堆棧(stacks)、數組(arrays)等等,標準模板庫(StandardTemplateLibrary,STL)是最好的選擇。STL為計算機科學提供了多樣的標準算法的實現,比如排序和搜索,以及類似于向量、列表、隊列等數據結構。這是一個先進的C++概念,如果想瀏覽一下相關信息,可以訪問/the-c-standard-template-library-stl/。機器人操作系統(ROS)2.4建立一個C++工程現在你已經學習了一些重要的OOP概念,現在讓我們來看看如何建立C++工程。想象一下,你有成百上千個源代碼文件,而且你需要編譯、鏈接它們,你要如何處理?這一部分將討論這個問題。如果你想使用多個源代碼文件,需要使用下列工具來編譯、鏈接你的工程。Linuxmakefile可以非常方便的用來編譯一個或多個源文件,并生成可執行文件。讓我們通過一個簡單的工程來證明makefile的能力。我們將編寫一些代碼來對兩個數字求和,為此我們要先建立一個類。當編寫C++類的時候,我們可以和main函數一起在源文件中聲明和定義這個類。另外一種聲明和定義類的方式是使用.h文件和.cpp文件,然后把.h文件包含到main函數所在的源文件中。這種方法對整個項目的模塊化很有幫助。我們的工程包含三個文件。main.cpp:是我們將要構建的主要代碼。add.h:add類的頭文件,包含一個類的聲明。add.cpp:這個文件里含有類add的全部定義。最好將類、頭文件、.cpp文件用同一個名字命名。這里我們建立類add,所以頭文件名是add.h和add.cpp。機器人操作系統(ROS)2.4建立一個C++工程以下是add.h代碼:#include<iostream>classadd{public: intcompute(intno_1,intno_2);};以下是add.cpp代碼:#include"add.h"intadd::compute(inta,intb){ return(a+b);}機器人操作系統(ROS)2.4建立一個C++工程以下是main.cpp代碼:#include"add.h"usingnamespacestd;intmain(){ addobj; intresult=pute(43,34); cout<<"TheResult:="<<result<<endl; return0;}機器人操作系統(ROS)2.4建立一個C++工程在main.cpp中,我們首先通過包含add.h頭文件來訪問add類,然后創建了add類的一個對象,并將兩個數字傳遞給compute函數,最后打印結果。我們可以使用以下命令編譯并執行中的代碼,其輸出結果如圖所示。對于編譯單個源代碼,g++命令很容易使用,但是如果我們想要編譯若干個源代碼,那么g++命令就不那么方便了。Linuxmakefile則提供了一種組織、編譯多個源代碼文件的方法。下面部分將展示了如何通過編寫makefile文件來編譯代碼。機器人操作系統(ROS)2.4建立一個C++工程這部分是LinuxMakefile文件內容:CC=g++CFLAGS=-cSOURCES=main.cppadd.cppOBJECTS=$(SOURCES:.cpp=.o)EXECUTABLE=mainall:$(OBJECTS)$(EXECUTABLE)$(EXECUTABLE):$(OBJECTS) $(CC)$(OBJECTS)-o$@.cpp.o:*.h $(CC)$(CFLAGS)$<-o$@clean: -rm-f$(OBJECTS)$(EXECUTABLE).PHONY:allclean機器人操作系統(ROS)2.4建立一個C++工程上面代碼保存為makefile之后,我們必須執行以下命令來執行編譯。$make這樣就編譯了源代碼,如圖2-22所示。在使用make命令編譯之后,可以使用以下命令執行程序。結果如圖2-23所示:$./main你可以通過/cplusplus/gnumake.php了解更多關于makefile的信息機器人操作系統(ROS)2.4.2創建一個CMake文件CMake()是構建C++工程的另一種方法。CMake代表cross-platformmakefile。它是一個開源工具,可以跨操作系統編譯、測試和打包軟件。我們可以使用以下命令安裝CMake。$sudoapt-getinstallcmake安裝之后,需要將下面代碼保存為CMakeLists.txt:cmake_minimum_required(VERSION3.0)set(CMAKE_BUILD_TYPERelease)set(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS}-std=c++14")project(main)add_executable( main add.cpp main.cpp)機器人操作系統(ROS)2.4.2創建一個CMake文件這段代碼的意思一目了然,它僅僅設置了C++標志,并從源代碼add.cpp和main.cpp中創建了一個名為main的可執行文件。CMake命令的使用說明可以在/documentation/中找到。將上述命令保存為CMakeLists.txt之后,我們還需要創建一個用于構建工程的文件夾。你可以為文件夾選擇任何名稱。在這里,我們使用build作為該文件夾的名稱。$mkdirbuild在創建文件夾之后,切換到build文件夾并在當前文件夾中打開終端,并在該路徑下執行以下命令。$cmake..機器人操作系統(ROS)2.4.2創建一個CMake文件此命令會解析工程路徑中的CMakeLists.txt,然后將CMakeLists.txt轉換為makefile,這樣我們就可以通過makefile進行編譯了。基本上可以說,它使編寫Linuxmakefile的過程變的自動化了。如果在執行cmake..命令之后一切都成功,你應該得到如圖1所示的消息。在這之后,你可以通過輸入make指令($make)來編譯工程。如果成功的話,項目就可以被執行了($./main)。圖2展示了make指令和運行可執行文件的輸出。機器人操作系統(ROS)2.5Python簡介Python和C++一樣,也是一門面向對象的解釋型計算機程序設計語言,由荷蘭人GuidovanRossum于1989年發明。Python具有豐富和強大的庫,它常被昵稱為膠水語言,能夠把用其他語言制作的各種模塊(尤其是C/C++)很輕松地聯結在一起。它是一門跨平臺、開源、免費的解釋型高級動態編程語言,和C++最大的區別就是,Python是一門解釋型語言,而C++是一門編譯型語言。解釋型語言指的是程序不需要編譯,程序在運行時才翻譯成機器語言,每執行一次都要翻譯一次,因此效率比較低。比如Basic語言,專門有一個解釋器能夠直接執行Basic程序,每個語句都是執行的時候才翻譯。而編譯型語言程序在執行之前需要一個專門的編譯過程,把程序編譯成為機器語言的文件,運行時不需要重新翻譯,直接使用編譯的結果就行了。相比較之下,使用解釋型語言進行程序編寫時更符合人本身的語言習慣,這也是Python成為ROS程序編寫熱門語言的一大重要原因。機器人操作系統(ROS)2.6.1Linux中的Python解釋器與GNUC/C++編譯器一樣,Python解釋器也預裝在Ubuntu中。使用所示的命令$python可以查看系統默認的Python解釋器版本。圖2-26展示了系統默認的Python解釋器的版本。機器人操作系統(ROS)2.6.1Linux中的Python解釋器可以看到,當前默認的Python版本是2.7.12。在輸入Python命令后通過按兩次Tab鍵,還可以獲得已安裝的Python版本的列表。圖2-27顯示了Ubuntu中可用的Python版本列表。機器人操作系統(ROS)2.6.1Linux中的Python解釋器在這里,你可以看到若干個Python命令,它們分別服務于兩個不同的版本2.7.12和3.5.2。Python、Python2和Python2.7命令用于啟動2.7.12版本,其余的命令則用于啟動3.5.2版本。Python3m和Python3.5m是帶有pymalloc的版本,它比使用malloc的默認內存分配性能更好。如前所述,Python在Ubuntu中是預裝的,除此之外,也可以通過下面的命令手動安裝相應版本的Python解釋器:$sudoapt-getinstallPythonPython3機器人操作系統(ROS)2.6.2驗證Python的安裝本節展示如何查看Python可執行路徑和版本。下面是查看Python和Python3命令的當前路徑的兩條命令。$whichPython$whichPython3顯示結果如圖所示。機器人操作系統(ROS)2.6.2驗證Python的安裝如果讀者想查看Python二進制文件、源文件和文檔的位置,則可以使用以下兩條命令。$whereisPython$whereisPython3.5顯示結果如圖2-29所示。機器人操作系統(ROS)2.6.3編寫第一條Python程序我們的第一個程序同樣將打印一個“Nicetomeetyou,ROS.”消息,讓我們看看如何使用Python實現它。在開始編程之前,我們需要首先了解一下Python編程的兩種方式。(1)在Python解釋器中直接編程;(2)編寫Python腳本并使用解釋器運行;這兩種方法以相同的方式工作。第一個方法中的代碼在解釋器中逐行執行。編寫腳本的方法則要求在文件中寫入所有代碼,然后再使用解釋器執行。首先我們在命令行中用Python解釋器打印“Nicetomeetyou,ROS.”消息,如圖3-5所示。機器人操作系統(ROS)2.6.3編寫第一條Python程序從圖2-30可以看出,用Python輸出消息非常容易,只需輸入print語句和被打印的消息數據,然后按回車鍵即可,如下所示:>>>print'Nicetomeetyou,ROS.'如果你在Python3.0以上的版本中執行HelloWorld程序,那么需要對Python語句做一些更改。Python3.x和2.x的主要的差別可以在https://wiki.P/moin/Python2orPython3中找到。與Python2.x中使用的print語句不同,在Python3.x中使用下面的語句來打印消息,運行結果如圖2-31所示:>>>print('Nicetomeetyou,ROS.')機器人操作系統(ROS)2.6.3編寫第一條Python程序下面介紹在腳本中編寫Python程序。使用腳本時,我們將代碼寫入擴展名為.py的文件中。編寫Python代碼的標準方法請參見www.P/dev/peps/pep-0008/。與創建C++可執行文件類似,我們將先創建一個名為HelloROS.py的文件,并在文件中編寫代碼,具體內容如下:#!/usr/bin/envpython#-*-coding:utf-8-*-print‘Nicetomeetyou,ROS.’其中的第一行“#!/usr/bin/envPython”稱為Shebang。當我們執行Python代碼時,程序加載器將解析這一行命令并使用該語句指定的執行環境來執行代碼。這里我們將Python設置為執行環境,因此其余代碼將在Python解釋器中執行。接下來讓我們看一下如何執行上述代碼。機器人操作系統(ROS)2.6.4運行Python代碼將hello_world.py保存到home文件夾或其他文件夾下。本書代碼的保存路徑是桌面文件夾,因此我們需把路徑切換到桌面文件夾下并用如下命令執行Python代碼。$pythonHello\ROS.py這里的腳本名稱因為含有空格所以需要加上轉義符號“\”。如果你的代碼沒有任何錯誤,它將顯示如圖2-32所示的輸出。機器人操作系統(ROS)2.6.4運行Python代碼還有另外一種方法可以執行Python文件。首先使用下面的命令向給定的Python代碼提供可執行權限。$chmoda+xHello\ROS.py然后使用以下命令執行Python代碼。$./Hello\ROS.py圖2-33展示了如何通過上述方式執行Python腳本。接下來我們將討論Python的基礎語法。這一話題涵蓋了很多內容,我們將通過具體的例子來討論其中的各個部分,以增加讀者的理解。機器人操作系統(ROS)2.7從實例中學習Python簡單易學是Python語言如此受歡迎的主要原因。因為Python的代碼很短,所以較之別的編程語言Python語言可以更快地幫助建立算法模型。也正是因為它如此受歡迎,所以網上有海量的Python教程資源和很多活躍的技術論壇,我們可以很容易的從中獲取到技術支持。Python還有非常多的庫函數來幫助你開發應用。Python庫的易獲得性,也是它優于別的語言的一個重要原因。有了Python庫,你就可以利用現有的函數來大幅的減少開發時間。Python還是一個跨平臺的語言,被廣泛應用于搜索、網絡、圖像、游戲、機器學習、數據科學以及機器人技術。很多公司都用這種語言來實現一些自動化任務,所以靠Python找份工作是比較容易的。那么學習這門語言有多難呢?如果你可以完成一項偽代碼的編寫任務,那就可以用Python寫代碼,因為它跟偽代碼非常類似。機器人操作系統(ROS)2.7.1Python中有哪些新東西如果你學過C++,那學Python就比較簡單了,但是你在寫Python代碼時還得了解一些東西。靜態語言和動態語言Python是一個動態語言,也就意味著我們不必在編程中提供變量的數據類型,它把每個變量都看作一個對象。我們可以給一個名字指定任何數據類型。但在C++中,我們需要先給變量制定一個數據類型,然后只能將那一類型的數據賦值給這個變量。C++則是一個靜態類型的語言,比如在C++里我們可以這樣賦值:intnumber;number=10;//這個有效number="10"http://這個無效但在Python里,我們則可以這樣賦值:#無需考慮數據類型number=10#有效number="10"#也有效所以現在number的值是10。機器人操作系統(ROS)2.7.1Python中有哪些新東西代碼縮進縮進,就是在一行的開頭敲一個tab或是幾個空格。在C++里,我們可以使用縮進對代碼分塊,但這不是強制性的,即使我們沒有縮進也可以編譯。然而在Python里就不一樣了,我們必須保證各代碼塊有一樣的縮進,否則就會出現縮進的錯誤。當代碼縮進變成強制的之后,代碼看起來就會更整齊,可讀性也更好。分號在C/C++中,每個語句末尾的分號是強制性的,但是在Python中,它們不是強制性的。你可以在Python中使用分號作為分隔符,但不能作為終止符。例如,如果你想在一行中編寫一組代碼,你可以通過分隔分號來編寫它們。機器人操作系統(ROS)2.7.2Python變量現在你已經了解了Python如何處理變量。圖2-34便展示了如何在Python中給變量賦值并打印不同的原始數據類型,如int、float和string。這里我們用到的測試環境為Python2.7.12版本。機器人操作系統(ROS)2.7.2Python變量類似于C/C++中的數組,Python提供列表(lists)和元組(tuples)數據類型。列表中的值可以通過使用方括號([])的列表索引進行訪問。例如,可以通過[0]訪問列表中的第一個元素,它類似于C/C++中的數組。圖展示了Python列表和元組的示例。圖3-11展示了如何使用Python元組。機器人操作系統(ROS)2.7.2Python變量元組的工作方式與列表類似,但元組包含在()中,而列表則包含在[]中。元組是只讀列表,因為它的值在初始化后不能被更改,但是在列表中我們可以修改其元素的值。Python提供的另一個內置數據類型是字典(dictionary)。與實際的字典類似,它有一個鍵(key)和一個與之關聯的值(value)。例如,在我們的字典里,有一個詞和它相應的釋義。這里的詞便是key,value就是該詞的釋義。圖顯示了Python字典的工作原理。如果我們在字典中給出鍵(key),它將返回與鍵相關聯的值。在下一節中,我們將學習Python條件語句。機器人操作系統(ROS)2.7.3Python的輸入和條件語句與C++類似,Python也有if/else語句用來檢查條件。在下面的示例中,你將看到Python如何處理用戶輸入,并基于此進行決策。程序的邏輯很簡單,僅要求用戶輸入移動機器人的命令。如果用戶輸入一個有效的命令,如move_left、move_right、move_forward或move_back,程序將輸出它正在移動,否則,它將輸出Invalidcommand,程序如下:#!/usr/bin/envpython#-*-coding:utf-8-*-Robot_command=raw_input(“Enterthecommand:>”)if(robot_command==“move_forward”):print“Robotismovingforward.”elif(robot_command==“move_backward”):print“Robotismovingbackward.”elif(robot_command==“move_left”):print“Robotismovingleft.”elif(robot_command==“move_right”):print“Robotismovingright.”else:print“Invalidcommand.”機器人操作系統(ROS)2.7.3Python的輸入和條件語句在Python中接受用戶的輸入,我們可以使用raw_input()函數或input()函數。raw_input()函數接受任何類型的數據,但是input()函數只能接受整數類型。下面是ra
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 哈爾濱劍橋學院《工程光學基礎實驗》2023-2024學年第二學期期末試卷
- 陜西職業技術學院《建筑工程計量與計價實訓》2023-2024學年第二學期期末試卷
- 寧夏職業技術學院《民間剪紙藝術》2023-2024學年第二學期期末試卷
- 云南旅游職業學院《財務數據模型分析與技術》2023-2024學年第二學期期末試卷
- 江蘇醫藥職業學院《合唱與合唱指揮2》2023-2024學年第二學期期末試卷
- 贛州師范高等專科學校《水文地質學基礎》2023-2024學年第二學期期末試卷
- 天津醫科大學臨床醫學院《微生物學與免疫學》2023-2024學年第二學期期末試卷
- 2025至2030年中國車輪輪輞平板卷圓機行業投資前景及策略咨詢報告
- 西安明德理工學院《中學化學改革研究》2023-2024學年第二學期期末試卷
- 成都醫學院《阿拉伯語聽力二》2023-2024學年第二學期期末試卷
- 大學《現代控制理論》期末考試測試卷
- 自適應光學在眼底成像中的突破
- 黑龍江省雞西市2024年中考數學全真模擬試題含解析
- 七年級英語下學期期末考試(無錫卷)七年級英語下冊單元重難點易錯題精練(牛津譯林版)
- 高標準農田設計實施方案(技術標)
- 2024廣東茂名市住房和城鄉建設局招聘10人歷年(高頻重點提升專題訓練)共500題附帶答案詳解
- JT-T-155-2021汽車舉升機行業標準
- 煙囪工程技術標準
- 農田耕作機械合同模板范文
- 完整版2024年“安全生產月”課件
- 國際談判與國際公文寫作-知到答案、智慧樹答案
評論
0/150
提交評論