UVM学习笔记(四)sequence与sequencer
目录
- 一、概述
- 1.1 类的继承
- 1.2 数据传送机制
- 二、uvm_sequence_item
- 2.1 功能与数据成员
- 2.2 示例
- 三、uvm_sequence
- 3.1 功能与分类
- 3.2 flat sequence
- 3.2 hierarchical sequence
- 3.3 virtual sequence
- 3.4 layering sequence
- 四、uvm_sequencer与uvm_driver
- 4.1 功能
- 4.2 端口与方法
- 4.3 传输实例
- 五、uvm_sequencer与uvm_sequence
- 5.1 sequence挂载到sequencer
- 5.2 item挂载到sequencer
- 5.3 发送序列的相关宏
- 5.4 仲裁模式
- 5.5 sequencer的锁定机制
一、概述
1.1 类的继承
- uvm_object->uvm_transaction->**uvm_sequence_item**->uvm_sequence_base->**uvm_sequence**
1.2 数据传送机制
- get模式:driver从sequencer获取item
- 优势:1. driver获取到item即可结束传输,put需要收到返回值才发起下一次传输,效率会低一些;2. driver作为initiator能更好的实现sequence的仲裁特性
二、uvm_sequence_item
2.1 功能与数据成员
- 功能:生成item
- 数据成员类型- 控制类:总线协议上的读写类型,数据长度,传送模式- 负载类:数据总线上的数据包- 配置类:控制driver的驱动行为,命令driver的发送间隔等- 调试类:标记格外信息
2.2 示例
1.声明
2.注册与域的自动化
3.test中构建,用create具有可以覆盖,建立层次化关系的优点
4.随机化t.randomize();
class bus_trans extends uvm_sequence_item;rand bit write ;rand int data ;rand int addr ;rand int delay;static int id_num;`uvm_object_utils_begin(bus_trans)`uvm_field_int...`uvm_object_utils_end
endclass
class test1 extends uvm_test ;`uvm_component_utils(test1)task run_phase(uvm_phase phase) ;bus_trans t1,t2 ;phase.raise_objection(phase) ;#100ns;t1 = new("t1") ;t1.print() ;#200ns;t2 = new("t2") ;void'(t2.randomize()) ;t2.print() ;phase.drop_objection(phase) ;endtask
endclass
三、uvm_sequence
3.1 功能与分类
- flat sequence:item实例构成
- hierarchical sequence:高层的sequence组织底层的sequence,让这些sequence按照顺序或并行挂载到同一个sequencer上
- virtual sequence:自身不挂载,将内部不同类型sequence挂载到不同的目标sequencer上
3.2 flat sequence
sequence被挂载后,自动执行**body**内容
class bus_trans extends uvm_sequence_item;rand bit write;rand int data[];rand int length;rand int addr;rand int delay;static int id_num;constrint cstr{data.size() == length;soft addr == 'h10;soft write == 1;delay inside{[1:5]};}//1.尽量将一段完整发生的数据传输中的、更长的的数据囊括在trans类中,可以使sequence不考虑数据内容,只考虑数据长度与地址等`uvm_object_utils_begin(bus_trans)uvm_field_int...`uvm_object_utils_end
endclassclass flat_seq extends uvm_sequence;rand int length;rand int addr;`uvm_object_utils(flat_seq)function new(string name = "flat_seq");super.new(name);endfunctiontask body();bus_trans tmp;tmp = new();tmp.randomize() with {length == local::length;addr == local::addr;};tmp.print();
endclass
class test extends uvm_test;`uvm_component_utils(test)task run_phase(uvm_phase phase)flat_seq seq;phase.raise_objection(phase);seq = flat_seq::type_id::create("seq");seq.randomize() with{addr == 'h20; length = 3;};seq.body();phase.drop_objection(phase);endtask
3.2 hierarchical sequence
1.创建sequence和trans
2.完成随机化
3.发送到sequencer
挂载到同一个sequencer
typedef enum {CLKON, CLKOFF, RESET, WRREG, RDREG} cmd_t;
class bus_trans extends uvm_sequence_item;rand cmd_t cmd;rand int addr;rand int data;constraint cstr{soft addr == 'h0;soft data == 'h0;}
endclass
class flat_seq extends uvm_sequence;rand int length;rand int addr;`uvm_object_utils(flat_seq)function new(string name = "flat_seq");super.new(name);endfunctiontask body();bus_trans tmp;tmp = new();tmp.randomize() with {length == local::length;addr == local::addr;};tmp.print();
endclass
class hier_seq extends uvm_sequence;`uvm_object_utils(hier_seq)function new(string name = "hier_seq");super.new(name);endfunctiontask body();bus_trans t1,t2;flat_seq s1,s2;`uvm_do_with(t1,{length == 2;})//item创建,随机化与发送到sequencerfork`uvm_do_with(s1,{length == 5})`uvm_do_with(s2,{length == 8})join`uvm_do_with(t2,{length == 3})endtask
endclass
class clk_rst_seq extends uvm_sequence;rand int freq;task body();bus_trans req;`uvm_do_with(req, {cmd == CLKON, data == freq;})`uvm_do_with(req, {cmd == RESET;})endtask
endclass
class reg_test_seq extends uvm_sequence;rand int chnl;task body();bus_trans req;//读写`uvm_do_with(req, {cmd == WRREG, addr == chnl*'h4;})`uvm_do_with(req, {cmd == RDREG, addr == chnl*'h4;})//读`uvm_do_with(req, {cmd == RDREG, addr == chnl*'h4 + 'h10;})endtask
endclass
class top_seq extends uvm_sequence;task body();reg_test_seq regseq0, regseq1, regseq2;clk_rst_seq clkseq;grab_seq grabs;m_sequencer.set_arbitration(UVM_SEQ_ARB_STRICT_FIFO);fork`uvm_do_with(clkseq, {freq== 150;})//打开时钟150Mhz,reset`uvm_do_with(regseq0, {chnl == 0;})`uvm_do_with(regseq1, {chnl == 1;})`uvm_do_with(regseq2, {chnl == 2;})//优先级比seq1和seq2低joinendtask
endclass
class reg_master_driver extends uvm_driver;task run_phase(uvm_phase phase);REQ tmp;bus_tranas req;forever beginseq_item_port.get_next_item(tmp);void'($cast(req, tmp));`uvm_info("DRV",$sformatf("got a item \n %s", req.sprint()),UVM_LOW)seq_item_port.item_done();endendtask
endclass
3.3 virtual sequence
- virtual sequencer定义所有要挂载的sequencer的句柄
- env实例化virtual sequencer,将所有sequencer句柄赋值给virtual sequencer
- virtual sequence通过uvm_declare_p_sequencer(virtual sequencer)获取所有句柄,通过uvm_do_on将不同的sequence的数据挂载到不同的sequencer上且发送
- test中实例化virtual sequence,将virtual sequence挂载到virtual sequencer上
//1.virtual sequencer
class mcdf_virtual_sequencer extends uvm_sequencer;cr_master_sequencer cr_sqr;reg_master_sequencer reg_sqr;chnl_master_sequencer chnl_sqr0;chnl_master_sequencer chnl_sqr1;chnl_master_sequencer chnl_sqr2;fmt_slave_sequencer fmt_sqr;mcdf_virtual_sequencer virt_sqr;`uvm_component_utils(mcdf_virtual_sequencer)function new(string name, uvm_coponent parent)super.new(name,parent);endfunction
endclass
//2.env
class mcdf_env extends uvm_env;cr_master_agent cr_agt; reg_master_agent reg_agt;chnl_master_agent chnl_agt0;chnl_master_agent chnl_agt1;chnl_master_agent chnl_agt2;fmt_slave_agent fmt_agt;mcdf_virtual_sequencer virt_sqr;`uvm_component_utils(mcdf_env)function new(string name, uvm_component parent);super.new(this);endfunction//创建各个有sequencer的容器function void build_phase(uvm_phase phase);cr_agt = cr_master_agent::type_id::create("cr_agt",this);reg_agt = reg_master_agent:: type_id::create("reg_agt",this);chnl_agt0 = chnl_master_agent::type_id::create("chnl_agt0",this);chnl_agt1 = chnl_master_agent::type_id::create("chnl_agt1",this);chnl_agt2 = chnl_master_agent::type_id::create("chnl_agt2",this);fmt_agt = fmt_slave_agent::type_id::create("fmt_agt",this);virt_sqr = mcdf_virtual_sequencer::type_id::create("virt_sqr",this);endfunction//避免悬空,非常重要function void connect_phase(uvm_phase phase);virt_sqr.cr_sqr = cr_agt.sqr;virt_sqr.reg_sqr = reg_agr.sqr;virt_sqr.chnl_sqr0 = chnl_agt0.sqr;virt_sqr.chnl_sqr1 = chnl_agt1.sqr;virt_sqr.chnl_sqr2 = chnl_agt2.sqr;virt_sqr.fmt_sqr = fmt_agt.sqr;endfunciton
endclass:mcdf_env
//3.virtual sequence,分属不同的sequencer,clk_rst_seq....分别配置sequencer且发送数据
class mcdf_normal_seq extends uvm_sequence;`uvm_object_utils(mcdf_normal_seq)`uvm_declare_p_sequencer(mcdf_virtual_sequencer)task body();clk_rst_seq clk_seq;reg_cfg_seq cfg_seq;data_trans_seq data_seq;fmt_slv_cfg_seq fmt_seq;//配置formatter slave agent`uvm_do_on(fmt_seq, p_sequencer.fmt_sqr)//打开时钟并完成复位`uvm_do_on(clk_seq, p_sequencer.cr_sqr)//配置MCDF寄存器`uvm_do_on(cfg_seq, p_sequencer.reg_sqr)//传送channel数据包fork`uvm_do_on(data_seq, p_sequencer.chnl_sqr0)`uvm_do_on(data_seq, p_sequencer.chnl_sqr1)`uvm_do_on(data_seq, p_sequencer.chnl_sqr2)joinendtask
endclass
//4.test,将virtual sequence挂载到virtual sequencer上
class test1 extends uvm_test;mcdf_env e;task run_phase(uvm_phase phase);mcdf_normal_seq seq;phase.raise_objection(phase);seq = mcdf_normal_seq::type_id::create("seq",this);seq.start(e.virt_sqr);phase.drop_objection(phase);endtask
endclass:test1
3.4 layering sequence
高抽象的item、中间转换的sequence、低抽象的item
typedef enum {CLKON, CLKOFF, RESET, WRREG, RDREG} phy_cmd_t;
typedef enum {FREQ_LOW_TRANS, FREQ_MID_TRANS, FREQ_HIGH_TRANS} layer_cmd_t;
//1.layer_trans高抽象级item
class layer_trans extends uvm_sequence_item;rand layer_cmd_t cmd;rand int pkt_len;rand int pkt_idle;constraint cstr{soft pkt_len inside{[10: 20]};layer_cmd == FREQ_LOW_TRANS -> pkt_idle inside {[300:400]};layer_cmd == FREQ_MID_TRANS -> pkt_idle inside {[100:200]};layer_cmd == FREQ_HIGH_TRANS -> pkt_idle inside {[20:40]};}
endclass
//2.bus_trans低抽象的item
class bus_trans extends uvm_sequence_item;rand phy_cmd_t cmd;rand int addr;rand int data;constraint cstr{soft addr == 'h0;soft data == 'h0;}
endclass
//3.packet_seq 低抽象级的item,bus_trans
class packet_seq extends uvm_sequence;rand int len;rand int addr;rand int data[];rand phy_cmd_t cmd;constraint cstr{soft len inside{[30:50}};soft addr[31:16] == 'hFF00;data.size() == len;}task body();bus_trans req;foreach(data[i])`uvm_do_with(req, {cmd == local::cmd;addr == local::addr;data == local::data[i];})endtask
endclass
//4.adapter_seq 转化层,从layer获取数据;挂载到phy_sequencer中,产生的为phy_sequence
class adapter_seq extends uvm_sequence;`uvm_objecet_utils(adapter_seq)`uvm_declare_p_sequencer(phy_master_sequencer)task body();layer_trans trans;//高抽象packet_seq pkt;//低抽象forever beginp_sequencer.up_sqr.get_next_item(req);//upsqr为更上层的sequencer句柄,从layersequencer中获取layer item;经常在driver中调用,但是这个是sequencer的方法,拿到句柄后可以调用,得到layer_trans;void'($cast(trans, req));repeat(trans.pkt_len) begin`uvm_do(pkt)delay(trans.pkt_idle);endp_sequencer.up_sqr.item_done();//消化掉高抽象级的itemendendtaskvirtual task delay(int delay);endtask
endclass
//5.top_seq 更顶层的sequence,连续发送两个layer_trans
class top_seq extends uvm_sequence;task body();layer_trans trans;`uvm_do_with(trans, {layer_cmd == FREQ_LOW_TRANS;})`uvm_do_with(trans, {layer_cmd == FREQ_HIGH_TRANS;})endtask
endclass
//6.sequencer phy中有up_sqr
class layering_sequencer extends uvm_sequencer;
endclass
class phy_master_sequencer extends uvm_sequencer;layering_sequencer up_sqr ;
endclassclass phy_master_driver extends uvm_driver;task run_phase(uvm_phase phase);REQ tmp;bus_trans req;forever beginseq_item_port.get_next_item(tmp);void'($cast(req, tmp));`uvm_info("DRV",$sformatf("got a item \n %s",req.sprint()),UVM_LOW)seq_item_port.item_done();endendtask
endclass
//
class phy_master_agent extends uvm_agent;phy_master_sequencer sqr;phy_master_driver drv;function void build_phase(uvm_phase phase);sqr = phy_master_sequencer::type_id::create("sqr",this);drv = phy_maaster_driver::type_id::create("drv",this);endfunctionfunction void connect_phase(uvm_phasae phase);drv.seq_item_port.connect(sqr.seq_item_export);endfunction
endclass
//
class test1 extends uvm_test;layering_sequencer layer_sqr;phy_master_agent phy_agt;function void build_phase(uvm_phase phase);layer_sqr = layering_sequencer::type_id::create("layer_sqr",this);phy_agt = phy_master_agent::type_id::create("phy_agt",this);endfunctionfunction void connect_phase(uvm_phase phase);phy_agt.sqr.up_sqr = layer_sqr;endfunctiontask run_phase(uvm_phase phase);top_seq seq;adaper_seq adapter;phase.raise_objection(phase):seq = new();adapter = new();forkadapter.start(phy_agt.sqr);//adaper_seq 挂载到phy上面join_noneseq.start(layer_sqr);//top_seq 挂载到layer上面phase.drop_objection(phase);endtask
endclass
四、uvm_sequencer与uvm_driver
4.1 功能
driver从sequencer通过get模式获取itemuvm_sequencer1. component通过TLM端口与driver传送item对象2. 仲裁多个并行sequence,路由,sequencer有选择的动态挂载所需的sequenceuvm_driver驱动激励时序
4.2 端口与方法
uvm_sequencer· uvm_seq_item_pull_imp #(REQ,RSP,this_type) seq_item_export· uvm_analysis_export#(RSP) rsp_export //analysis一对多端口,与fifo组件连接,fifo内部有imp,所以接收用的export端口;
uvm_driver· uvm_seq_item_pull_port#(REQ,RSP) seq_item_port· uvm_analysis_port#(RSP) rsp_port
driver常用方法· seq_item_port.get_next_item(tmp)· seq_item_port.item_done(rsp)· seq_item_port.put_rsponse(rsp)//在sequence中get_response(rsp)对应· rsp_port.write(RSP)
4.3 传输实例
//1.传输类
class bus_trans extends uvm_sequence_item;rand int data;`uvm_object_utils_begin(bus_trans)`uvm_field_int(data,UVM_ALL_ON)`uvm_object_utils_end
endclass
/*2.sequence类
挂载后通过seq.start自动执行body()内容
req=create_item(bus_trans::get_type(),m_sequencer,"req");创建request item对象
start_item(req);准备发送item
完成发送前对item进行随机处理
finish_item(req);完成item发送
get_response(tmp);从driver获取响应
*/
class flat_seq extends uvm_sequence;`uvm_object_utils(flat_seq)task body();bus_trans req,rsp;uvm_sequence_item tmp;//过渡与转换的//trans的type,name和要被挂载的sequencertmp = create_item(bus_trans::get_type(),m_sequencer,"req");//类型强制转换了void'($cast(req,tmp));//可改为req=create_item(bus_trans::get_type(),m_sequencer,"req");start_item(req);//立即返回,表示开始等待req.randomize with {data == 10;};finish_item(req);//阻塞,数据准备好,真实的在等待get_response(tmp);//driver::put_response与item_done(rsp)一一对应void'($cast(rsp,tmp));endtask
endclass
//3.sequencer类
class sequencer extends uvm_sequencer;`uvm_component_utils(sequencer)
endclass
//typedef uvm_sequencer#(bus_trans) sequencer;
//4.uvm_driver类
class driver extends uvm_driver;`uvm_component_utils(driver)task run_phase(uvm_phase phase);REQ tmp;//源码的REQbus_trans req, rsp;seq_item_port.get_next_item(tmp);//driver开始从sequencer获取数据void'($cast(req,tmp));//强制转换,这个类型可以在定义类时将参数传入,默认为uvm_sequence_item`uvm_info("DRV",$sformatf("got a item \n %s",req.sprint()),UVM_LOW)void'($cast(rsp, req.clone()));//clone返回都是objectrsp.set_sequence_id(req.get_sequence_id());//id可以在response才知道发送给谁rsp.data += 100;seq_item_port.item_done(rsp);//done发送了respone,sequence需要获取get_response`uvm_info("DRV",$sformatf("got a item \n %s",req.sprint()),UVM_LOW)endtask
endclass
//5.env
class env extends uvm_env;sequencer sqr;driver drv;`uvm_component_utils(env)function void build_phase(uvm_phase phase);sqr = sequencer::type_id::create("sqr",this);drv = driver::type_id::create("drv",this);endfunctionfunction void connect_phase(uvm_phase phase);drv.seq_item_port.connect(sqr.seq_item_export);//连接endfunction
endclass
//6.test
class test extends uvm_test;env e;`uvm_component_utils(test)function void build_phase(uvm_phase phase);e = env::type_id::create("e",this);endfunctiontask run_phase(uvm_phase phase);flat_seq seq;phase.raise_objection(phase);seq = flat_seq::type_id::create("seq");seq.start(e.sqr);//挂载,body自动执行,这里sequence还没有随机化phase.drop_objection(phase);endtask
endclass
五、uvm_sequencer与uvm_sequence
5.1 sequence挂载到sequencer
seq.start(要挂载的sequencer, 上层的sequence可以保留优先级,优先级,是否执行pre_body()和post_body())
5.2 item挂载到sequencer
create_item//创建item
start_item(req);
finish_item(req);
只有item才有优先级
5.3 发送序列的相关宏
只有sequence可以调用这些宏
class child_seq extends uvm_sequence;task body();bus_trans req;`uvm_create(req)`uvm_rand_send_with(req, {data == 10;})endtask
endclass
class top_seq extends uvm_sequence;task body();child_seq cseq;bus_trans req;`uvm_do(cseq)`uvm_do_with(req,{data == 20})endtask
endclass
5.4 仲裁模式
uvm_sequencer::set_arbitration(UVM_SEQ_ARB_TYPE val)设置仲裁模式
UVM_SEQ_ARB_FIFO:默认,fifo先入先出一次授权
UVM_SEQ_ARB_WEIGHTED:按优先级权重随机授权
UVM_SEQ_ARB_RANDOM:随机授权
UVM_SEQ_ARB_STRICT_FIFO:按优先级和抵达顺序依次授权
class child_seq extends uvm_sequence;rand int base;task body();bus_trans req;repeat(2) `uvm_do_with(req, {data inside {[base: base + 9]};//wait_for_grant才会等待授权endtask
endclass
class top_seq extends uvm_sequence;task body();child_seq seq1, seq2, seq3;m_sequencer.set_arbitration(UVM_SEQ_ARB_STRICT_FIFO);fork`uvm_do_pri_with(seq1, 500, {base == 10;})//同一时间申请发起传送请求,uvm_do_pri_with发送sequence时可以传递优先级参数`uvm_do_pri_with(seq2, 500, {base == 20;})`uvm_do_pri_with(seq3, 300, {base == 30;})joinendtask
endclass
class driver extends uvm_driver;task run_phase(uvm_phase phase);REQ tmp;bus_trans req;forever beginseq_item_port.get_next_item(tmp);void'($cast(req, tmp));`uvm_info("DRV",$sformatf("got a item %0d from parent sequence %s", req.data, req.get_parent_sequence().get_name()),UVM_LOW)seq_item_port.item_done();endendtask
endclass
class test extends uvm_test;env e;task run_phase(uvm_phase phase);top_seq seq;phase.raise_objection(phase);seq = top_seq::type_id::create("seq");seq.start(e.sqr);//只有在sequence里面才可以用宏phase.drop_objection(phase);endtask
endclass
5.5 sequencer的锁定机制
lock() unclock()按优先级获取
grab() ungrab()不按优先级
class lock_seq extends uvm_sequence;task body();bus_trans req;#10ns;m_sequencer.lock(this);//等待权限时,lock住`uvm_info("LOCK","get exclusive access by lock()"),UVM_LOW)repeat(3) #10ns `uvm_do_with(req, {data inside {[100:110]};})m_sequencer.unclock(this);endtask
endclass
class grab_seq extends uvm_sequence;task body();bus_trans req;#20ns;m_sequencer.grab(this);//`uvm_info("GRAB","get exclusive access by grab()"),UVM_LOW)repeat(3) #10ns `uvm_do_with(req, {data inside {[200:210]};})m_sequencer.ungrab(this);endtask
endclass
class top_seq extends uvm_sequence;task body();child_seq seq1, seq2, seq3;lock_seq locks;grab_seq grabs;m_sequencer.set_arbitration(UVM_SEQ_ARB_STRICT_FIFO);fork`uvm_do_pri_with(seq1, 500, {base == 10;})//同一时间申请发起传送请求,uvm_do_pri_with发送sequence时可以传递优先级参数`uvm_do_pri_with(seq2, 500, {base == 20;})`uvm_do_pri_with(seq3, 300, {base == 30;})`uvm_do_pri(locks,300)//优先级比seq1和seq2低`uvm_do(grabs)//没有优先级,不管优先级,20ns才开始获取joinendtask
endclass
UVM学习笔记(四)sequence与sequencer相关推荐
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决)
RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决) 参考文章: (1)RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决) (2)https://www.cnblogs. ...
- JSP学习笔记(四十九):抛弃POI,使用iText生成Word文档
POI操作excel的确很优秀,操作word的功能却不敢令人恭维.我们可以利用iText生成rtf文档,扩展名使用doc即可. 使用iText生成rtf,除了iText的包外,还需要额外的一个支持rt ...
- Ethernet/IP 学习笔记四
Ethernet/IP 学习笔记四 EtherNet/IP Quick Start for Vendors Handbook (PUB213R0): https://www.odva.org/Port ...
- OpenCV学习笔记四-image的一些整体操作
title: OpenCV学习笔记四-image的一些整体操作 categories: 编程 date: 2019-08-08 12:50:47 tags: OpenCV image的一些操作 sP4 ...
- 吴恩达《机器学习》学习笔记四——单变量线性回归(梯度下降法)代码
吴恩达<机器学习>学习笔记四--单变量线性回归(梯度下降法)代码 一.问题介绍 二.解决过程及代码讲解 三.函数解释 1. pandas.read_csv()函数 2. DataFrame ...
- esp8266舵机驱动_arduino开发ESP8266学习笔记四—–舵机
arduino开发ESP8266学习笔记四-–舵机 使用时发现会有ESP8266掉电的情况,应该是板上的稳压芯片的限流导致的,观测波形,发现当舵机运转时,电源线3.3V不再是稳定的3.3V,大概是在3 ...
- mysql新增表字段回滚_MySql学习笔记四
MySql学习笔记四 5.3.数据类型 数值型 整型 小数 定点数 浮点数 字符型 较短的文本:char, varchar 较长的文本:text, blob(较长的二进制数据) 日期型 原则:所选择类 ...
- ROS学习笔记四:理解ROS节点
ROS学习笔记四:理解ROS节点 本节主要介绍ROS图形概念,讨论ROS命令行工具roscore.rosnode和rosrun. 要求 要求已经在Linux系统中安装一个学习用的ros软件包例子: s ...
最新文章
- 【HDOJ】3487 Play with Chain
- 放授权代码的php文件夹,自己的项目如果包含别人的开源代码,licence文件应放在哪里...
- 面试题热个身:5 亿整数的大文件,来排个序?
- python 中的 for-else 和 while-else 语句
- oracle禁止自动启动命令,自动启动和关闭Oracle 脚本
- 今日arXiv精选 | 28篇EMNLP 2021最新论文
- 软件工程小组第三次正式会议
- (2.2)HarmonyOS鸿蒙页面跳转
- c语言100以内奇数的和为多少,编写C#程序,计算100以内所有奇数的和。谢谢了,大神帮忙啊...
- HTML元素参考手册 HTML Elements Reference
- 同一台电脑安装python2python3
- Linux错误 libXext.so.6: cannot open shared object file
- 基于社会资源的普通摄像机1400结构化AI算法改造方案
- 10个简单的放松运动
- 核磁共振成像读片指南(一)
- 国内哪里培训python比较好-最好的Python培训机构是哪家?
- Moniter和Lock
- go 并发goroutines,channal
- 布施持戒忍辱精进禅定般若——净空法师【转】
- git版本回退简单记录