tobot

  • 2025-03-09
  • 回复了主题帖: 【新年花灯秀】彩色PCB雪花灯

    漂亮

  • 2025-03-01
  • 回复了主题帖: 想知道两轮差速方形底盘 URDF 咋做,ROS2 配 Rviz 咋显示吗?看这里!

    学习学习

  • 2025-02-28
  • 回复了主题帖: 跟我学:每天5分钟,一个月入门mujoco(序)

    freebsder 发表于 2025-2-28 16:29 这是个仿真平台还是个开发平台呢? 可以把这个当作是一个游戏引擎:把一个完整游戏里面的素材都删掉,但保留了接口。   就像马里奥制造那样的,各种砖块都放在那里,你想搭一个什么关卡都可以,等你搭好了,就可以尝试过关(类似仿真),但是你也可以你的存档给别人,别人可以在你基础上继续修改(类似开发)。

  • 2025-02-27
  • 回复了主题帖: 跟我学:每天5分钟,一个月入门mujoco(1.3)

    jryq213 发表于 2025-2-27 12:33 非常错的资料,学习了,如果有详细课件更好。 有源码,全套代码我是我自己敲的。 需要ppt么?那可能得重新写

  • 回复了主题帖: 跟我学:每天5分钟,一个月入门mujoco(1.3)

    wangerxian 发表于 2025-2-27 08:57 可以配置小球的密度或者材质吗? 可以的,下下下……节就有了 下节是初速度 下下节是采集数据和生成曲线 再往后就是改变各种外部参数,比如重力、风力(风阻)、密度等等

  • 2025-02-26
  • 发表了主题帖: 跟我学:每天5分钟,一个月入门mujoco(1.3)

    第3节 自由落体 在以比萨斜塔为背景,让两个小球从高处落下: [localvideo]f194ab1f63194a35a1dd18fae011e4a6[/localvideo]   可以看到,存在一个加速下落的过程。 代码如下: import mujoco import mujoco.viewer import time from xml.dom import minidom def load_xml(xml): dom = minidom.parse(xml) return dom def get_root_element(dom): if dom is not None: root = dom.documentElement return root return None def get_child_elements(root,tag): if root is not None: child_elements = root.getElementsByTagName(tag) return child_elements return None def make_object(dom,obj): newnode = dom.createElement("geom") for k,v in obj.items(): newnode.setAttribute(k,v) return newnode def add_object(dom,pnode,newnode): if newnode.nodeName == "geom": tmpbody = dom.createElement("body") tmpnode = dom.createElement("joint") tmpnode.setAttribute("type","free") tmpbody.appendChild(tmpnode) tmpbody.appendChild(newnode) pnode.appendChild(tmpbody) if __name__ == "__main__": red_ball = {} red_ball["type"] = "sphere" red_ball["pos"] = "16 -1.5 30" red_ball["size"] = "1" red_ball["rgba"] = ".9 0 0 1" blue_ball = {} blue_ball["type"] = "sphere" blue_ball["pos"] = "16 1.5 30" blue_ball["size"] = "1" blue_ball["rgba"] = "0 0 .9 1" dom = load_xml("tower.xml") root = get_root_element(dom) pnode = get_child_elements(root, 'worldbody')[0] newnode = make_object(dom,red_ball) add_object(dom,pnode,newnode) newnode = make_object(dom,blue_ball) add_object(dom,pnode,newnode) model = mujoco.MjModel.from_xml_string(dom.toxml()) data = mujoco.MjData(model) viewer = mujoco.viewer.launch_passive(model, data) viewer.cam.azimuth = 145.0 viewer.cam.distance = 90 viewer.cam.elevation = -5.0 while True: mujoco.mj_step(model, data) viewer.sync() time.sleep(0.001) 分析: 这里有两个函数 def make_object(dom,obj):     newnode = dom.createElement("geom")     for k,v in obj.items():         newnode.setAttribute(k,v)     return newnode   def add_object(dom,pnode,newnode):     if newnode.nodeName == "geom":         tmpbody = dom.createElement("body")         tmpnode = dom.createElement("joint")         tmpnode.setAttribute("type","free")         tmpbody.appendChild(tmpnode)         tmpbody.appendChild(newnode)         pnode.appendChild(tmpbody)   make_object是用于生成一个新的geom(几何体),是将刚生成的几何体放置在之前的dom中。 在前面章节里面,我们知道,如果不做设置,同一个body内的的几何体相对位置是固定的,也就是说,即使我们放置了geom,它也会悬在半空。为了实现下落的要求,我们增加了一个属性类型为”free”的joint(关节),这里新引入了joint的概念,它是用于连接几何体的虚拟构件。主要属性有: name:名字 pos:关节位置 type:关节类型,可以是hinge(铰链关节,绕单一轴旋转)、slide(滑动关节,沿单一轴线移动)、ball(球形关节)、free(自由型),缺省是hinge axis:轴,可以用于滚动(hinge)或者滑动slide

  • 2025-02-25
  • 回复了主题帖: 跟我学:每天5分钟,一个月入门mujoco(1.2)

    wangerxian 发表于 2025-2-25 20:39 这是一个3D库吗?可以导入什么样的3D文件? 事实上,它的3D功能好像还真不怎么样,基础功能只有方块、球、椭球、连三角块都需要外部建模,支持stl格式的mesh导入…… 而且渲染功能我一直没搞定,但物理特性仿真不错(特指固体)。

  • 2025-02-24
  • 发表了主题帖: 跟我学:每天5分钟,一个月入门mujoco(1.2)

    第2节 设置视角 在前1节,我们建立了模型并且将其存储为一个xml文件,但我们发现,这个模型相对我们的显示界面“太大”了,需要用鼠标调整以后才能摆在屏幕中间,至于怎么调整,相信大家都很熟悉,左键拖动旋转,右键移动位置,滚轮缩放。 在本节,我们复习载入xml文件,并学习在代码中变换视角。 [localvideo]67a900b20b8bda66810078b99025e377[/localvideo] 代码其实非常简单,就是不断变换几个参数: import mujoco import mujoco.viewer import time if __name__ == "__main__": model = mujoco.MjModel.from_xml_path('tower.xml') data = mujoco.MjData(model) viewer = mujoco.viewer.launch_passive(model, data) for i in range(0,960): viewer.cam.elevation= 0 - i/65 viewer.cam.distance = i/15+40 viewer.cam.azimuth = i/2 viewer.cam.lookat = [0, 0, -15+i/55] time.sleep(0.02) 由于代码实在太简单,本节不做代码讲解。

  • 回复了主题帖: 跟我学:每天5分钟,一个月入门mujoco(1.1)

    hellokitty_bean 发表于 2025-2-24 08:57 让人好好奇呀。。。。。。。。。。mujoco这么可爱好玩吗 如果当游戏玩的话,建议“马里奥制造”,如果想用来当物理学教具,我认为初中的所有实验都够了

  • 2025-02-23
  • 发表了主题帖: 跟我学:每天5分钟,一个月入门mujoco(1.1)

    重力加速度 在本章中,我们尝试编写一个模型测试物体在重力场中的行为,并尝试修改各项参数(质量、形状、重力加速度等),看看如何在mujoco的呈现。   第1节 坐标系与参照物 说起重力加速度,最出名的肯定是伽利略先生在比萨斜塔上做的自由落体实验。多年前我也曾前往斜塔朝圣,这里就以斜塔作为落体的参照物吧。 这一节我们先学着画参照物:   (照片来自网络,侵权请告知) 可以看到塔分8层,每层的结构相似,由柱子和塔身构成,可以抽象为使用若干大大小小的圆柱组合而成。   如前一章节中介绍,可以使用xml格式文件来存储mujoco模型。那么现在就介绍一下mujoco里面常用的xml标签元素: mujoco: 这是最外层的标签元素,也就是所谓的根,全xml只能有一个,有属性值model,缺省是“MuJoCo Model”,在viewer中显示的标题。 body(体): body是在mujoco中用于指定物体的标签元素(支持套嵌,最外层的叫做worldbody),可以包括的属性有: name:体的名字,定义后可以用name来引用这个体 pos:体的位置,当然是基于上级元素的,缺省是(0,0,0) euler:控制体的方向,也是基于上级元素的 Geom(几何体): name:名字 pos:几何体位置 type:几何体类型,可以是sphere(球体,缺省值)、plane(地平面)、box(立方体)、cylinder(圆柱体)、capsule(胶囊体)、ellipsoid(橄榄球形)等等 size:几何体大小 rgba:渲染几何体的颜色     知道了上述信息,就能开始了,首先,我们具有简单python基础,编写xml文件可以用dom。 import mujoco import mujoco.viewer import xml.dom.minidom as minidom import math def create_root(dom): root = dom.documentElement root.setAttribute("model", "Elizabeth Tower") return root def create_world(dom,root): worldbody = dom.createElement("worldbody") root.appendChild(worldbody) plane = dom.createElement("geom") plane.setAttribute("type","plane") plane.setAttribute("size","20 20 0.1") plane.setAttribute("rgba","0 .8 0 1") plane.setAttribute("pos","0 0 -22") ground = dom.createElement("geom") ground.setAttribute("type","box") ground.setAttribute("name","ground") ground.setAttribute("size","20 20 1") ground.setAttribute("rgba",".237 .189 .101 1") ground.setAttribute("pos","0 0 -23") worldbody.appendChild(plane) worldbody.appendChild(ground) towerbody = create_tower(dom) towerbody.setAttribute("pos","0 0 -23") towerbody.setAttribute("euler","0 5 0") worldbody.appendChild(towerbody) def create_tower(dom): towerbody = dom.createElement("body") towerbody.setAttribute("name","Elizabeth Tower") towerbase = dom.createElement("geom") towerbase.setAttribute("type","cylinder") towerbase.setAttribute("rgba",".5 .5 .5 1") towerbase.setAttribute("pos","0 0 5") towerbase.setAttribute("size","9 5") towerbody.appendChild(towerbase) for i in range(15): a=11 pole = dom.createElement("geom") pole.setAttribute("type","cylinder") pole.setAttribute("rgba",".5 .5 .5 1") pole.setAttribute("pos",str(a*math.sin(i*math.pi/7.5))+" "+str(a*math.cos(i*math.pi/7.5))+" 5") pole.setAttribute("size",".7 5") towerbody.appendChild(pole) top1 = dom.createElement("geom") top1.setAttribute("type","cylinder") top1.setAttribute("rgba",".5 .5 .5 1") top1.setAttribute("pos","0 0 10") top1.setAttribute("size","12.1 .1") towerbody.appendChild(top1) a = 10.8 for level in range(1,7): top = dom.createElement("geom") top.setAttribute("type","cylinder") top.setAttribute("rgba",".5 .5 .5 1") top.setAttribute("pos","0 0 "+str(10+level*6)) top.setAttribute("size",str(a+0.8)+" .1") towerbody.appendChild(top) for i in range(30): pole = dom.createElement("geom") pole.setAttribute("type","cylinder") pole.setAttribute("rgba",".5 .5 .5 1") pole.setAttribute("pos",str(a*math.sin(i*math.pi/15))+" "+str(a*math.cos(i*math.pi/15))+" "+str(7+6*level)) pole.setAttribute("size",".5 3") towerbody.appendChild(pole) stair = dom.createElement("geom") stair.setAttribute("type","cylinder") stair.setAttribute("rgba",".5 .5 .5 0.5") stair.setAttribute("pos","0 0 "+str(7+6*level)) stair.setAttribute("size",str(a-2)+" 3") towerbody.appendChild(stair) a=a-0.15 towertop = dom.createElement("geom") towertop.setAttribute("type","cylinder") towertop.setAttribute("rgba",".5 .5 .5 1") towertop.setAttribute("pos","0 0 50") towertop.setAttribute("size","7 4") towerbody.appendChild(towertop) for i in range(12): a=8 pole = dom.createElement("geom") pole.setAttribute("type","cylinder") pole.setAttribute("rgba",".5 .5 .5 1") pole.setAttribute("pos",str(a*math.sin(i*math.pi/6))+" "+str(a*math.cos(i*math.pi/6))+" 50") pole.setAttribute("size",".4 4") towerbody.appendChild(pole) top2 = dom.createElement("geom") top2.setAttribute("type","cylinder") top2.setAttribute("rgba",".5 .5 .5 1") top2.setAttribute("pos","0 0 54") top2.setAttribute("size","9 .3") towerbody.appendChild(top2) return towerbody if __name__ == "__main__": dom = minidom.getDOMImplementation().createDocument(None,"mujoco",None) root = create_root(dom) create_world(dom,root) m = mujoco.MjModel.from_xml_string(dom.toxml()) v = mujoco.viewer.launch(m) with open('tower.xml', 'w', encoding='utf-8') as f: dom.writexml(f, addindent='\t', newl='\n',encoding='utf-8')   执行一下看看,嗯,由于模型太大了,可能看不到全图,可以用鼠标滚轮操作一下缩放:     代码分析: dom = minidom.getDOMImplementation().createDocument(None,"mujoco",None) 新建dom,其中根叫做mujoco root = dom.documentElement root.setAttribute("model", "Elizabeth Tower") 获取根节点,指定model属性(显示名为Elizabeth Tower)。 worldbody = dom.createElement("worldbody") root.appendChild(worldbody) 在root下增加worldbody。 with open('tower.xml', 'w', encoding='utf-8') as f:         dom.writexml(f, addindent='\t', newl='\n',encoding='utf-8') 保存xml文件,命名为tower.xml。

  • 2025-02-21
  • 回复了主题帖: 恭喜LitchiCheng走马上任机器人开发版块版主!!

    恭喜恭喜

  • 发表了主题帖: 跟我学:每天5分钟,一个月入门mujoco(序)

    机器人仿真是一个很有趣的话题,多年前我曾尝试用过不少游戏引擎去学习“制作”机器人,但最终比较倾向于使用webots和mujoco。 这里可以开两个两个讨论话题:webots、mujoco。 Mujoco也是比较神奇的,最初免费,不少人学习使用;后来收费,损失了大量人气,再后来被deepmind买下,直接开源了,但已经不复当年盛况,在中文的各论坛上也基本找不到什么新一点有深度的资料——几年前的还有,但已经不再适配最新版本了。 有鉴于此,笔者准备为爱发电,借eeworld宝地开一个mujoco系列。大家可以试着跟读,每天只占用5分钟阅读时间,大概一个月,就能把这个有趣物理引擎玩转了。当然我不保证每天都能更新。 mujoco是什么? Multi-Joint dynamics with Contact,翻译起来可以认为是多关节动力学连接。这也是mujoco的主要用途。可以快速开发多个物体的连接,并且对其物理特性进行仿真。具体使用什么语言去开发,其实并不重要,看大家的习惯吧。在本系列的文章中,我们从实战入手,使用python进行开发,且假设各位都已经有一点点python的开发基础了。     第0章 安装环境和显示一个mujoco模型 在本章的练习中,我们将使用到mujoco的传统例子——机械手臂。 首先,我们准备一下开发环境,使用pip install mujoco安装mujoco的python支持(这里最好是python3.10以上的版本,本人使用的是python3.11)。需要用到的xml文件(arm26.xml)和本节所用到的代码见附件。 我们先介绍一下几个基础概念: 模型 在mujoco中,模型是可以用于定义显示和操作的,可以使用xml存储。 视图 Viewer是mujoco最重要的组成部分,用于呈现出界面。一般来说,我们可以通过命令行调用: python -m mujoco.viewer --mjcf=arm26.xml 执行该命令后,可以看到一个所谓2连接6肌肉的手臂,可以通过按钮来控制这个手臂 [localvideo]e1308ec00eb9ee7d1b90c454b7ab00e9[/localvideo]         用代码载入 #直接pip install mujoco安装 import mujoco.viewer m = mujoco.MjModel.from_xml_path('arm26.xml') v = mujoco.viewer.launch(m)   核心就两条,因为太过简单,就不怎么介绍了吧 m = mujoco.MjModel.from_xml_path('arm26.xml') v = mujoco.viewer.launch(m)   本章节用到模型xml文件  

  • 回复了主题帖: 撒积分啦!!机器人开发圈公众号上线、还有多个新板块设立哦~~

    恭喜恭喜

  • 回复了主题帖: 四足机器人学习资料

    freebsder 发表于 2025-2-20 19:21 arduino控制的?应该没那么智能吧 确实是arduino。。。

  • 2025-02-20
  • 上传了资料: 四足机器人

  • 发表了主题帖: 四足机器人学习资料

    上传两个我珍藏模型——以前一直以为有时间能弄出来玩玩的,一拖就是几年 [localvideo]187a7cfaf2d55df5399c29f4a5496992[/localvideo]    

  • 回复了主题帖: 【过年都玩啥】话说探友们过年都玩啥了呢?

    回乡炸牛屎。。。

  • 2025-02-17
  • 回复了主题帖: 你参加哪吒2的百亿项目了吗?

    smartzheng981 发表于 2025-2-17 08:55 父亲是大军区最高将领,母亲娘家背景深厚,大哥是老大秘书,二哥是老二秘书,这种人又能差到哪去 还有师傅太乙,十二常委之一……

  • 回复了主题帖: 关于一个成绩分类的C语言实现的两种方式

    python ,没有switch。。。总有它的道理

  • 回复了主题帖: 【新年点灯】link2

    okhxyyo 发表于 2025-2-11 14:25 太可爱了!!有那种玩古早游戏的赶脚 就是太古时代的游戏了,网上已经找不到原始的了,只有后面几代的,下面这张图已经是可以找到最早游戏的截图了,画质已经大有改善了 和女生一起进房间可以加血,不过对话总感觉有让人想歪(也许就是日本的特色。。。)  

最近访客

< 1/6 >

统计信息

已有362人来访过

  • 芯积分:1832
  • 好友:5
  • 主题:116
  • 回复:313

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言