feat: 重构
This commit is contained in:
parent
c567b1cab4
commit
83d817e9e5
@ -1,5 +1,5 @@
|
|||||||
# 页面标题
|
# 页面标题
|
||||||
VITE_APP_TITLE = 招商车研AI测评机器人模拟测试平台
|
VITE_APP_TITLE = 招商车研机器人智能测试管理系统
|
||||||
|
|
||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
VITE_APP_ENV = 'development'
|
VITE_APP_ENV = 'development'
|
||||||
@ -7,8 +7,8 @@ VITE_APP_ENV = 'development'
|
|||||||
# 招商车研物联网平台/开发环境
|
# 招商车研物联网平台/开发环境
|
||||||
VITE_APP_BASE_API = '/dev-api'
|
VITE_APP_BASE_API = '/dev-api'
|
||||||
|
|
||||||
VITE_API_URL = http://192.168.0.201:13080
|
VITE_API_URL = http://192.168.0.222:14080
|
||||||
VITE_WS_URL = ws://192.168.0.201:13080/ws
|
VITE_WS_URL = ws://192.168.0.222:14080/ws
|
||||||
|
VITE_PORT = 5174
|
||||||
# explanation
|
|
||||||
VITE_INSPECTION_TYPE = "inspection"
|
VITE_INSPECTION_TYPE = "inspection"
|
||||||
|
VITE_MINIO_URL = "http://192.168.28.10:9000/cmvr-iot/"
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
# 页面标题
|
# 页面标题
|
||||||
VITE_APP_TITLE = 智能座舱测评AI机器人
|
VITE_APP_TITLE = 招商车研机器人智能测试管理系统
|
||||||
|
|
||||||
# 生产环境配置
|
# 生产环境配置
|
||||||
VITE_APP_ENV = 'production'
|
VITE_APP_ENV = 'production'
|
||||||
@ -10,11 +10,8 @@ VITE_APP_BASE_API = '/prod-api'
|
|||||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||||
VITE_BUILD_COMPRESS = gzip
|
VITE_BUILD_COMPRESS = gzip
|
||||||
|
|
||||||
#node-red 服务地址
|
|
||||||
VITE_NODE_RED_URL = 'http://10.148.108.59:13080'
|
VITE_NODE_RED_URL = 'http://10.148.108.59:13080'
|
||||||
|
|
||||||
VITE_API_URL = http://192.168.28.10:13080
|
VITE_API_URL = http://192.168.28.10:13080
|
||||||
VITE_WS_URL = ws://192.168.0.201:13080/ws
|
VITE_WS_URL = ws://192.168.0.201:13080/ws
|
||||||
|
|
||||||
# explanation
|
|
||||||
VITE_INSPECTION_TYPE = "inspection"
|
VITE_INSPECTION_TYPE = "inspection"
|
||||||
|
VITE_MINIO_URL = "http://192.168.28.10:9000/cmvr-iot/"
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
# 页面标题
|
# 页面标题
|
||||||
VITE_APP_TITLE = 招商车研物联网平台管理系统
|
VITE_APP_TITLE = 招商车研机器人智能测试管理系统
|
||||||
|
|
||||||
# 生产环境配置
|
# 生产环境配置
|
||||||
VITE_APP_ENV = 'staging'
|
VITE_APP_ENV = 'staging'
|
||||||
|
|
||||||
# 招商车研物联网平台管理系统/生产环境
|
# 招商车研物联网平台/测试环境
|
||||||
VITE_APP_BASE_API = '/stage-api'
|
VITE_APP_BASE_API = '/stage-api'
|
||||||
|
|
||||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||||
VITE_BUILD_COMPRESS = gzip
|
VITE_BUILD_COMPRESS = gzip
|
||||||
|
|
||||||
VITE_API_URL = http://10.148.121.100:13080
|
VITE_API_URL = http://10.148.121.100:13080
|
||||||
VITE_WS_URL = ws://192.168.0.201:13080/ws
|
VITE_WS_URL = ws://192.168.0.201:13080/ws
|
||||||
|
VITE_INSPECTION_TYPE = "inspection"
|
||||||
|
VITE_MINIO_URL = "http://192.168.28.10:9000/cmvr-iot/"
|
||||||
|
|||||||
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
custom: http://doc.ruoyi.vip/ruoyi-vue/other/donate.html
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@ -18,9 +18,8 @@ selenium-debug.log
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.local
|
*.local
|
||||||
.history
|
|
||||||
|
|
||||||
package-lock.json
|
package-lock.json
|
||||||
yarn.lock
|
yarn.lock
|
||||||
bin/
|
|
||||||
pnpm-lock.yaml
|
.history
|
||||||
|
|||||||
125
README.md
125
README.md
@ -1,35 +1,102 @@
|
|||||||
|
# CMVR IoT 管理控制台
|
||||||
|
|
||||||
## 前端运行
|
招商车研物联网平台 Vue 3 管理端。项目以 RuoYi-Vue3 3.9.2 为新版基础框架,完整迁移原 `cmvr-iot-ui` 的业务页面、API、机器人模型和运行配置,并连接 `RuoYi-Vue-master` 中的 Spring Boot 4 后端。
|
||||||
|
|
||||||
|
旧前端仅作为迁移来源,不参与本项目构建。
|
||||||
|
|
||||||
|
## 功能范围
|
||||||
|
|
||||||
|
- 系统管理:用户、角色、部门、岗位、菜单、字典、参数、通知和文件。
|
||||||
|
- 系统监控:在线用户、操作日志、登录日志、缓存、服务、Quartz 和 Druid。
|
||||||
|
- 设备管理:设备注册、终端、机器人、相机、机械臂、灵巧手、机器人头部、麦克风、扬声器和电机。
|
||||||
|
- 测试平台:测试项目、任务配置、任务编排、检测项、任务实例和执行流程。
|
||||||
|
- 智能巡检:机器人、地图、点位、任务、执行实例、巡检结果、告警和驾驶舱。
|
||||||
|
- 交互评价:语音交互、触控交互、评价指标、方案、项目和语料。
|
||||||
|
- 智能座舱:车机界面、车辆配置、功能配置、流程编辑和执行评价。
|
||||||
|
- 语料与媒体:语料管理、音频上传、图片预览、视频播放和 WebSocket 实时消息。
|
||||||
|
- 开发工具:代码生成、表单构建和 Knife4j 接口文档。
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
| 组件 | 版本 |
|
||||||
|
| --- | --- |
|
||||||
|
| Vue | 3.5.26 |
|
||||||
|
| Vite | 6.4.1 |
|
||||||
|
| Element Plus | 2.13.1 |
|
||||||
|
| Pinia | 3.0.4 |
|
||||||
|
| Vue Router | 4.6.4 |
|
||||||
|
| 可视化 | ECharts、Vue Flow、Three.js、Monaco Editor、XGPlayer |
|
||||||
|
|
||||||
|
## 环境要求
|
||||||
|
|
||||||
|
- Node.js 20 LTS
|
||||||
|
- pnpm 10
|
||||||
|
- 后端 `RuoYi-Vue-master/cmvr-iot-admin`
|
||||||
|
|
||||||
|
## 开发运行
|
||||||
|
|
||||||
|
先启动后端,确认 `http://localhost:13080` 可以访问,然后执行:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 安装依赖
|
pnpm install
|
||||||
yarn --registry=https://registry.npmmirror.com
|
pnpm dev
|
||||||
|
|
||||||
# 启动服务
|
|
||||||
yarn dev
|
|
||||||
|
|
||||||
# 构建测试环境 yarn build:stage
|
|
||||||
# 构建生产环境 yarn build:prod
|
|
||||||
# 前端访问地址 http://localhost:80
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 内置功能
|
默认地址:
|
||||||
|
|
||||||
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
|
- 前端:`http://localhost:80`
|
||||||
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
|
- 后端:`http://localhost:13080`
|
||||||
3. 岗位管理:配置系统用户所属担任职务。
|
- Knife4j:`http://localhost:13080/doc.html`
|
||||||
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
|
|
||||||
5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
|
开发配置位于 `.env.development`:
|
||||||
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
|
|
||||||
7. 参数管理:对系统动态配置常用参数。
|
```dotenv
|
||||||
8. 通知公告:系统通知公告信息发布维护。
|
VITE_APP_TITLE=招商车研物联网平台管理系统
|
||||||
9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
|
VITE_APP_BASE_API=/dev-api
|
||||||
10. 登录日志:系统登录日志记录查询包含登录异常。
|
VITE_API_URL=http://localhost:13080
|
||||||
11. 在线用户:当前系统中活跃用户状态监控。
|
VITE_WS_URL=ws://localhost:13080/ws
|
||||||
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
|
VITE_PORT=80
|
||||||
13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
|
```
|
||||||
14. 系统接口:根据业务代码自动生成相关的api接口文档。
|
|
||||||
15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
|
## 构建
|
||||||
16. 缓存监控:对系统的缓存信息查询,命令统计等。
|
|
||||||
17. 在线构建器:拖动表单元素生成相应的HTML代码。
|
```bash
|
||||||
18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
|
pnpm build:dev
|
||||||
|
pnpm build:stage
|
||||||
|
pnpm build:prod
|
||||||
|
pnpm preview
|
||||||
|
```
|
||||||
|
|
||||||
|
生产构建输出到 `dist`。部署时需要由 Nginx 或网关转发 `/prod-api`,并支持 `/ws` WebSocket、文件上传和媒体请求。
|
||||||
|
|
||||||
|
## 目录说明
|
||||||
|
|
||||||
|
```text
|
||||||
|
public/models 机器人 URDF 和网格模型
|
||||||
|
public/inspection 巡检机械臂模型
|
||||||
|
src/adapters URDF/Xacro 模型适配
|
||||||
|
src/api REST API 封装
|
||||||
|
src/components 公共及业务组件
|
||||||
|
src/router 公共路由和隐藏业务路由
|
||||||
|
src/store Pinia 状态管理
|
||||||
|
src/views/device 设备管理与设备控制
|
||||||
|
src/views/test 测试业务
|
||||||
|
src/views/flow 流程编排
|
||||||
|
src/views/inspection 智能巡检
|
||||||
|
src/views/evaluate 评价管理
|
||||||
|
src/views/vi 语音交互
|
||||||
|
src/views/is 智能座舱
|
||||||
|
src/views/corpusManger 语料管理
|
||||||
|
```
|
||||||
|
|
||||||
|
业务菜单由后端 `/getRouters` 动态返回。数据库菜单中的 `component` 必须与 `src/views` 下的实际页面路径一致,权限字符必须与后端控制器保持一致。
|
||||||
|
|
||||||
|
## 配置说明
|
||||||
|
|
||||||
|
- `.env.development`:本地开发地址。
|
||||||
|
- `.env.staging`:测试环境地址。
|
||||||
|
- `.env.production`:生产环境地址、Node-RED 和 MinIO。
|
||||||
|
- `vite.config.js`:代理、端口、Monaco 和构建分包。
|
||||||
|
- `src/settings.js`:布局、页签和版权配置。
|
||||||
|
|
||||||
|
生产密码、访问密钥和内部网络配置应通过部署环境注入,不要提交新的敏感信息。
|
||||||
|
|||||||
12
bin/build.bat
Normal file
12
bin/build.bat
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
@echo off
|
||||||
|
echo.
|
||||||
|
echo [信息] 打包Web工程,生成dist文件。
|
||||||
|
echo.
|
||||||
|
|
||||||
|
%~d0
|
||||||
|
cd %~dp0
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
yarn build:prod
|
||||||
|
|
||||||
|
pause
|
||||||
12
bin/package.bat
Normal file
12
bin/package.bat
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
@echo off
|
||||||
|
echo.
|
||||||
|
echo [信息] 安装Web工程,生成node_modules文件。
|
||||||
|
echo.
|
||||||
|
|
||||||
|
%~d0
|
||||||
|
cd %~dp0
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
yarn --registry=https://registry.npmmirror.com
|
||||||
|
|
||||||
|
pause
|
||||||
12
bin/run-web.bat
Normal file
12
bin/run-web.bat
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
@echo off
|
||||||
|
echo.
|
||||||
|
echo [信息] 使用 Vite 命令运行 Web 工程。
|
||||||
|
echo.
|
||||||
|
|
||||||
|
%~d0
|
||||||
|
cd %~dp0
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
yarn dev
|
||||||
|
|
||||||
|
pause
|
||||||
@ -7,7 +7,7 @@
|
|||||||
<meta name="renderer" content="webkit">
|
<meta name="renderer" content="webkit">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
<link rel="icon" href="/favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<title>招商车研物联网平台管理系统</title>
|
<title>%VITE_APP_TITLE%</title>
|
||||||
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
|
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
|
||||||
<style>
|
<style>
|
||||||
html,
|
html,
|
||||||
|
|||||||
58
package.json
58
package.json
@ -1,32 +1,36 @@
|
|||||||
{
|
{
|
||||||
"name": "CMVR-IOT-UI",
|
"name": "cmvr-iot-aima",
|
||||||
"version": "3.8.8",
|
"version": "1.0.0",
|
||||||
"description": "CMVR-IOT平台管理系统前端UI框架",
|
"description": "招商车研物联网平台管理系统前端",
|
||||||
"author": "CMVR",
|
"author": "CMVR",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build:dev": "vite build --mode development",
|
"build:dev": "vite build --mode development",
|
||||||
"build:prod": "vite build --mode production",
|
"build:prod": "vite build",
|
||||||
"build:staging": "vite build --mode staging --verbose",
|
"build:stage": "vite build --mode staging",
|
||||||
|
"build:staging": "vite build --mode staging",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "2.3.1",
|
"@cmvr/iot-common": "1.0.0",
|
||||||
"@logicflow/core": "^2.0.13",
|
"@element-plus/icons-vue": "2.3.2",
|
||||||
"@logicflow/extension": "^2.0.18",
|
"@vue-flow/background": "^1.3.2",
|
||||||
|
"@vue-flow/controls": "^1.1.3",
|
||||||
|
"@vue-flow/core": "^1.48.2",
|
||||||
"@vueup/vue-quill": "1.2.0",
|
"@vueup/vue-quill": "1.2.0",
|
||||||
"@vueuse/core": "10.11.0",
|
"@vueuse/core": "14.1.0",
|
||||||
"ace-builds": "^1.43.0",
|
"ace-builds": "^1.43.0",
|
||||||
"axios": "0.28.1",
|
"autofit.js": "^3.2.8",
|
||||||
|
"axios": "1.13.2",
|
||||||
"clipboard": "2.0.11",
|
"clipboard": "2.0.11",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"echarts": "5.5.1",
|
"echarts": "5.6.0",
|
||||||
"element-plus": "2.9.4",
|
"element-plus": "2.13.1",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
"fuse.js": "6.6.2",
|
"fuse.js": "7.1.0",
|
||||||
"js-beautify": "1.14.11",
|
"js-beautify": "1.15.4",
|
||||||
"js-cookie": "3.0.5",
|
"js-cookie": "3.0.5",
|
||||||
"jsencrypt": "3.3.2",
|
"jsencrypt": "3.3.2",
|
||||||
"json-editor-vue": "^0.18.1",
|
"json-editor-vue": "^0.18.1",
|
||||||
@ -35,32 +39,38 @@
|
|||||||
"monaco-editor": "^0.55.1",
|
"monaco-editor": "^0.55.1",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"pako": "^2.1.0",
|
"pako": "^2.1.0",
|
||||||
"pinia": "2.1.7",
|
"pinia": "3.0.4",
|
||||||
"pnpm": "^10.23.0",
|
|
||||||
"socket.io-client": "^4.8.1",
|
"socket.io-client": "^4.8.1",
|
||||||
"sockjs-client": "^1.6.1",
|
"sockjs-client": "^1.6.1",
|
||||||
|
"sortablejs": "^1.15.6",
|
||||||
"splitpanes": "3.1.5",
|
"splitpanes": "3.1.5",
|
||||||
"three": "^0.181.2",
|
"three": "^0.181.2",
|
||||||
"urdf-loader": "^0.12.6",
|
"urdf-loader": "^0.12.6",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
"vue": "3.4.31",
|
"vue": "3.5.26",
|
||||||
"vue-cropper": "1.1.1",
|
"vue-cropper": "1.1.1",
|
||||||
"vue-router": "4.4.0",
|
"vue-router": "4.6.4",
|
||||||
"vue3-ace-editor": "^2.2.4",
|
"vue3-ace-editor": "^2.2.4",
|
||||||
"vue3-json-viewer": "2.3.0",
|
"vue3-json-viewer": "2.3.0",
|
||||||
"vuedraggable": "4.1.0",
|
"vuedraggable": "4.1.0",
|
||||||
|
"xacro-parser": "^0.3.11",
|
||||||
"xgplayer": "^3.0.22"
|
"xgplayer": "^3.0.22"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "5.0.5",
|
"@vitejs/plugin-vue": "5.2.4",
|
||||||
"file-loader": "^6.2.0",
|
"sass-embedded": "1.97.2",
|
||||||
"sass": "1.77.5",
|
"unplugin-auto-import": "0.18.6",
|
||||||
"unplugin-auto-import": "0.17.6",
|
|
||||||
"unplugin-vue-setup-extend-plus": "1.0.1",
|
"unplugin-vue-setup-extend-plus": "1.0.1",
|
||||||
"vite": "5.3.2",
|
"vite": "6.4.1",
|
||||||
"vite-plugin-compression": "0.5.1",
|
"vite-plugin-compression": "0.5.1",
|
||||||
"vite-plugin-monaco-editor": "^1.1.0",
|
"vite-plugin-monaco-editor": "^1.1.0",
|
||||||
"vite-plugin-svg-icons": "2.0.1"
|
"vite-plugin-svg-icons": "2.0.1"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@9.15.9+sha512.68046141893c66fad01c079231128e9afb89ef87e2691d69e4d40eee228988295fd4682181bae55b58418c3a253bde65a505ec7c5f9403ece5cc3cd37dcf2531"
|
"overrides": {
|
||||||
|
"quill": "2.0.2"
|
||||||
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"quill": "2.0.2"
|
||||||
|
},
|
||||||
|
"packageManager": "pnpm@10.24.0"
|
||||||
}
|
}
|
||||||
|
|||||||
6000
pnpm-lock.yaml
generated
Normal file
6000
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
6
pnpm-workspace.yaml
Normal file
6
pnpm-workspace.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
allowBuilds:
|
||||||
|
core-js: true
|
||||||
|
es5-ext: true
|
||||||
|
esbuild: true
|
||||||
|
json-editor-vue: true
|
||||||
|
vue-demi: true
|
||||||
465
public/inspection/elfin10/elfin10.urdf.xacro
Normal file
465
public/inspection/elfin10/elfin10.urdf.xacro
Normal file
@ -0,0 +1,465 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<robot name="elfin10" xmlns:xacro="http://wiki.ros.org/xacro">
|
||||||
|
|
||||||
|
<xacro:arg name="use_real_hardware" default="true" />
|
||||||
|
<xacro:arg name="use_fake_hardware" default="false" />
|
||||||
|
|
||||||
|
<!-- Load TRANSMISSION file: -->
|
||||||
|
<xacro:include filename="file://$(find elfin_description)/elfin10_transmission.xacro" />
|
||||||
|
<!-- Load GAZEBO/ROS2_CONTROL file: -->
|
||||||
|
<xacro:include filename="file://$(find elfin_description)/elfin10_gazebo.xacro" />
|
||||||
|
|
||||||
|
<xacro:property name="PI" value="3.1415926535897931"/>
|
||||||
|
|
||||||
|
<xacro:property name="density" value="3.09"/>
|
||||||
|
<!-- <xacro:macro name="elfin10"> -->
|
||||||
|
|
||||||
|
<!-- TRANSMISSION: -->
|
||||||
|
<xacro:elfin10_transmission />
|
||||||
|
<!-- GAZEBO - ROS2_CONTROL: -->
|
||||||
|
<xacro:elfin10_gazebo
|
||||||
|
use_real_hardware="$(arg use_real_hardware)"
|
||||||
|
use_fake_hardware="$(arg use_fake_hardware)"/>
|
||||||
|
|
||||||
|
<link name="world"/>
|
||||||
|
|
||||||
|
<joint name="world_base" type="fixed">
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 -1.5708" />
|
||||||
|
<parent
|
||||||
|
link="world" />
|
||||||
|
<child
|
||||||
|
link="elfin_base_link" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="elfin_base_link"/>
|
||||||
|
|
||||||
|
<joint name="elfin_base_joint" type="fixed">
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 ${PI/2}" />
|
||||||
|
<parent
|
||||||
|
link="elfin_base_link" />
|
||||||
|
<child
|
||||||
|
link="elfin_base" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link
|
||||||
|
name="elfin_base">
|
||||||
|
<inertial>
|
||||||
|
<origin
|
||||||
|
xyz="-0.00226511349377665 4.35718066723588E-06 0.0325128562537015"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<mass
|
||||||
|
value="1.66727740473724" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.004269288474386"
|
||||||
|
ixy="6.02518130623876E-08"
|
||||||
|
ixz="-6.92087963593712E-05"
|
||||||
|
iyy="0.00385585336301628"
|
||||||
|
iyz="-5.51423740998761E-08"
|
||||||
|
izz="0.0068204473327682" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_base.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material
|
||||||
|
name="">
|
||||||
|
<color
|
||||||
|
rgba="0.752941176470588 0.752941176470588 0.752941176470588 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_base.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
<link
|
||||||
|
name="elfin_link1">
|
||||||
|
<inertial>
|
||||||
|
<origin
|
||||||
|
xyz="7.61162863471406E-07 -0.00300107309756385 -0.0432743915921636"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<mass
|
||||||
|
value="6.3589066662676" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.0391771076676677"
|
||||||
|
ixy="5.46819690041203E-08"
|
||||||
|
ixz="4.18972540516346E-07"
|
||||||
|
iyy="0.0381555138034643"
|
||||||
|
iyz="0.00661206821297882"
|
||||||
|
izz="0.0211340101406971" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link1.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material
|
||||||
|
name="">
|
||||||
|
<color
|
||||||
|
rgba="0.752941176470588 0.752941176470588 0.752941176470588 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link1.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
<joint
|
||||||
|
name="elfin_joint1"
|
||||||
|
type="revolute">
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0.26"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<parent
|
||||||
|
link="elfin_base" />
|
||||||
|
<child
|
||||||
|
link="elfin_link1" />
|
||||||
|
<axis
|
||||||
|
xyz="0 0 1" />
|
||||||
|
<limit
|
||||||
|
lower="-3.14"
|
||||||
|
upper="3.14"
|
||||||
|
effort="420"
|
||||||
|
velocity="1.57" />
|
||||||
|
</joint>
|
||||||
|
<link
|
||||||
|
name="elfin_link2">
|
||||||
|
<inertial>
|
||||||
|
<origin
|
||||||
|
xyz="-1.29217317440473E-07 0.204406209458582 0.145205671136993"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<mass
|
||||||
|
value="5.51072381215317" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.140886684844275"
|
||||||
|
ixy="-1.98882818733046E-05"
|
||||||
|
ixz="1.28793862225363E-06"
|
||||||
|
iyy="0.00904523320332792"
|
||||||
|
iyz="0.00556623571013066"
|
||||||
|
izz="0.143882970137024" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link2.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material
|
||||||
|
name="">
|
||||||
|
<color
|
||||||
|
rgba="0.752941176470588 0.752941176470588 0.752941176470588 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link2.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
<joint
|
||||||
|
name="elfin_joint2"
|
||||||
|
type="revolute">
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="1.5708 0 0" />
|
||||||
|
<parent
|
||||||
|
link="elfin_link1" />
|
||||||
|
<child
|
||||||
|
link="elfin_link2" />
|
||||||
|
<axis
|
||||||
|
xyz="0 0 1" />
|
||||||
|
<limit
|
||||||
|
lower="-2.35"
|
||||||
|
upper="2.35"
|
||||||
|
effort="420"
|
||||||
|
velocity="1.57" />
|
||||||
|
</joint>
|
||||||
|
<link
|
||||||
|
name="elfin_link3">
|
||||||
|
<inertial>
|
||||||
|
<origin
|
||||||
|
xyz="0.0357493010718184 -2.74303992683623E-06 -0.00441107040289549"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<mass
|
||||||
|
value="3.25128088148268" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.00712273850158261"
|
||||||
|
ixy="4.14573354600121E-07"
|
||||||
|
ixz="-0.00240614658407673"
|
||||||
|
iyy="0.0131139013038093"
|
||||||
|
iyz="-1.53858261863385E-07"
|
||||||
|
izz="0.0123861174875263" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link3.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material
|
||||||
|
name="">
|
||||||
|
<color
|
||||||
|
rgba="0.752941176470588 0.752941176470588 0.752941176470588 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link3.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
<joint
|
||||||
|
name="elfin_joint3"
|
||||||
|
type="revolute">
|
||||||
|
<origin
|
||||||
|
xyz="0 0.48 0"
|
||||||
|
rpy="-3.1416 0 1.5708" />
|
||||||
|
<parent
|
||||||
|
link="elfin_link2" />
|
||||||
|
<child
|
||||||
|
link="elfin_link3" />
|
||||||
|
<axis
|
||||||
|
xyz="0 0 1" />
|
||||||
|
<limit
|
||||||
|
lower="-2.61"
|
||||||
|
upper="2.61"
|
||||||
|
effort="200"
|
||||||
|
velocity="1.57" />
|
||||||
|
</joint>
|
||||||
|
<link
|
||||||
|
name="elfin_link4">
|
||||||
|
<inertial>
|
||||||
|
<origin
|
||||||
|
xyz="3.8972274666868E-06 -0.065883038527668 0.300149807420176"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<mass
|
||||||
|
value="2.45076028364132" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.0366043963749035"
|
||||||
|
ixy="2.14481800816891E-07"
|
||||||
|
ixz="1.74370308297691E-06"
|
||||||
|
iyy="0.0331005868546169"
|
||||||
|
iyz="0.00876542795872678"
|
||||||
|
izz="0.00689303506560623" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link4.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material
|
||||||
|
name="">
|
||||||
|
<color
|
||||||
|
rgba="0.752941176470588 0.752941176470588 0.752941176470588 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link4.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
<joint
|
||||||
|
name="elfin_joint4"
|
||||||
|
type="revolute">
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="1.5708 0 1.5708" />
|
||||||
|
<parent
|
||||||
|
link="elfin_link3" />
|
||||||
|
<child
|
||||||
|
link="elfin_link4" />
|
||||||
|
<axis
|
||||||
|
xyz="0 0 1" />
|
||||||
|
<limit
|
||||||
|
lower="-3.14"
|
||||||
|
upper="3.14"
|
||||||
|
effort="200"
|
||||||
|
velocity="1.57" />
|
||||||
|
</joint>
|
||||||
|
<link
|
||||||
|
name="elfin_link5">
|
||||||
|
<inertial>
|
||||||
|
<origin
|
||||||
|
xyz="5.37084413168812E-06 -0.0262437975997385 -0.00353971828905618"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<mass
|
||||||
|
value="1.39234539037872" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.0033625821599978"
|
||||||
|
ixy="2.21090591006111E-07"
|
||||||
|
ixz="-5.5969383984273E-07"
|
||||||
|
iyy="0.00182229285631246"
|
||||||
|
iyz="0.000639319386824375"
|
||||||
|
izz="0.00292731816323284" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link5.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material
|
||||||
|
name="">
|
||||||
|
<color
|
||||||
|
rgba="0.752941176470588 0.752941176470588 0.752941176470588 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link5.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
<joint
|
||||||
|
name="elfin_joint5"
|
||||||
|
type="revolute">
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0.52"
|
||||||
|
rpy="-1.5708 0 0" />
|
||||||
|
<parent
|
||||||
|
link="elfin_link4" />
|
||||||
|
<child
|
||||||
|
link="elfin_link5" />
|
||||||
|
<axis
|
||||||
|
xyz="0 0 1" />
|
||||||
|
<limit
|
||||||
|
lower="-2.56"
|
||||||
|
upper="2.56"
|
||||||
|
effort="69"
|
||||||
|
velocity="1.57" />
|
||||||
|
</joint>
|
||||||
|
<link
|
||||||
|
name="elfin_link6">
|
||||||
|
<inertial>
|
||||||
|
<origin
|
||||||
|
xyz="-8.45231478862452E-06 -0.000388392932234965 0.144636177508013"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<mass
|
||||||
|
value="0.297803050744826" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000151919382929214"
|
||||||
|
ixy="-1.8598001023495E-09"
|
||||||
|
ixz="6.95653480101813E-08"
|
||||||
|
iyy="0.000155217204136347"
|
||||||
|
iyz="-6.63866631888914E-08"
|
||||||
|
izz="0.00027009779924127" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link6.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material
|
||||||
|
name="">
|
||||||
|
<color
|
||||||
|
rgba="0.752941176470588 0.752941176470588 0.752941176470588 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh
|
||||||
|
filename="file://$(find elfin_description)/meshes/elfin10/elfin_link6.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
<joint
|
||||||
|
name="elfin_joint6"
|
||||||
|
type="revolute">
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="1.5708 0 0" />
|
||||||
|
<parent
|
||||||
|
link="elfin_link5" />
|
||||||
|
<child
|
||||||
|
link="elfin_link6" />
|
||||||
|
<axis
|
||||||
|
xyz="0 0 1" />
|
||||||
|
<limit
|
||||||
|
lower="-3.14"
|
||||||
|
upper="3.14"
|
||||||
|
effort="69"
|
||||||
|
velocity="1.57" />
|
||||||
|
</joint>
|
||||||
|
<link
|
||||||
|
name="elfin_end_link"/>
|
||||||
|
<joint
|
||||||
|
name="elfin_end_joint"
|
||||||
|
type="fixed">
|
||||||
|
<origin
|
||||||
|
xyz="0 0.0 0.1735"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<parent
|
||||||
|
link="elfin_link6" />
|
||||||
|
<child
|
||||||
|
link="elfin_end_link" />
|
||||||
|
<axis
|
||||||
|
xyz="0 0 0" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="elfin_dummy_gripper"/>
|
||||||
|
|
||||||
|
<joint name="elfin_dummy_joint" type="fixed">
|
||||||
|
<origin
|
||||||
|
xyz="0 0.109 0"
|
||||||
|
rpy="${-PI/2} ${-PI/2} 0" />
|
||||||
|
<parent
|
||||||
|
link="elfin_link6" />
|
||||||
|
<child
|
||||||
|
link="elfin_dummy_gripper" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
</robot>
|
||||||
134
public/inspection/elfin10/elfin10_gazebo.xacro
Normal file
134
public/inspection/elfin10/elfin10_gazebo.xacro
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">
|
||||||
|
|
||||||
|
<xacro:macro name="elfin10_gazebo"
|
||||||
|
params="use_fake_hardware:=false
|
||||||
|
use_real_hardware:=true">
|
||||||
|
|
||||||
|
<gazebo>
|
||||||
|
<plugin filename="libgazebo_ros2_control.so" name="gazebo_ros2_control">
|
||||||
|
<robot_sim_type>gazebo_ros2_control/GazeboSystem</robot_sim_type>
|
||||||
|
<parameters>$(find elfin10_ros2_gazebo)/config/elfin_arm_controller.yaml</parameters>
|
||||||
|
</plugin>
|
||||||
|
</gazebo>
|
||||||
|
|
||||||
|
<ros2_control name="GazeboSystem" type="system">
|
||||||
|
|
||||||
|
<hardware>
|
||||||
|
<xacro:if value="${use_real_hardware}">
|
||||||
|
<plugin>elfin_hardware_interface/ElfinHWInterface</plugin>
|
||||||
|
</xacro:if>
|
||||||
|
|
||||||
|
<xacro:unless value="${use_real_hardware}">
|
||||||
|
<xacro:if value="${use_fake_hardware}">
|
||||||
|
<plugin>fake_components/GenericSystem</plugin>
|
||||||
|
</xacro:if>
|
||||||
|
|
||||||
|
<xacro:unless value="${use_fake_hardware}">
|
||||||
|
<plugin>gazebo_ros2_control/GazeboSystem</plugin>
|
||||||
|
</xacro:unless>
|
||||||
|
</xacro:unless>
|
||||||
|
</hardware>
|
||||||
|
|
||||||
|
|
||||||
|
<joint name="elfin_joint1">
|
||||||
|
<command_interface name="position">
|
||||||
|
<param name="min">-3.14</param>
|
||||||
|
<param name="max">3.14</param>
|
||||||
|
</command_interface>
|
||||||
|
<command_interface name="velocity">
|
||||||
|
<param name="min">-1.57</param>
|
||||||
|
<param name="max">1.57</param>
|
||||||
|
</command_interface>
|
||||||
|
<state_interface name="position"/>
|
||||||
|
<state_interface name="velocity"/>
|
||||||
|
</joint>
|
||||||
|
<joint name="elfin_joint2">
|
||||||
|
<command_interface name="position">
|
||||||
|
<param name="min">-2.35</param>
|
||||||
|
<param name="max">2.35</param>
|
||||||
|
</command_interface>
|
||||||
|
<command_interface name="velocity">
|
||||||
|
<param name="min">-1.57</param>
|
||||||
|
<param name="max">1.57</param>
|
||||||
|
</command_interface>
|
||||||
|
<state_interface name="position"/>
|
||||||
|
<state_interface name="velocity"/>
|
||||||
|
</joint>
|
||||||
|
<joint name="elfin_joint3">
|
||||||
|
<command_interface name="position">
|
||||||
|
<param name="min">-2.61</param>
|
||||||
|
<param name="max">2.61</param>
|
||||||
|
</command_interface>
|
||||||
|
<command_interface name="velocity">
|
||||||
|
<param name="min">-1.57</param>
|
||||||
|
<param name="max">1.57</param>
|
||||||
|
</command_interface>
|
||||||
|
<state_interface name="position"/>
|
||||||
|
<state_interface name="velocity"/>
|
||||||
|
</joint>
|
||||||
|
<joint name="elfin_joint4">
|
||||||
|
<command_interface name="position">
|
||||||
|
<param name="min">-3.14</param>
|
||||||
|
<param name="max">3.14</param>
|
||||||
|
</command_interface>
|
||||||
|
<command_interface name="velocity">
|
||||||
|
<param name="min">-1.57</param>
|
||||||
|
<param name="max">1.57</param>
|
||||||
|
</command_interface>
|
||||||
|
<state_interface name="position"/>
|
||||||
|
<state_interface name="velocity"/>
|
||||||
|
</joint>
|
||||||
|
<joint name="elfin_joint5">
|
||||||
|
<command_interface name="position">
|
||||||
|
<param name="min">-2.56</param>
|
||||||
|
<param name="max">2.56</param>
|
||||||
|
</command_interface>
|
||||||
|
<command_interface name="velocity">
|
||||||
|
<param name="min">-1.57</param>
|
||||||
|
<param name="max">1.57</param>
|
||||||
|
</command_interface>
|
||||||
|
<state_interface name="position"/>
|
||||||
|
<state_interface name="velocity"/>
|
||||||
|
</joint>
|
||||||
|
<joint name="elfin_joint6">
|
||||||
|
<command_interface name="position">
|
||||||
|
<param name="min">-3.14</param>
|
||||||
|
<param name="max">3.14</param>
|
||||||
|
</command_interface>
|
||||||
|
<command_interface name="velocity">
|
||||||
|
<param name="min">-1.57</param>
|
||||||
|
<param name="max">1.57</param>
|
||||||
|
</command_interface>
|
||||||
|
<state_interface name="position"/>
|
||||||
|
<state_interface name="velocity"/>
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
</ros2_control>
|
||||||
|
|
||||||
|
<gazebo reference="elfin_link2">
|
||||||
|
<visual name='visual'>
|
||||||
|
<material>
|
||||||
|
<script>
|
||||||
|
<uri>file://media/materials/scripts/gazebo.material</uri>
|
||||||
|
<name>Gazebo/Grey</name>
|
||||||
|
</script>
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
</gazebo>
|
||||||
|
|
||||||
|
<gazebo reference="elfin_link4">
|
||||||
|
<visual name='visual'>
|
||||||
|
<material>
|
||||||
|
<script>
|
||||||
|
<uri>file://media/materials/scripts/gazebo.material</uri>
|
||||||
|
<name>Gazebo/Grey</name>
|
||||||
|
</script>
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
</gazebo>
|
||||||
|
|
||||||
|
</xacro:macro>
|
||||||
|
|
||||||
|
</robot>
|
||||||
69
public/inspection/elfin10/elfin10_transmission.xacro
Normal file
69
public/inspection/elfin10/elfin10_transmission.xacro
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<robot xmlns:xacro="http://wiki.ros.org/xacro">
|
||||||
|
|
||||||
|
<xacro:macro name="elfin10_transmission" >
|
||||||
|
|
||||||
|
<transmission name="elfin_joint1_trans">
|
||||||
|
<type>transmission_interface/SimpleTransmission</type>
|
||||||
|
<joint name="elfin_joint1">
|
||||||
|
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
||||||
|
</joint>
|
||||||
|
<actuator name="elfin_joint1_motor">
|
||||||
|
<mechanicalReduction>1</mechanicalReduction>
|
||||||
|
</actuator>
|
||||||
|
</transmission>
|
||||||
|
|
||||||
|
<transmission name="elfin_joint2_trans">
|
||||||
|
<type>transmission_interface/SimpleTransmission</type>
|
||||||
|
<joint name="elfin_joint2">
|
||||||
|
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
||||||
|
</joint>
|
||||||
|
<actuator name="elfin_joint2_motor">
|
||||||
|
<mechanicalReduction>1</mechanicalReduction>
|
||||||
|
</actuator>
|
||||||
|
</transmission>
|
||||||
|
|
||||||
|
<transmission name="elfin_joint3_trans">
|
||||||
|
<type>transmission_interface/SimpleTransmission</type>
|
||||||
|
<joint name="elfin_joint3">
|
||||||
|
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
||||||
|
</joint>
|
||||||
|
<actuator name="elfin_joint3_motor">
|
||||||
|
<mechanicalReduction>1</mechanicalReduction>
|
||||||
|
</actuator>
|
||||||
|
</transmission>
|
||||||
|
|
||||||
|
<transmission name="elfin_joint4_trans">
|
||||||
|
<type>transmission_interface/SimpleTransmission</type>
|
||||||
|
<joint name="elfin_joint4">
|
||||||
|
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
||||||
|
</joint>
|
||||||
|
<actuator name="elfin_joint4_motor">
|
||||||
|
<mechanicalReduction>1</mechanicalReduction>
|
||||||
|
</actuator>
|
||||||
|
</transmission>
|
||||||
|
|
||||||
|
<transmission name="elfin_joint5_trans">
|
||||||
|
<type>transmission_interface/SimpleTransmission</type>
|
||||||
|
<joint name="elfin_joint5">
|
||||||
|
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
||||||
|
</joint>
|
||||||
|
<actuator name="elfin_joint5_motor">
|
||||||
|
<mechanicalReduction>1</mechanicalReduction>
|
||||||
|
</actuator>
|
||||||
|
</transmission>
|
||||||
|
|
||||||
|
<transmission name="elfin_joint6_trans">
|
||||||
|
<type>transmission_interface/SimpleTransmission</type>
|
||||||
|
<joint name="elfin_joint6">
|
||||||
|
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
|
||||||
|
</joint>
|
||||||
|
<actuator name="elfin_joint6_motor">
|
||||||
|
<mechanicalReduction>1</mechanicalReduction>
|
||||||
|
</actuator>
|
||||||
|
</transmission>
|
||||||
|
|
||||||
|
</xacro:macro>
|
||||||
|
|
||||||
|
</robot>
|
||||||
BIN
public/inspection/elfin10/meshes/elfin10/elfin_base.STL
Normal file
BIN
public/inspection/elfin10/meshes/elfin10/elfin_base.STL
Normal file
Binary file not shown.
BIN
public/inspection/elfin10/meshes/elfin10/elfin_end_link.STL
Normal file
BIN
public/inspection/elfin10/meshes/elfin10/elfin_end_link.STL
Normal file
Binary file not shown.
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link1.STL
Normal file
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link1.STL
Normal file
Binary file not shown.
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link2.STL
Normal file
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link2.STL
Normal file
Binary file not shown.
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link3.STL
Normal file
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link3.STL
Normal file
Binary file not shown.
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link4.STL
Normal file
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link4.STL
Normal file
Binary file not shown.
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link5.STL
Normal file
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link5.STL
Normal file
Binary file not shown.
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link6.STL
Normal file
BIN
public/inspection/elfin10/meshes/elfin10/elfin_link6.STL
Normal file
Binary file not shown.
660
public/models/dual_arm.urdf
Normal file
660
public/models/dual_arm.urdf
Normal file
@ -0,0 +1,660 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<robot name="dual_arm">
|
||||||
|
<mujoco>
|
||||||
|
<compiler
|
||||||
|
meshdir="meshes"
|
||||||
|
balanceinertia="true"
|
||||||
|
discardvisual="false" />
|
||||||
|
</mujoco>
|
||||||
|
|
||||||
|
|
||||||
|
<link name="base_link">
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0.6" rpy="0 0 0"/>
|
||||||
|
<geometry>
|
||||||
|
<cylinder radius="0.05" length="1.2"/>
|
||||||
|
</geometry>
|
||||||
|
<material name="gray">
|
||||||
|
<color rgba="0.5 0.5 0.5 1.0"/>
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0.6" rpy="0 0 0"/>
|
||||||
|
<geometry>
|
||||||
|
<cylinder radius="0.05" length="1.2"/>
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
|
||||||
|
<inertial>
|
||||||
|
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<mass value="25.4469"/>
|
||||||
|
|
||||||
|
<inertia
|
||||||
|
ixx="3.06953"
|
||||||
|
ixy="0.0"
|
||||||
|
ixz="0.0"
|
||||||
|
iyy="3.06953"
|
||||||
|
iyz="0.0"
|
||||||
|
izz="0.03181"/>
|
||||||
|
</inertial>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="base_fixed" type="fixed">
|
||||||
|
<origin rpy="0 0 0" xyz="0 0 1.2"/>
|
||||||
|
<parent link="base_link"/>
|
||||||
|
<child link="PELVIS_S"/>
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="PELVIS_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="3.78529087037144E-05 3.81781425684836E-07 0.0386396273530852" rpy="0 0 0" />
|
||||||
|
<mass value="2.10624590271277" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.00165706865324979"
|
||||||
|
ixy="3.13663044821662E-09"
|
||||||
|
ixz="6.84209533216046E-07"
|
||||||
|
iyy="0.00136736758630241"
|
||||||
|
iyz="-1.01014607878816E-10"
|
||||||
|
izz="0.00168295663089359" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/PELVIS_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.698039215686274 0.698039215686274 0.698039215686274 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/PELVIS_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<link name="L_SHOULDER_P_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00982258725282134 0.0704593083751867 1.15261874861217E-06" rpy="0 0 0" />
|
||||||
|
<mass value="0.880737519698403" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000583190308378148"
|
||||||
|
ixy="-1.53153074560473E-05"
|
||||||
|
ixz="6.58466471754072E-09"
|
||||||
|
iyy="0.000445532440067177"
|
||||||
|
iyz="6.37001404038516E-09"
|
||||||
|
izz="0.000465648071069952" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.898039215686275 0.917647058823529 0.929411764705882 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_SHOULDER_P" type="revolute">
|
||||||
|
<origin xyz="0 0.0945 0.042" rpy="0 0 0" />
|
||||||
|
<parent link="PELVIS_S" />
|
||||||
|
<child link="L_SHOULDER_P_S" />
|
||||||
|
<axis xyz="0 1 0" />
|
||||||
|
<limit lower="-1.57" upper="1.57" effort="120" velocity="3.351" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_SHOULDER_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0346025282975857 0.091739327988169 -1.67085072999562E-08" rpy="0 0 0" />
|
||||||
|
<mass value="0.594788424442483" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000380970396712656"
|
||||||
|
ixy="4.80751844573946E-05"
|
||||||
|
ixz="-1.34913746586865E-11"
|
||||||
|
iyy="0.000320962178597474"
|
||||||
|
iyz="-1.00039763442409E-09"
|
||||||
|
izz="0.000414771047901155" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_SHOULDER_R" type="revolute">
|
||||||
|
<origin xyz="0.035 0.0765 0" rpy="0 0 0" />
|
||||||
|
<parent link="L_SHOULDER_P_S" />
|
||||||
|
<child link="L_SHOULDER_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="-2" upper="2" effort="120" velocity="3.351" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_SHOULDER_Y_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00440976862014801 0.0863620459174068 9.50748668682166E-09"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<mass value="0.563406026626801" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000327003834287552"
|
||||||
|
ixy="-1.8057438966771E-05"
|
||||||
|
ixz="7.28778136267901E-10"
|
||||||
|
iyy="0.000213830709361531"
|
||||||
|
iyz="1.49273668517817E-10"
|
||||||
|
izz="0.000297341029639189" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_SHOULDER_Y" type="revolute">
|
||||||
|
<origin xyz="-0.035 0.1475 0" rpy="0 0 0" />
|
||||||
|
<parent link="L_SHOULDER_R_S" />
|
||||||
|
<child link="L_SHOULDER_Y_S" />
|
||||||
|
<axis xyz="0 1 0" />
|
||||||
|
<limit lower="-2.18" upper="0" effort="80" velocity="3.8758" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_ELBOW_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0335624237303443 0.0603199964106564 2.99655911639718E-07" rpy="0 0 0" />
|
||||||
|
<mass value="0.393571904406493" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.00017277119386253"
|
||||||
|
ixy="2.34549801867355E-05"
|
||||||
|
ixz="-1.90560556659271E-09"
|
||||||
|
iyy="0.000155340245267897"
|
||||||
|
iyz="8.82493073600007E-09"
|
||||||
|
izz="0.00018104232734159" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_ELBOW_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_ELBOW_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_ELBOW_R" type="revolute">
|
||||||
|
<origin xyz="0.034 0.1025 0" rpy="0 0 0" />
|
||||||
|
<parent link="L_SHOULDER_Y_S" />
|
||||||
|
<child link="L_ELBOW_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="-2.05" upper="0" effort="50" velocity="4.71" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_WRIST_P_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-1.39659173115092E-10 0.0675972604744393 0.019200551565574" rpy="0 0 0" />
|
||||||
|
<mass value="0.442332465815496" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000476754055455895"
|
||||||
|
ixy="-4.61505824713347E-15"
|
||||||
|
ixz="6.03808112272229E-18"
|
||||||
|
iyy="0.000103466585850499"
|
||||||
|
iyz="-4.88426705501198E-05"
|
||||||
|
izz="0.000482956345754213" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.698039215686274 0.698039215686274 0.698039215686274 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_WRIST_P" type="revolute">
|
||||||
|
<origin xyz="-0.034 0.0965 0" rpy="0 0 0" />
|
||||||
|
<parent link="L_ELBOW_R_S" />
|
||||||
|
<child link="L_WRIST_P_S" />
|
||||||
|
<axis xyz="0 1 0" />
|
||||||
|
<limit lower="0" upper="3.14" effort="50" velocity="4.71" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_WRIST_Y_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00464135887331864 -5.06426789392833E-10 -0.0341253783666609" rpy="0 0 0" />
|
||||||
|
<mass value="0.23573847772002" />
|
||||||
|
<inertia
|
||||||
|
ixx="5.10686940455785E-05"
|
||||||
|
ixy="7.45706654358429E-16"
|
||||||
|
ixz="6.2619568923368E-06"
|
||||||
|
iyy="6.00636019624519E-05"
|
||||||
|
iyz="1.27989654155383E-16"
|
||||||
|
izz="5.32182903609189E-05" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.647058823529412 0.619607843137255 0.588235294117647 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_WRIST_Y" type="revolute">
|
||||||
|
<origin xyz="0 0.1525 0.039" rpy="0 0 0" />
|
||||||
|
<parent link="L_WRIST_P_S" />
|
||||||
|
<child link="L_WRIST_Y_S" />
|
||||||
|
<axis xyz="0 0 1" />
|
||||||
|
<limit lower="-0.78" upper="0.78" effort="50" velocity="0.79" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_WRIST_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0161477357620243 0.0955046558857351 -0.00499392489444117" rpy="0 0 0" />
|
||||||
|
<mass value="0.504894112043562" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000186833711781125"
|
||||||
|
ixy="-3.99488705622731E-06"
|
||||||
|
ixz="-1.51920720398336E-06"
|
||||||
|
iyy="0.000179960980467837"
|
||||||
|
iyz="3.6992669535716E-06"
|
||||||
|
izz="0.000280756101568308" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_WRIST_R" type="revolute">
|
||||||
|
<origin xyz="0.0258 0 -0.039" rpy="0 0 0" />
|
||||||
|
<parent link="L_WRIST_Y_S" />
|
||||||
|
<child link="L_WRIST_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="-1.57" upper="0.26" effort="50" velocity="4.71" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_SHOULDER_P_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00982258725282141 -0.0704593093873431 -1.15069920925137E-06" rpy="0 0 0" />
|
||||||
|
<mass value="0.880737519698404" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000583190308378149"
|
||||||
|
ixy="1.53153074560471E-05"
|
||||||
|
ixz="-6.58466471736542E-09"
|
||||||
|
iyy="0.000445532440067178"
|
||||||
|
iyz="6.37001403998779E-09"
|
||||||
|
izz="0.000465648071069953" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_SHOULDER_P" type="revolute">
|
||||||
|
<origin xyz="0 -0.0945 0.042" rpy="0 0 0" />
|
||||||
|
<parent link="PELVIS_S" />
|
||||||
|
<child link="R_SHOULDER_P_S" />
|
||||||
|
<axis xyz="0 -1 0" />
|
||||||
|
<limit lower="-3.14" upper="3.14" effort="120" velocity="3.351" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_SHOULDER_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0346025282975784 -0.09173932900033 1.86280643132974E-08" rpy="0 0 0" />
|
||||||
|
<mass value="0.59478842444248" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000380970396712653"
|
||||||
|
ixy="-4.80751844573946E-05"
|
||||||
|
ixz="1.34913746041655E-11"
|
||||||
|
iyy="0.000320962178597472"
|
||||||
|
iyz="-1.00039763417375E-09"
|
||||||
|
izz="0.000414771047901152" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_SHOULDER_R" type="revolute">
|
||||||
|
<origin xyz="0.035 -0.0765 0" rpy="0 0 0" />
|
||||||
|
<parent link="R_SHOULDER_P_S" />
|
||||||
|
<child link="R_SHOULDER_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="-0.78" upper="1.57" effort="120" velocity="3.351" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_SHOULDER_Y_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00440976862014946 -0.0863620469295699 -7.58791862676134E-09" rpy="0 0 0" />
|
||||||
|
<mass value="0.563406026626801" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000327003834287551"
|
||||||
|
ixy="1.80574389667711E-05"
|
||||||
|
ixz="-7.28778136077729E-10"
|
||||||
|
iyy="0.000213830709361532"
|
||||||
|
iyz="1.49273668428957E-10"
|
||||||
|
izz="0.000297341029639189" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material
|
||||||
|
name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_SHOULDER_Y" type="revolute">
|
||||||
|
<origin xyz="-0.035 -0.1475 0" rpy="0 0 0" />
|
||||||
|
<parent link="R_SHOULDER_R_S" />
|
||||||
|
<child link="R_SHOULDER_Y_S" />
|
||||||
|
<axis xyz="0 -1 0" />
|
||||||
|
<limit lower="-3.14" upper="3.14" effort="80" velocity="3.8758" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_ELBOW_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0335624237303424 -0.0603199974228191 -2.97736340082455E-07" rpy="0 0 0" />
|
||||||
|
<mass value="0.393571904406492" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000172771193862529"
|
||||||
|
ixy="-2.34549801867353E-05"
|
||||||
|
ixz="1.90560556668771E-09"
|
||||||
|
iyy="0.000155340245267897"
|
||||||
|
iyz="8.82493073602971E-09"
|
||||||
|
izz="0.00018104232734159" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_ELBOW_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_ELBOW_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_ELBOW_R" type="revolute">
|
||||||
|
<origin xyz="0.034 -0.1025 0" rpy="0 0 0" />
|
||||||
|
<parent link="R_SHOULDER_Y_S" />
|
||||||
|
<child link="R_ELBOW_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="0" upper="2.05" effort="80" velocity="3.8758" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_WRIST_P_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-1.39656577968772E-10 -0.0675972614865965 0.0192005515655728" rpy="0 0 0" />
|
||||||
|
<mass value="0.442332465815497" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000476754055455896"
|
||||||
|
ixy="-4.61462558956188E-15"
|
||||||
|
ixz="-5.91762926004267E-18"
|
||||||
|
iyy="0.0001034665858505"
|
||||||
|
iyz="4.88426705501212E-05"
|
||||||
|
izz="0.000482956345754214" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.647058823529412 0.619607843137255 0.588235294117647 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_WRIST_P" type="revolute">
|
||||||
|
<origin xyz="-0.034 -0.0965 0" rpy="0 0 0" />
|
||||||
|
<parent link="R_ELBOW_R_S" />
|
||||||
|
<child link="R_WRIST_P_S" />
|
||||||
|
<axis xyz="0 -1 0" />
|
||||||
|
<limit lower="-3.14" upper="3.14" effort="50" velocity="4.71" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_WRIST_Y_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00464135887330083 -5.06426456325926E-10 -0.0341253783666614" rpy="0 0 0" />
|
||||||
|
<mass value="0.235738477720019" />
|
||||||
|
<inertia
|
||||||
|
ixx="5.1068694045578E-05"
|
||||||
|
ixy="7.45771487459288E-16"
|
||||||
|
ixz="6.26195689233664E-06"
|
||||||
|
iyy="6.00636019624515E-05"
|
||||||
|
iyz="1.27828046342987E-16"
|
||||||
|
izz="5.32182903609188E-05" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.647058823529412 0.619607843137255 0.588235294117647 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_WRIST_Y" type="revolute">
|
||||||
|
<origin xyz="0 -0.1525 0.039" rpy="0 0 0" />
|
||||||
|
<parent link="R_WRIST_P_S" />
|
||||||
|
<child link="R_WRIST_Y_S" />
|
||||||
|
<axis xyz="0 0 1" />
|
||||||
|
<limit lower="-0.78" upper="0.78" effort="50" velocity="0.79" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_WRIST_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0201642233698132 -0.11074968386657 -0.00598955339232021" rpy="0 0 0" />
|
||||||
|
<mass value="0.504366058218534" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000185559065855467"
|
||||||
|
ixy="5.75889766751509E-06"
|
||||||
|
ixz="2.40683898454438E-06"
|
||||||
|
iyy="0.000131246007872084"
|
||||||
|
iyz="1.60533277040148E-06"
|
||||||
|
izz="0.000271800951396149" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material
|
||||||
|
name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_WRIST_R" type="revolute">
|
||||||
|
<origin xyz="0.03 0 -0.039" rpy="0 0 0" />
|
||||||
|
<parent link="R_WRIST_Y_S" />
|
||||||
|
<child link="R_WRIST_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="-0.26" upper="1.57" effort="50" velocity="4.71" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_FINGER_TIP">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<mass value="0"/>
|
||||||
|
<inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6"/>
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<geometry>
|
||||||
|
<sphere radius="0.004"/>
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0 1 1 1"/> <!-- 绿色 -->
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<geometry>
|
||||||
|
<sphere radius="0.005"/>
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_FINGER_TIP_FIXED" type="fixed">
|
||||||
|
<origin xyz="0.00684256 -0.284077 0.00801525" rpy="0 0 0"/>
|
||||||
|
<parent link="R_WRIST_R_S"/>
|
||||||
|
<child link="R_FINGER_TIP"/>
|
||||||
|
<axis xyz="0 0 1"/>
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_CAM">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<mass value="0"/>
|
||||||
|
<inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6"/>
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<geometry>
|
||||||
|
<sphere radius="0.004"/>
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0 1 0 1"/> <!-- 绿色 -->
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<geometry>
|
||||||
|
<sphere radius="0.005"/>
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_CAM_FIXED" type="fixed">
|
||||||
|
<origin xyz="-0.01212 -0.17655 0.07506" rpy="-1.5707963267 0 3.1415926535"/>
|
||||||
|
<parent link="R_WRIST_R_S"/>
|
||||||
|
<child link="R_CAM"/>
|
||||||
|
<axis xyz="0 0 1"/>
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
</robot>
|
||||||
281
public/models/left_arm.urdf
Normal file
281
public/models/left_arm.urdf
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<robot name="left_arm">
|
||||||
|
<mujoco>
|
||||||
|
<compiler
|
||||||
|
meshdir="meshes"
|
||||||
|
balanceinertia="true"
|
||||||
|
discardvisual="false" />
|
||||||
|
</mujoco>
|
||||||
|
<link name="base_link">
|
||||||
|
<visual>
|
||||||
|
<geometry>
|
||||||
|
<cylinder radius="0.05" length="1.2"/>
|
||||||
|
</geometry>
|
||||||
|
<material name="gray">
|
||||||
|
<color rgba="0.5 0.5 0.5 1.0"/>
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<collision>
|
||||||
|
<geometry>
|
||||||
|
<cylinder radius="0.05" length="1.2"/>
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
|
||||||
|
<inertial>
|
||||||
|
<mass value="20.0"/>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="1.0" iyz="0.0" izz="1.0"/>
|
||||||
|
</inertial>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="base_fixed" type="fixed">
|
||||||
|
<origin rpy="0 0 0.0" xyz="0 0 0.6"/>
|
||||||
|
<parent link="base_link"/>
|
||||||
|
<child link="PELVIS_S"/>
|
||||||
|
<axis xyz="0 0 0"/>
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="PELVIS_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="3.78529087037144E-05 3.81781425684836E-07 0.0386396273530852" rpy="0 0 0" />
|
||||||
|
<mass value="2.10624590271277" />
|
||||||
|
<inertia ixx="0.00165706865324979" ixy="3.13663044821662E-09" ixz="6.84209533216046E-07" iyy="0.00136736758630241" iyz="-1.01014607878816E-10" izz="0.00168295663089359" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/PELVIS_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.698039215686274 0.698039215686274 0.698039215686274 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/PELVIS_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_SHOULDER_P" type="revolute">
|
||||||
|
<origin xyz="0 0.0945 0.042" rpy="0 0 0" />
|
||||||
|
<parent link="PELVIS_S" />
|
||||||
|
<child link="L_SHOULDER_P_S" />
|
||||||
|
<axis xyz="0 1 0" />
|
||||||
|
<limit lower="-3.14" upper="3.14" effort="100" velocity="3.351" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_SHOULDER_P_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00982258725282134 0.0704593083751867 1.15261874861217E-06" rpy="0 0 0" />
|
||||||
|
<mass value="0.880737519698403" />
|
||||||
|
<inertia ixx="0.000583190308378148" ixy="-1.53153074560473E-05" ixz="6.58466471754072E-09" iyy="0.000445532440067177" iyz="6.37001404038516E-09" izz="0.000465648071069952" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material
|
||||||
|
name="">
|
||||||
|
<color rgba="0.898039215686275 0.917647058823529 0.929411764705882 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_SHOULDER_R" type="revolute">
|
||||||
|
<origin xyz="0.035 0.0765 0" rpy="0 0 0" />
|
||||||
|
<parent link="L_SHOULDER_P_S" />
|
||||||
|
<child link="L_SHOULDER_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="-3.14" upper="3.14" effort="100" velocity="3.351" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_SHOULDER_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0346025282975857 0.091739327988169 -1.67085072999562E-08" rpy="0 0 0" />
|
||||||
|
<mass value="0.594788424442483" />
|
||||||
|
<inertia ixx="0.000380970396712656" ixy="4.80751844573946E-05" ixz="-1.34913746586865E-11" iyy="0.000320962178597474" iyz="-1.00039763442409E-09" izz="0.000414771047901155" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_SHOULDER_Y" type="revolute">
|
||||||
|
<origin xyz="-0.035 0.1475 0" rpy="0 0 0" />
|
||||||
|
<parent link="L_SHOULDER_R_S" />
|
||||||
|
<child link="L_SHOULDER_Y_S" />
|
||||||
|
<axis xyz="0 1 0" />
|
||||||
|
<limit lower="-3.14" upper="3.14" effort="49" velocity="3.8758" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_SHOULDER_Y_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00440976862014801 0.0863620459174068 9.50748668682166E-09" rpy="0 0 0" />
|
||||||
|
<mass value="0.563406026626801" />
|
||||||
|
<inertia ixx="0.000327003834287552" ixy="-1.8057438966771E-05" ixz="7.28778136267901E-10" iyy="0.000213830709361531" iyz="1.49273668517817E-10" izz="0.000297341029639189" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_SHOULDER_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_ELBOW_R" type="revolute">
|
||||||
|
<origin xyz="0.034 0.1025 0" rpy="0 0 0" />
|
||||||
|
<parent link="L_SHOULDER_Y_S" />
|
||||||
|
<child link="L_ELBOW_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="-3.14" upper="3.14" effort="49" velocity="3.8758" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_ELBOW_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0335624237303443 0.0603199964106564 2.99655911639718E-07" rpy="0 0 0" />
|
||||||
|
<mass value="0.393571904406493" />
|
||||||
|
<inertia ixx="0.00017277119386253" ixy="2.34549801867355E-05" ixz="-1.90560556659271E-09" iyy="0.000155340245267897" iyz="8.82493073600007E-09" izz="0.00018104232734159" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_ELBOW_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_ELBOW_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_WRIST_P" type="revolute">
|
||||||
|
<origin xyz="-0.034 0.0965 0" rpy="0 0 0" />
|
||||||
|
<parent link="L_ELBOW_R_S" />
|
||||||
|
<child link="L_WRIST_P_S" />
|
||||||
|
<axis xyz="0 1 0" />
|
||||||
|
<limit lower="-3.14" upper="3.14" effort="26" velocity="4.19" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_WRIST_P_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-1.39659173115092E-10 0.0675972604744393 0.019200551565574" rpy="0 0 0" />
|
||||||
|
<mass value="0.442332465815496" />
|
||||||
|
<inertia ixx="0.000476754055455895" ixy="-4.61505824713347E-15" ixz="6.03808112272229E-18" iyy="0.000103466585850499" iyz="-4.88426705501198E-05" izz="0.000482956345754213" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.698039215686274 0.698039215686274 0.698039215686274 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_WRIST_Y" type="revolute">
|
||||||
|
<origin xyz="0 0.1525 0.039" rpy="0 0 0" />
|
||||||
|
<parent link="L_WRIST_P_S" />
|
||||||
|
<child link="L_WRIST_Y_S" />
|
||||||
|
<axis xyz="0 0 1" />
|
||||||
|
<limit lower="-3.14" upper="3.14" effort="26" velocity="4.71" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_WRIST_Y_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00464135887331864 -5.06426789392833E-10 -0.0341253783666609" rpy="0 0 0" />
|
||||||
|
<mass value="0.23573847772002" />
|
||||||
|
<inertia ixx="5.10686940455785E-05" ixy="7.45706654358429E-16" ixz="6.2619568923368E-06" iyy="6.00636019624519E-05" iyz="1.27989654155383E-16" izz="5.32182903609189E-05" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.647058823529412 0.619607843137255 0.588235294117647 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="L_WRIST_R" type="revolute">
|
||||||
|
<origin xyz="0.0258 0 -0.039" rpy="0 0 0" />
|
||||||
|
<parent link="L_WRIST_Y_S" />
|
||||||
|
<child link="L_WRIST_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="-3.14" upper="3.14" effort="26" velocity="4.71" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="L_WRIST_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0161477357620243 0.0955046558857351 -0.00499392489444117" rpy="0 0 0" />
|
||||||
|
<mass value="0.504894112043562" />
|
||||||
|
<inertia ixx="0.000186833711781125" ixy="-3.99488705622731E-06" ixz="-1.51920720398336E-06" iyy="0.000179960980467837" iyz="3.6992669535716E-06" izz="0.000280756101568308" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/L_WRIST_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
|
||||||
|
</robot>
|
||||||
BIN
public/models/meshes/L_ELBOW_R_S.STL
Normal file
BIN
public/models/meshes/L_ELBOW_R_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/L_SHOULDER_P_S.STL
Normal file
BIN
public/models/meshes/L_SHOULDER_P_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/L_SHOULDER_R_S.STL
Normal file
BIN
public/models/meshes/L_SHOULDER_R_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/L_SHOULDER_Y_S.STL
Normal file
BIN
public/models/meshes/L_SHOULDER_Y_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/L_WRIST_P_S.STL
Normal file
BIN
public/models/meshes/L_WRIST_P_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/L_WRIST_R_S.STL
Normal file
BIN
public/models/meshes/L_WRIST_R_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/L_WRIST_Y_S.STL
Normal file
BIN
public/models/meshes/L_WRIST_Y_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/NECK_P_S.STL
Normal file
BIN
public/models/meshes/NECK_P_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/NECK_R_S.STL
Normal file
BIN
public/models/meshes/NECK_R_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/NECK_Y_S.STL
Normal file
BIN
public/models/meshes/NECK_Y_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/PELVIS_S.STL
Normal file
BIN
public/models/meshes/PELVIS_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/R_ELBOW_R_S.STL
Normal file
BIN
public/models/meshes/R_ELBOW_R_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/R_SHOULDER_P_S.STL
Normal file
BIN
public/models/meshes/R_SHOULDER_P_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/R_SHOULDER_R_S.STL
Normal file
BIN
public/models/meshes/R_SHOULDER_R_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/R_SHOULDER_Y_S.STL
Normal file
BIN
public/models/meshes/R_SHOULDER_Y_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/R_WRIST_P_S.STL
Normal file
BIN
public/models/meshes/R_WRIST_P_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/R_WRIST_R_S.STL
Normal file
BIN
public/models/meshes/R_WRIST_R_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/R_WRIST_Y_S.STL
Normal file
BIN
public/models/meshes/R_WRIST_Y_S.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/base_link.STL
Normal file
BIN
public/models/meshes/base_link.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/index_force_sensor_1.STL
Normal file
BIN
public/models/meshes/index_force_sensor_1.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/index_force_sensor_2.STL
Normal file
BIN
public/models/meshes/index_force_sensor_2.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/index_force_sensor_3.STL
Normal file
BIN
public/models/meshes/index_force_sensor_3.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/little_force_sensor_1.STL
Normal file
BIN
public/models/meshes/little_force_sensor_1.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/little_force_sensor_2.STL
Normal file
BIN
public/models/meshes/little_force_sensor_2.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/little_force_sensor_3.STL
Normal file
BIN
public/models/meshes/little_force_sensor_3.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/middle_force_sensor_1.STL
Normal file
BIN
public/models/meshes/middle_force_sensor_1.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/middle_force_sensor_2.STL
Normal file
BIN
public/models/meshes/middle_force_sensor_2.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/middle_force_sensor_3.STL
Normal file
BIN
public/models/meshes/middle_force_sensor_3.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/palm_force_sensor.STL
Normal file
BIN
public/models/meshes/palm_force_sensor.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_index_1.STL
Normal file
BIN
public/models/meshes/right_index_1.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_index_2.STL
Normal file
BIN
public/models/meshes/right_index_2.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_little_1.STL
Normal file
BIN
public/models/meshes/right_little_1.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_little_2.STL
Normal file
BIN
public/models/meshes/right_little_2.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_middle_1.STL
Normal file
BIN
public/models/meshes/right_middle_1.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_middle_2.STL
Normal file
BIN
public/models/meshes/right_middle_2.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_ring_1.STL
Normal file
BIN
public/models/meshes/right_ring_1.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_ring_2.STL
Normal file
BIN
public/models/meshes/right_ring_2.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_thumb_1.STL
Normal file
BIN
public/models/meshes/right_thumb_1.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_thumb_2.STL
Normal file
BIN
public/models/meshes/right_thumb_2.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_thumb_3.STL
Normal file
BIN
public/models/meshes/right_thumb_3.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/right_thumb_4.STL
Normal file
BIN
public/models/meshes/right_thumb_4.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/ring_force_sensor_1.STL
Normal file
BIN
public/models/meshes/ring_force_sensor_1.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/ring_force_sensor_2.STL
Normal file
BIN
public/models/meshes/ring_force_sensor_2.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/ring_force_sensor_3.STL
Normal file
BIN
public/models/meshes/ring_force_sensor_3.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/thumb_force_sensor_1.STL
Normal file
BIN
public/models/meshes/thumb_force_sensor_1.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/thumb_force_sensor_2.STL
Normal file
BIN
public/models/meshes/thumb_force_sensor_2.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/thumb_force_sensor_3.STL
Normal file
BIN
public/models/meshes/thumb_force_sensor_3.STL
Normal file
Binary file not shown.
BIN
public/models/meshes/thumb_force_sensor_4.STL
Normal file
BIN
public/models/meshes/thumb_force_sensor_4.STL
Normal file
Binary file not shown.
322
public/models/right_arm.urdf
Normal file
322
public/models/right_arm.urdf
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<robot name="right_arm">
|
||||||
|
<mujoco>
|
||||||
|
<compiler
|
||||||
|
meshdir="meshes"
|
||||||
|
balanceinertia="true"
|
||||||
|
discardvisual="false" />
|
||||||
|
</mujoco>
|
||||||
|
<link name="PELVIS_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="3.78529e-05 3.81781e-07 0.0386396" rpy="0 0 0"/>
|
||||||
|
<mass value="2.10624590271277"/>
|
||||||
|
<inertia
|
||||||
|
ixx="0.00165706865324979" ixy="3.13663e-09" ixz="6.84210e-07"
|
||||||
|
iyy="0.00136736758630241" iyz="-1.01015e-10" izz="0.00168295663089359"/>
|
||||||
|
</inertial>
|
||||||
|
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/PELVIS_S.STL"/>
|
||||||
|
</geometry>
|
||||||
|
<material name="light_gray">
|
||||||
|
<color rgba="0.698 0.698 0.698 1"/>
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/PELVIS_S.STL"/>
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<link name="R_SHOULDER_P_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00982258725282141 -0.0704593093873431 -1.15069920925137E-06" rpy="0 0 0" />
|
||||||
|
<mass value="0.880737519698404" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000583190308378149"
|
||||||
|
ixy="1.53153074560471E-05"
|
||||||
|
ixz="-6.58466471736542E-09"
|
||||||
|
iyy="0.000445532440067178"
|
||||||
|
iyz="6.37001403998779E-09"
|
||||||
|
izz="0.000465648071069953" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin
|
||||||
|
xyz="0 0 0"
|
||||||
|
rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_SHOULDER_P" type="revolute">
|
||||||
|
<origin xyz="0 -0.0945 0.042" rpy="0 0 0" />
|
||||||
|
<parent link="PELVIS_S" />
|
||||||
|
<child link="R_SHOULDER_P_S" />
|
||||||
|
<axis xyz="0 -1 0" />
|
||||||
|
<limit lower="-1.57" upper="1.57" effort="120" velocity="3.351" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_SHOULDER_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0346025282975784 -0.09173932900033 1.86280643132974E-08" rpy="0 0 0" />
|
||||||
|
<mass value="0.59478842444248" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000380970396712653" ixy="-4.80751844573946E-05" ixz="1.34913746041655E-11"
|
||||||
|
iyy="0.000320962178597472" iyz="-1.00039763417375E-09" izz="0.000414771047901152" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_SHOULDER_R" type="revolute">
|
||||||
|
<origin xyz="0.035 -0.0765 0" rpy="0 0 0" />
|
||||||
|
<parent link="R_SHOULDER_P_S" />
|
||||||
|
<child link="R_SHOULDER_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="-2" upper="2" effort="120" velocity="3.351" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_SHOULDER_Y_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00440976862014946 -0.0863620469295699 -7.58791862676134E-09" rpy="0 0 0" />
|
||||||
|
<mass value="0.563406026626801" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000327003834287551"
|
||||||
|
ixy="1.80574389667711E-05"
|
||||||
|
ixz="-7.28778136077729E-10"
|
||||||
|
iyy="0.000213830709361532"
|
||||||
|
iyz="1.49273668428957E-10"
|
||||||
|
izz="0.000297341029639189" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_SHOULDER_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_SHOULDER_Y" type="revolute">
|
||||||
|
<origin xyz="-0.035 -0.1475 0" rpy="0 0 0" />
|
||||||
|
<parent link="R_SHOULDER_R_S" />
|
||||||
|
<child link="R_SHOULDER_Y_S" />
|
||||||
|
<axis xyz="0 -1 0" />
|
||||||
|
<limit lower="0" upper="3.14" effort="80" velocity="3.8758" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_ELBOW_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0335624237303424 -0.0603199974228191 -2.97736340082455E-07" rpy="0 0 0" />
|
||||||
|
<mass value="0.393571904406492" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000172771193862529"
|
||||||
|
ixy="-2.34549801867353E-05"
|
||||||
|
ixz="1.90560556668771E-09"
|
||||||
|
iyy="0.000155340245267897"
|
||||||
|
iyz="8.82493073602971E-09"
|
||||||
|
izz="0.00018104232734159" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_ELBOW_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_ELBOW_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_ELBOW_R" type="revolute">
|
||||||
|
<origin xyz="0.034 -0.1025 0" rpy="0 0 0" />
|
||||||
|
<parent link="R_SHOULDER_Y_S" />
|
||||||
|
<child link="R_ELBOW_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="0" upper="2.18" effort="80" velocity="3.8758" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_WRIST_P_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-1.39656577968772E-10 -0.0675972614865965 0.0192005515655728" rpy="0 0 0" />
|
||||||
|
<mass value="0.442332465815497" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000476754055455896"
|
||||||
|
ixy="-4.61462558956188E-15"
|
||||||
|
ixz="-5.91762926004267E-18"
|
||||||
|
iyy="0.0001034665858505"
|
||||||
|
iyz="4.88426705501212E-05"
|
||||||
|
izz="0.000482956345754214" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.647058823529412 0.619607843137255 0.588235294117647 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_P_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_WRIST_P" type="revolute">
|
||||||
|
<origin xyz="-0.034 -0.0965 0" rpy="0 0 0" />
|
||||||
|
<parent link="R_ELBOW_R_S" />
|
||||||
|
<child link="R_WRIST_P_S" />
|
||||||
|
<axis xyz="0 -1 0" />
|
||||||
|
<limit lower="-3.14" upper="0" effort="50" velocity="4.71" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_WRIST_Y_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.00464135887330083 -5.06426456325926E-10 -0.0341253783666614" rpy="0 0 0" />
|
||||||
|
<mass value="0.235738477720019" />
|
||||||
|
<inertia
|
||||||
|
ixx="5.1068694045578E-05"
|
||||||
|
ixy="7.45771487459288E-16"
|
||||||
|
ixz="6.26195689233664E-06"
|
||||||
|
iyy="6.00636019624515E-05"
|
||||||
|
iyz="1.27828046342987E-16"
|
||||||
|
izz="5.32182903609188E-05" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.647058823529412 0.619607843137255 0.588235294117647 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_Y_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_WRIST_Y" type="revolute">
|
||||||
|
<origin xyz="0 -0.1525 0.039" rpy="0 0 0" />
|
||||||
|
<parent link="R_WRIST_P_S" />
|
||||||
|
<child link="R_WRIST_Y_S" />
|
||||||
|
<axis xyz="0 0 1" />
|
||||||
|
<limit lower="0" upper="0.78" effort="50" velocity="0.79" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_WRIST_R_S">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="-0.0201642233698132 -0.11074968386657 -0.00598955339232021" rpy="0 0 0" />
|
||||||
|
<mass value="0.204366058218534" />
|
||||||
|
<inertia
|
||||||
|
ixx="0.000185559065855467"
|
||||||
|
ixy="5.75889766751509E-06"
|
||||||
|
ixz="2.40683898454438E-06"
|
||||||
|
iyy="0.000131246007872084"
|
||||||
|
iyz="1.60533277040148E-06"
|
||||||
|
izz="0.000271800951396149" />
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0.890196078431372 0.890196078431372 0.913725490196078 1" />
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0" />
|
||||||
|
<geometry>
|
||||||
|
<mesh filename="meshes/R_WRIST_R_S.STL" />
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_WRIST_R" type="revolute">
|
||||||
|
<origin xyz="0.03 0 -0.039" rpy="0 0 0" />
|
||||||
|
<parent link="R_WRIST_Y_S" />
|
||||||
|
<child link="R_WRIST_R_S" />
|
||||||
|
<axis xyz="1 0 0" />
|
||||||
|
<limit lower="-0.26" upper="1.57" effort="50" velocity="4.71" />
|
||||||
|
</joint>
|
||||||
|
|
||||||
|
<link name="R_FINGER_TIP">
|
||||||
|
<inertial>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<mass value="0"/>
|
||||||
|
<inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6"/>
|
||||||
|
</inertial>
|
||||||
|
<visual>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<geometry>
|
||||||
|
<sphere radius="0.002"/>
|
||||||
|
</geometry>
|
||||||
|
<material name="">
|
||||||
|
<color rgba="0 1 0 1"/> <!-- 绿色 -->
|
||||||
|
</material>
|
||||||
|
</visual>
|
||||||
|
<collision>
|
||||||
|
<origin xyz="0 0 0" rpy="0 0 0"/>
|
||||||
|
<geometry>
|
||||||
|
<sphere radius="0.005"/>
|
||||||
|
</geometry>
|
||||||
|
</collision>
|
||||||
|
</link>
|
||||||
|
|
||||||
|
<joint name="R_FINGER_TIP_FIXED" type="fixed">
|
||||||
|
<origin xyz="-0.01212 -0.17655 0.07506" rpy="3.14159 0 -1.5708"/>
|
||||||
|
<parent link="R_WRIST_R_S"/>
|
||||||
|
<child link="R_FINGER_TIP"/>
|
||||||
|
</joint>
|
||||||
|
</robot>
|
||||||
461
src/adapters/URDFAdapter.js
Normal file
461
src/adapters/URDFAdapter.js
Normal file
@ -0,0 +1,461 @@
|
|||||||
|
/**
|
||||||
|
* URDF Adapter
|
||||||
|
* Converts urdf-loaders result to unified model
|
||||||
|
*/
|
||||||
|
import * as THREE from 'three';
|
||||||
|
import { UnifiedRobotModel, Link, Joint, JointLimits, VisualGeometry, CollisionGeometry, InertialProperties } from '@/models/UnifiedRobotModel.js';
|
||||||
|
|
||||||
|
export class URDFAdapter {
|
||||||
|
/**
|
||||||
|
* Convert urdf-loaders robot object to unified model
|
||||||
|
* @param {THREE.Group} robot - Robot object returned by urdf-loaders
|
||||||
|
* @param {string} urdfXML - Original URDF XML content (optional, for extracting inertial data)
|
||||||
|
* @returns {UnifiedRobotModel}
|
||||||
|
*/
|
||||||
|
static convert(robot, urdfXML = null) {
|
||||||
|
const model = new UnifiedRobotModel();
|
||||||
|
model.name = robot.name || 'robot';
|
||||||
|
model.threeObject = robot;
|
||||||
|
|
||||||
|
// Mark model type as URDF
|
||||||
|
if (!robot.userData) robot.userData = {};
|
||||||
|
robot.userData.type = 'urdf';
|
||||||
|
|
||||||
|
if (!robot.links || !robot.joints) {
|
||||||
|
console.warn('URDF model missing links or joints information');
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If XML provided, parse inertial data
|
||||||
|
let inertialData = {};
|
||||||
|
if (urdfXML) {
|
||||||
|
inertialData = this.parseInertialFromXML(urdfXML);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert links
|
||||||
|
Object.values(robot.links).forEach(urdfLink => {
|
||||||
|
const link = this.convertLink(urdfLink);
|
||||||
|
|
||||||
|
// If urdf-loader didn't parse inertial, get from XML
|
||||||
|
if (!link.inertial && inertialData[urdfLink.name]) {
|
||||||
|
link.inertial = inertialData[urdfLink.name];
|
||||||
|
}
|
||||||
|
|
||||||
|
model.addLink(link);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert joints
|
||||||
|
Object.values(robot.joints).forEach(urdfJoint => {
|
||||||
|
const joint = this.convertJoint(urdfJoint);
|
||||||
|
model.addJoint(joint);
|
||||||
|
});
|
||||||
|
|
||||||
|
// If XML provided, supplement effort and velocity from XML (urdf-loaders may not have parsed)
|
||||||
|
if (urdfXML) {
|
||||||
|
this.supplementJointLimitsFromXML(model, urdfXML);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find root link (link that is not a child of any joint)
|
||||||
|
const allChildren = new Set(
|
||||||
|
Array.from(model.joints.values()).map(j => j.child).filter(c => c)
|
||||||
|
);
|
||||||
|
const rootLinks = Array.from(model.links.keys()).filter(
|
||||||
|
name => !allChildren.has(name)
|
||||||
|
);
|
||||||
|
if (rootLinks.length > 0) {
|
||||||
|
model.rootLink = rootLinks[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enhance materials for better lighting (MuJoCo style)
|
||||||
|
this.enhanceMaterials(robot);
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enhance materials for better lighting (MuJoCo style)
|
||||||
|
* Applies consistent shininess and specular properties to all materials
|
||||||
|
* Directly modifies materials in place to ensure changes persist
|
||||||
|
*/
|
||||||
|
static enhanceMaterials(robotObject) {
|
||||||
|
robotObject.traverse((child) => {
|
||||||
|
if (child.isMesh && child.material) {
|
||||||
|
// Handle material arrays
|
||||||
|
if (Array.isArray(child.material)) {
|
||||||
|
child.material = child.material.map(mat => {
|
||||||
|
return this.enhanceSingleMaterial(mat);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
child.material = this.enhanceSingleMaterial(child.material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enhance a single material with better lighting properties
|
||||||
|
* Returns enhanced material (may be cloned or modified in place)
|
||||||
|
* Saves original properties for lighting toggle
|
||||||
|
*/
|
||||||
|
static enhanceSingleMaterial(material) {
|
||||||
|
if (material.isMeshPhongMaterial || material.isMeshStandardMaterial) {
|
||||||
|
// Save original properties if not already saved (for lighting toggle)
|
||||||
|
if (material.userData.originalShininess === undefined) {
|
||||||
|
material.userData.originalShininess = material.shininess !== undefined ? material.shininess : 30;
|
||||||
|
// IMPORTANT: Save original color to preserve URDF material colors
|
||||||
|
if (!material.userData.originalColor && material.color) {
|
||||||
|
material.userData.originalColor = material.color.clone();
|
||||||
|
}
|
||||||
|
// Save original specular - if material had no specular, save null
|
||||||
|
if (!material.specular) {
|
||||||
|
material.userData.originalSpecular = null;
|
||||||
|
} else if (material.specular.isColor) {
|
||||||
|
const spec = material.specular;
|
||||||
|
if (spec.r < 0.1 && spec.g < 0.1 && spec.b < 0.1) {
|
||||||
|
material.userData.originalSpecular = null; // Likely default
|
||||||
|
} else {
|
||||||
|
material.userData.originalSpecular = spec.clone();
|
||||||
|
}
|
||||||
|
} else if (typeof material.specular === 'number') {
|
||||||
|
if (material.specular === 0x111111 || material.specular < 0x111111) {
|
||||||
|
material.userData.originalSpecular = null;
|
||||||
|
} else {
|
||||||
|
material.userData.originalSpecular = new THREE.Color(material.specular);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
material.userData.originalSpecular = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMPORTANT: Preserve original color from URDF material definitions
|
||||||
|
// Do not modify material.color - urdf-loaders already sets the correct color
|
||||||
|
|
||||||
|
// Apply enhanced lighting (default enabled)
|
||||||
|
// Increase shininess for better highlights
|
||||||
|
if (material.shininess === undefined || material.shininess < 50) {
|
||||||
|
material.shininess = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enhance specular reflection - ensure it's a Color object with proper values
|
||||||
|
if (!material.specular) {
|
||||||
|
material.specular = new THREE.Color(0.3, 0.3, 0.3);
|
||||||
|
} else if (material.specular.isColor) {
|
||||||
|
// If it's already a Color object, update values
|
||||||
|
if (material.specular.r < 0.2 || material.specular.g < 0.2 || material.specular.b < 0.2) {
|
||||||
|
material.specular.setRGB(0.3, 0.3, 0.3);
|
||||||
|
}
|
||||||
|
} else if (typeof material.specular === 'number') {
|
||||||
|
// Convert number to Color object
|
||||||
|
if (material.specular < 0x333333) {
|
||||||
|
material.specular = new THREE.Color(0.3, 0.3, 0.3);
|
||||||
|
} else {
|
||||||
|
// Convert hex to Color
|
||||||
|
material.specular = new THREE.Color(material.specular);
|
||||||
|
if (material.specular.r < 0.2) {
|
||||||
|
material.specular.setRGB(0.3, 0.3, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark material as needing update
|
||||||
|
material.needsUpdate = true;
|
||||||
|
return material;
|
||||||
|
} else if (material.type === 'MeshBasicMaterial') {
|
||||||
|
// Convert MeshBasicMaterial to MeshPhongMaterial
|
||||||
|
const oldMaterial = material;
|
||||||
|
const envMap = typeof window !== 'undefined' && window.app?.sceneManager?.environmentManager?.getEnvironmentMap();
|
||||||
|
const newMaterial = new THREE.MeshPhongMaterial({
|
||||||
|
color: oldMaterial.color,
|
||||||
|
map: oldMaterial.map,
|
||||||
|
transparent: oldMaterial.transparent,
|
||||||
|
opacity: oldMaterial.opacity,
|
||||||
|
side: oldMaterial.side,
|
||||||
|
shininess: 50,
|
||||||
|
specular: new THREE.Color(0.3, 0.3, 0.3),
|
||||||
|
envMap: envMap || null,
|
||||||
|
reflectivity: envMap ? 0.3 : 0
|
||||||
|
});
|
||||||
|
// Save original properties for lighting toggle
|
||||||
|
newMaterial.userData.originalShininess = 30;
|
||||||
|
newMaterial.userData.originalSpecular = null; // MeshBasicMaterial had no specular
|
||||||
|
return newMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
static convertLink(urdfLink) {
|
||||||
|
const link = new Link(urdfLink.name);
|
||||||
|
link.threeObject = urdfLink;
|
||||||
|
|
||||||
|
// Convert inertial properties
|
||||||
|
if (urdfLink.inertial) {
|
||||||
|
link.inertial = this.convertInertial(urdfLink.inertial);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: urdf-loaders has already converted visual and collision to Three.js objects
|
||||||
|
// We mainly extract metadata, actual meshes are in threeObject
|
||||||
|
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
static convertJoint(urdfJoint) {
|
||||||
|
// URDF joint object has jointType property (not type)
|
||||||
|
const jointType = urdfJoint.jointType || urdfJoint.type || 'fixed';
|
||||||
|
const joint = new Joint(urdfJoint.name, jointType);
|
||||||
|
|
||||||
|
// Extract parent name (urdf-loader returns Three.js object reference)
|
||||||
|
joint.parent = urdfJoint.parent?.name || null;
|
||||||
|
|
||||||
|
// child may not be in urdfJoint.child, but in Three.js children array
|
||||||
|
// In Three.js scene graph, Joint is parent node, Child Link is Joint's child node
|
||||||
|
if (urdfJoint.child && urdfJoint.child.name) {
|
||||||
|
joint.child = urdfJoint.child.name;
|
||||||
|
} else if (urdfJoint.children && urdfJoint.children.length > 0) {
|
||||||
|
// Find Link object from children array
|
||||||
|
const childLink = urdfJoint.children.find(child =>
|
||||||
|
child.isURDFLink || child.type === 'URDFLink'
|
||||||
|
);
|
||||||
|
if (childLink) {
|
||||||
|
joint.child = childLink.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
joint.threeObject = urdfJoint;
|
||||||
|
|
||||||
|
// Convert origin
|
||||||
|
if (urdfJoint.origin) {
|
||||||
|
joint.origin = {
|
||||||
|
xyz: urdfJoint.origin.xyz || [0, 0, 0],
|
||||||
|
rpy: urdfJoint.origin.rpy || [0, 0, 0]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert axis
|
||||||
|
if (urdfJoint.axis) {
|
||||||
|
joint.axis = { xyz: urdfJoint.axis.xyz || [0, 0, 1] };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert limits
|
||||||
|
if (urdfJoint.limit) {
|
||||||
|
joint.limits = this.convertLimits(urdfJoint.limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current value
|
||||||
|
if (urdfJoint.angle !== undefined) {
|
||||||
|
joint.currentValue = urdfJoint.angle;
|
||||||
|
} else if (urdfJoint.jointValue !== undefined) {
|
||||||
|
joint.currentValue = urdfJoint.jointValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return joint;
|
||||||
|
}
|
||||||
|
|
||||||
|
static convertLimits(limit) {
|
||||||
|
const limits = new JointLimits();
|
||||||
|
if (limit.lower !== undefined) limits.lower = limit.lower;
|
||||||
|
if (limit.upper !== undefined) limits.upper = limit.upper;
|
||||||
|
if (limit.effort !== undefined) limits.effort = limit.effort;
|
||||||
|
if (limit.velocity !== undefined) limits.velocity = limit.velocity;
|
||||||
|
return limits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supplement joint effort and velocity information from URDF XML
|
||||||
|
* (because urdf-loaders may not have parsed these attributes)
|
||||||
|
*/
|
||||||
|
static supplementJointLimitsFromXML(model, urdfXML) {
|
||||||
|
try {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(urdfXML, 'text/xml');
|
||||||
|
|
||||||
|
const jointElements = doc.querySelectorAll('joint');
|
||||||
|
jointElements.forEach(jointEl => {
|
||||||
|
const jointName = jointEl.getAttribute('name');
|
||||||
|
const joint = model.joints.get(jointName);
|
||||||
|
|
||||||
|
if (joint) {
|
||||||
|
const limitEl = jointEl.querySelector('limit');
|
||||||
|
if (limitEl) {
|
||||||
|
if (!joint.limits) {
|
||||||
|
joint.limits = new JointLimits();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read effort and velocity
|
||||||
|
const effort = limitEl.getAttribute('effort');
|
||||||
|
const velocity = limitEl.getAttribute('velocity');
|
||||||
|
|
||||||
|
if (effort !== null) {
|
||||||
|
joint.limits.effort = parseFloat(effort);
|
||||||
|
}
|
||||||
|
if (velocity !== null) {
|
||||||
|
joint.limits.velocity = parseFloat(velocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also ensure lower and upper are correctly set
|
||||||
|
const lower = limitEl.getAttribute('lower');
|
||||||
|
const upper = limitEl.getAttribute('upper');
|
||||||
|
if (lower !== null) {
|
||||||
|
joint.limits.lower = parseFloat(lower);
|
||||||
|
}
|
||||||
|
if (upper !== null) {
|
||||||
|
joint.limits.upper = parseFloat(upper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to supplement joint limit information from XML:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static convertInertial(inertial) {
|
||||||
|
const props = new InertialProperties();
|
||||||
|
if (inertial.mass !== undefined) props.mass = inertial.mass;
|
||||||
|
if (inertial.origin) {
|
||||||
|
props.origin = {
|
||||||
|
xyz: inertial.origin.xyz || [0, 0, 0],
|
||||||
|
rpy: inertial.origin.rpy || [0, 0, 0]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (inertial.ixx !== undefined) props.ixx = inertial.ixx;
|
||||||
|
if (inertial.iyy !== undefined) props.iyy = inertial.iyy;
|
||||||
|
if (inertial.izz !== undefined) props.izz = inertial.izz;
|
||||||
|
if (inertial.ixy !== undefined) props.ixy = inertial.ixy;
|
||||||
|
if (inertial.ixz !== undefined) props.ixz = inertial.ixz;
|
||||||
|
if (inertial.iyz !== undefined) props.iyz = inertial.iyz;
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse inertial data from URDF XML
|
||||||
|
* @param {string} xmlContent - URDF XML content
|
||||||
|
* @returns {Object} Mapping from link names to inertial data
|
||||||
|
*/
|
||||||
|
static parseInertialFromXML(xmlContent) {
|
||||||
|
const inertialData = {};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const xmlDoc = parser.parseFromString(xmlContent, 'text/xml');
|
||||||
|
|
||||||
|
// Get all link elements
|
||||||
|
const links = xmlDoc.getElementsByTagName('link');
|
||||||
|
|
||||||
|
for (let i = 0; i < links.length; i++) {
|
||||||
|
const linkElement = links[i];
|
||||||
|
const linkName = linkElement.getAttribute('name');
|
||||||
|
|
||||||
|
// Find inertial element
|
||||||
|
const inertialElement = linkElement.getElementsByTagName('inertial')[0];
|
||||||
|
if (!inertialElement) continue;
|
||||||
|
|
||||||
|
const inertial = new InertialProperties();
|
||||||
|
|
||||||
|
// Parse mass
|
||||||
|
const massElement = inertialElement.getElementsByTagName('mass')[0];
|
||||||
|
if (massElement) {
|
||||||
|
inertial.mass = parseFloat(massElement.getAttribute('value'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse origin
|
||||||
|
const originElement = inertialElement.getElementsByTagName('origin')[0];
|
||||||
|
if (originElement) {
|
||||||
|
const xyz = originElement.getAttribute('xyz');
|
||||||
|
const rpy = originElement.getAttribute('rpy');
|
||||||
|
inertial.origin = {
|
||||||
|
xyz: xyz ? xyz.split(' ').map(parseFloat) : [0, 0, 0],
|
||||||
|
rpy: rpy ? rpy.split(' ').map(parseFloat) : [0, 0, 0]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
inertial.origin = { xyz: [0, 0, 0], rpy: [0, 0, 0] };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse inertia
|
||||||
|
const inertiaElement = inertialElement.getElementsByTagName('inertia')[0];
|
||||||
|
if (inertiaElement) {
|
||||||
|
inertial.ixx = parseFloat(inertiaElement.getAttribute('ixx')) || 0;
|
||||||
|
inertial.iyy = parseFloat(inertiaElement.getAttribute('iyy')) || 0;
|
||||||
|
inertial.izz = parseFloat(inertiaElement.getAttribute('izz')) || 0;
|
||||||
|
inertial.ixy = parseFloat(inertiaElement.getAttribute('ixy')) || 0;
|
||||||
|
inertial.ixz = parseFloat(inertiaElement.getAttribute('ixz')) || 0;
|
||||||
|
inertial.iyz = parseFloat(inertiaElement.getAttribute('iyz')) || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inertialData[linkName] = inertial;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to parse URDF XML inertial data:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return inertialData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set joint angle (using urdf-loaders' setJointValue method)
|
||||||
|
* Reference URDFClasses.js setJointValue implementation
|
||||||
|
*/
|
||||||
|
static setJointAngle(joint, angle, ignoreLimits = false) {
|
||||||
|
joint.currentValue = angle;
|
||||||
|
|
||||||
|
// URDF format: use urdf-loader's setJointValue method
|
||||||
|
if (joint.threeObject) {
|
||||||
|
// If ignoring limits, temporarily modify URDF joint object's limit values
|
||||||
|
let originalLimits = null;
|
||||||
|
if (ignoreLimits && joint.threeObject.limit) {
|
||||||
|
originalLimits = {
|
||||||
|
lower: joint.threeObject.limit.lower,
|
||||||
|
upper: joint.threeObject.limit.upper
|
||||||
|
};
|
||||||
|
joint.threeObject.limit.lower = -Math.PI * 2;
|
||||||
|
joint.threeObject.limit.upper = Math.PI * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefer setJointValue method (urdf-loader's standard method)
|
||||||
|
if (typeof joint.threeObject.setJointValue === 'function') {
|
||||||
|
joint.threeObject.setJointValue(angle);
|
||||||
|
|
||||||
|
// Restore original limits
|
||||||
|
if (originalLimits && joint.threeObject.limit) {
|
||||||
|
joint.threeObject.limit.lower = originalLimits.lower;
|
||||||
|
joint.threeObject.limit.upper = originalLimits.upper;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (typeof joint.threeObject.setAngle === 'function') {
|
||||||
|
joint.threeObject.setAngle(angle);
|
||||||
|
|
||||||
|
// Restore original limits
|
||||||
|
if (originalLimits && joint.threeObject.limit) {
|
||||||
|
joint.threeObject.limit.lower = originalLimits.lower;
|
||||||
|
joint.threeObject.limit.upper = originalLimits.upper;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore original limits (if none of the above methods executed)
|
||||||
|
if (originalLimits && joint.threeObject.limit) {
|
||||||
|
joint.threeObject.limit.lower = originalLimits.lower;
|
||||||
|
joint.threeObject.limit.upper = originalLimits.upper;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If none available, manually set rotation
|
||||||
|
// Note: For URDF, we usually shouldn't reach here, as urdf-loader should provide setJointValue
|
||||||
|
console.warn(`Joint ${joint.name} has no setJointValue or setAngle method, attempting manual setup`);
|
||||||
|
if (joint.type === 'revolute' || joint.type === 'continuous') {
|
||||||
|
const axis = joint.axis ? new THREE.Vector3(...joint.axis.xyz).normalize() : new THREE.Vector3(0, 0, 1);
|
||||||
|
// Note: joint.threeObject may not be a Three.js object, cannot directly set rotation
|
||||||
|
if (joint.threeObject.rotation) {
|
||||||
|
joint.threeObject.rotation.setFromAxisAngle(axis, angle);
|
||||||
|
}
|
||||||
|
} else if (joint.type === 'prismatic') {
|
||||||
|
const axis = joint.axis ? new THREE.Vector3(...joint.axis.xyz).normalize() : new THREE.Vector3(1, 0, 0);
|
||||||
|
if (joint.threeObject.position) {
|
||||||
|
joint.threeObject.position.copy(axis.multiplyScalar(angle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn(`Joint ${joint.name} has no threeObject`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
616
src/adapters/XacroAdapter.js
Normal file
616
src/adapters/XacroAdapter.js
Normal file
@ -0,0 +1,616 @@
|
|||||||
|
/**
|
||||||
|
* Xacro Adapter
|
||||||
|
*
|
||||||
|
* Parses ROS Xacro files and converts them to URDF format using xacro-parser.
|
||||||
|
*
|
||||||
|
* Supported Features:
|
||||||
|
* - Property definitions and substitutions (xacro:property)
|
||||||
|
* - Macro definitions with parameters (xacro:macro)
|
||||||
|
* - Conditional blocks (xacro:if, xacro:unless)
|
||||||
|
* - File inclusions (xacro:include) with package:// and relative paths
|
||||||
|
* - Python-style boolean constants (True/False)
|
||||||
|
* - Arithmetic expressions and property evaluation
|
||||||
|
*
|
||||||
|
* Compatibility:
|
||||||
|
* - ROS Jade and later (inOrder=true, requirePrefix=true, localProperties=true)
|
||||||
|
* - Automatically injects True/False constants for compatibility with ROS xacro files
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* - Upload all related xacro files (main file and included files)
|
||||||
|
* - The adapter automatically resolves file inclusions from the uploaded file map
|
||||||
|
* - Mesh files are resolved using package:// paths or relative paths
|
||||||
|
*/
|
||||||
|
import { XacroParser } from 'xacro-parser';
|
||||||
|
import { URDFAdapter } from './URDFAdapter.js';
|
||||||
|
|
||||||
|
export class XacroAdapter {
|
||||||
|
/**
|
||||||
|
* Parse xacro content and convert to unified model
|
||||||
|
* @param {string} xacroContent - Xacro file content
|
||||||
|
* @param {string} fileName - Xacro file name (for working path)
|
||||||
|
* @param {Map} fileMap - File map (path -> File object)
|
||||||
|
* @param {File} file - Original file object (optional)
|
||||||
|
* @returns {Promise<UnifiedRobotModel>}
|
||||||
|
*/
|
||||||
|
static async parse(xacroContent, fileName, fileMap = null, file = null) {
|
||||||
|
try {
|
||||||
|
// Create xacro parser
|
||||||
|
const parser = new XacroParser();
|
||||||
|
|
||||||
|
// Configure parser for ROS Jade and later (default settings)
|
||||||
|
parser.inOrder = true;
|
||||||
|
parser.requirePrefix = true;
|
||||||
|
parser.localProperties = true;
|
||||||
|
|
||||||
|
// Set working path (directory where xacro file is located)
|
||||||
|
const workingPath = fileName.includes('/')
|
||||||
|
? fileName.substring(0, fileName.lastIndexOf('/') + 1)
|
||||||
|
: '';
|
||||||
|
parser.workingPath = workingPath;
|
||||||
|
|
||||||
|
// Inject Python-style boolean constants as xacro properties
|
||||||
|
// Some xacro files use True/False (capitalized) in conditions
|
||||||
|
xacroContent = this.injectBooleanConstants(xacroContent);
|
||||||
|
|
||||||
|
// Extract and set xacro arguments with their default values
|
||||||
|
// Also add common ROS arguments that might be used without definition
|
||||||
|
const xacroArgs = this.extractXacroArguments(xacroContent);
|
||||||
|
|
||||||
|
// Add common ROS arguments with sensible defaults if not already defined
|
||||||
|
if (!xacroArgs.hasOwnProperty('DEBUG')) {
|
||||||
|
xacroArgs.DEBUG = 'false';
|
||||||
|
}
|
||||||
|
if (!xacroArgs.hasOwnProperty('SELF_COLLIDE')) {
|
||||||
|
xacroArgs.SELF_COLLIDE = 'false';
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.arguments = xacroArgs;
|
||||||
|
|
||||||
|
// If fileMap provided, setup custom file loader
|
||||||
|
if (fileMap) {
|
||||||
|
parser.getFileContents = async (path) => {
|
||||||
|
return await this.loadFileFromMap(path, fileMap, workingPath);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse xacro to URDF XML
|
||||||
|
const urdfXML = await parser.parse(xacroContent);
|
||||||
|
|
||||||
|
|
||||||
|
// Convert XMLDocument to string
|
||||||
|
const serializer = new XMLSerializer();
|
||||||
|
let urdfString = serializer.serializeToString(urdfXML);
|
||||||
|
|
||||||
|
// Clean up the XML string - remove empty xmlns attributes that might cause issues
|
||||||
|
urdfString = urdfString.replace(/\sxmlns=""/g, '');
|
||||||
|
|
||||||
|
// Re-parse the URDF string with DOMParser to create a clean XMLDocument
|
||||||
|
// This removes any xacro-specific nodes that urdf-loader might not handle
|
||||||
|
const domParser = new DOMParser();
|
||||||
|
const cleanUrdfXML = domParser.parseFromString(urdfString, 'text/xml');
|
||||||
|
|
||||||
|
// Check for parsing errors
|
||||||
|
const parseError = cleanUrdfXML.querySelector('parsererror');
|
||||||
|
if (parseError) {
|
||||||
|
throw new Error('Generated URDF has invalid XML: ' + parseError.textContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove problematic elements that urdf-loader might not handle well
|
||||||
|
// Remove gazebo elements (plugins, sensors, etc.)
|
||||||
|
const gazeboElements = cleanUrdfXML.querySelectorAll('gazebo');
|
||||||
|
gazeboElements.forEach(el => el.parentNode?.removeChild(el));
|
||||||
|
|
||||||
|
// Remove transmission elements (these are for Gazebo/ROS control)
|
||||||
|
const transmissionElements = cleanUrdfXML.querySelectorAll('transmission');
|
||||||
|
transmissionElements.forEach(el => el.parentNode?.removeChild(el));
|
||||||
|
|
||||||
|
// Remove visual/collision elements with empty geometry tags
|
||||||
|
this.removeEmptyGeometry(cleanUrdfXML);
|
||||||
|
|
||||||
|
// Clean up empty text nodes and comments that might cause issues
|
||||||
|
this.cleanXMLNodes(cleanUrdfXML.documentElement);
|
||||||
|
|
||||||
|
// Convert the clean XMLDocument back to string for URDFLoader
|
||||||
|
const finalUrdfString = serializer.serializeToString(cleanUrdfXML);
|
||||||
|
|
||||||
|
// Now use existing URDF loading infrastructure
|
||||||
|
// Import URDFLoader dynamically
|
||||||
|
const urdfModule = await import('urdf-loader');
|
||||||
|
const URDFLoader = urdfModule.URDFLoader || urdfModule.default || urdfModule;
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const loader = new URDFLoader();
|
||||||
|
loader.parseCollision = true;
|
||||||
|
|
||||||
|
// Extract directory where URDF file is located
|
||||||
|
const urdfDir = workingPath;
|
||||||
|
|
||||||
|
// If file map provided, setup resource loader (same as URDF loading)
|
||||||
|
if (fileMap) {
|
||||||
|
// Parse URDF content, find all used package names
|
||||||
|
const packages = this.extractPackagesFromURDF(finalUrdfString);
|
||||||
|
|
||||||
|
// Build package map
|
||||||
|
const packageMap = {};
|
||||||
|
packages.forEach(pkg => {
|
||||||
|
packageMap[pkg] = pkg;
|
||||||
|
});
|
||||||
|
packageMap[''] = '';
|
||||||
|
|
||||||
|
loader.packages = packageMap;
|
||||||
|
|
||||||
|
// Set URL Modifier (same as URDF loading)
|
||||||
|
const urlModifier = (url) => {
|
||||||
|
// Handle blob URLs
|
||||||
|
if (url.startsWith('blob:')) {
|
||||||
|
const blobMatch = url.match(/^blob:https?:\/\/[^\/]+\/(.+)$/);
|
||||||
|
if (blobMatch && blobMatch[1]) {
|
||||||
|
const fileName = blobMatch[1];
|
||||||
|
if (/\.(jpg|jpeg|png|gif|bmp|tga|tiff|webp|dae|stl|obj|gltf|glb)$/i.test(fileName)) {
|
||||||
|
url = fileName;
|
||||||
|
} else {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isTextureFile = /\.(jpg|jpeg|png|gif|bmp|tga|tiff|webp)$/i.test(url);
|
||||||
|
const isMeshFile = /\.(dae|stl|obj|gltf|glb)$/i.test(url);
|
||||||
|
|
||||||
|
let meshPath = url;
|
||||||
|
|
||||||
|
// Remove http:// or https:// prefix
|
||||||
|
if (meshPath.startsWith('http://') || meshPath.startsWith('https://')) {
|
||||||
|
try {
|
||||||
|
const urlObj = new URL(meshPath);
|
||||||
|
meshPath = urlObj.pathname;
|
||||||
|
if (meshPath.startsWith('/')) {
|
||||||
|
meshPath = meshPath.substring(1);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Invalid URL, use as-is
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove package:// prefix
|
||||||
|
if (meshPath.startsWith('package://')) {
|
||||||
|
meshPath = meshPath.replace(/^package:\/\//, '');
|
||||||
|
const parts = meshPath.split('/');
|
||||||
|
if (parts.length > 1) {
|
||||||
|
meshPath = parts.slice(1).join('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove leading ./
|
||||||
|
meshPath = meshPath.replace(/^\.\//, '');
|
||||||
|
|
||||||
|
// Handle relative paths
|
||||||
|
let normalizedPath = meshPath;
|
||||||
|
if (meshPath.includes('../')) {
|
||||||
|
const parts = meshPath.split('/');
|
||||||
|
const resolvedParts = [];
|
||||||
|
for (const part of parts) {
|
||||||
|
if (part === '..') {
|
||||||
|
resolvedParts.pop();
|
||||||
|
} else if (part !== '.' && part !== '') {
|
||||||
|
resolvedParts.push(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
normalizedPath = resolvedParts.join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build full path
|
||||||
|
const fullPath = urdfDir + normalizedPath;
|
||||||
|
const altPath = urdfDir + meshPath;
|
||||||
|
|
||||||
|
// Find file in fileMap
|
||||||
|
let matchedFile = fileMap.get(fullPath);
|
||||||
|
|
||||||
|
if (!matchedFile && altPath !== fullPath) {
|
||||||
|
matchedFile = fileMap.get(altPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matchedFile) {
|
||||||
|
matchedFile = fileMap.get(normalizedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matchedFile) {
|
||||||
|
matchedFile = fileMap.get(meshPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matchedFile) {
|
||||||
|
const targetFileName = normalizedPath.split('/').pop() || meshPath.split('/').pop();
|
||||||
|
for (const [key, file] of fileMap.entries()) {
|
||||||
|
const keyFileName = key.split('/').pop();
|
||||||
|
if (keyFileName === targetFileName) {
|
||||||
|
matchedFile = file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchedFile) {
|
||||||
|
const bloburl = URL.createObjectURL(matchedFile);
|
||||||
|
return bloburl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
};
|
||||||
|
|
||||||
|
loader.manager.setURLModifier(urlModifier);
|
||||||
|
|
||||||
|
// Custom loadMeshCb (same as URDF loading)
|
||||||
|
const originalLoadMeshCb = loader.loadMeshCb || loader.defaultMeshLoader.bind(loader);
|
||||||
|
loader.loadMeshCb = (path, manager, done) => {
|
||||||
|
this.findFileInMapByPath(path, fileMap, urdfDir).then(file => {
|
||||||
|
if (file) {
|
||||||
|
const ext = (file.name || path).toLowerCase().split('.').pop();
|
||||||
|
this.loadMeshFileAsync(file, ext, manager).then(meshObject => {
|
||||||
|
if (meshObject) {
|
||||||
|
done(meshObject, null);
|
||||||
|
} else {
|
||||||
|
done(null, new Error(`Failed to load mesh file: ${path}`));
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
console.error(`Failed to load mesh: ${path}`, err);
|
||||||
|
done(null, err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
let stlPath = path
|
||||||
|
stlPath = stlPath.replace('file:///', 'inspection/elfin10')
|
||||||
|
originalLoadMeshCb(path, manager, done);
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error(`Failed to find file: ${path}`, error);
|
||||||
|
originalLoadMeshCb(path, manager, done);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create temporary URL for URDF content
|
||||||
|
const blob = new Blob([finalUrdfString], { type: 'text/xml' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
loader.load(url, (robot) => {
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
|
||||||
|
// Convert to unified model using URDFAdapter
|
||||||
|
try {
|
||||||
|
const model = URDFAdapter.convert(robot, finalUrdfString);
|
||||||
|
resolve(model);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[XacroAdapter] URDF conversion error:', error);
|
||||||
|
reject(new Error('URDF conversion failed: ' + error.message));
|
||||||
|
}
|
||||||
|
}, undefined, (error) => {
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
console.error('[XacroAdapter] URDF loading error:', error);
|
||||||
|
reject(new Error('URDF loading failed: ' + (error.message || error)));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[XacroAdapter] Xacro parsing error:', error);
|
||||||
|
throw new Error('Xacro parsing failed: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load file from fileMap for xacro includes
|
||||||
|
* @param {string} path - File path
|
||||||
|
* @param {Map} fileMap - File map
|
||||||
|
* @param {string} workingPath - Working directory
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
static async loadFileFromMap(path, fileMap, workingPath) {
|
||||||
|
// Clean path - remove leading slash if present
|
||||||
|
let cleanPath = path;
|
||||||
|
// if (cleanPath.startsWith('/')) {
|
||||||
|
// cleanPath = cleanPath.substring(1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Remove leading ./
|
||||||
|
// cleanPath = cleanPath.replace(/^\.\//, '');
|
||||||
|
cleanPath = cleanPath.split('///')[1];
|
||||||
|
// Try different path combinations
|
||||||
|
const possiblePaths = [
|
||||||
|
cleanPath,
|
||||||
|
workingPath + cleanPath,
|
||||||
|
path,
|
||||||
|
workingPath + path.replace(/^\/+/, ''),
|
||||||
|
// Also try without the first directory component
|
||||||
|
cleanPath.includes('/') ? cleanPath.substring(cleanPath.indexOf('/') + 1) : cleanPath,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Try each path
|
||||||
|
for (const tryPath of possiblePaths) {
|
||||||
|
const file = fileMap.get(tryPath);
|
||||||
|
if (file) {
|
||||||
|
const content = await file.text();
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try filename only match
|
||||||
|
const fileName = cleanPath.split('/').pop();
|
||||||
|
for (const [key, file] of fileMap.entries()) {
|
||||||
|
const keyFileName = key.split('/').pop();
|
||||||
|
if (keyFileName === fileName) {
|
||||||
|
const content = await file.text();
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error('[XacroAdapter] Cannot find included file:', path);
|
||||||
|
throw new Error(`Cannot find included file: ${path}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove visual/collision elements with empty geometry tags
|
||||||
|
* xacro-parser may not fully expand conditional geometry (xacro:if)
|
||||||
|
* We'll just remove these empty visual elements rather than try to fix them
|
||||||
|
* @param {XMLDocument} xmlDoc - XML document to clean
|
||||||
|
*/
|
||||||
|
static removeEmptyGeometry(xmlDoc) {
|
||||||
|
// Find all geometry elements
|
||||||
|
const geometryElements = xmlDoc.querySelectorAll('geometry');
|
||||||
|
|
||||||
|
geometryElements.forEach(geom => {
|
||||||
|
// Check if geometry is empty (no child elements)
|
||||||
|
if (!geom.children || geom.children.length === 0) {
|
||||||
|
// Find the parent visual or collision element
|
||||||
|
let parent = geom.parentNode;
|
||||||
|
if (parent) {
|
||||||
|
const grandParent = parent.parentNode;
|
||||||
|
if (grandParent) {
|
||||||
|
if (parent.nodeName === 'visual' || parent.nodeName === 'collision') {
|
||||||
|
// Remove empty visual/collision elements
|
||||||
|
grandParent.removeChild(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively clean XML nodes - remove empty text nodes and comments
|
||||||
|
* @param {Element} element - Element to clean
|
||||||
|
*/
|
||||||
|
static cleanXMLNodes(element) {
|
||||||
|
if (!element || !element.childNodes) return;
|
||||||
|
|
||||||
|
const nodesToRemove = [];
|
||||||
|
|
||||||
|
// Collect nodes to remove
|
||||||
|
for (let i = 0; i < element.childNodes.length; i++) {
|
||||||
|
const node = element.childNodes[i];
|
||||||
|
|
||||||
|
// Remove comments
|
||||||
|
if (node.nodeType === Node.COMMENT_NODE) {
|
||||||
|
nodesToRemove.push(node);
|
||||||
|
}
|
||||||
|
// Remove empty or whitespace-only text nodes
|
||||||
|
else if (node.nodeType === Node.TEXT_NODE) {
|
||||||
|
if (!node.nodeValue || node.nodeValue.trim() === '') {
|
||||||
|
nodesToRemove.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Recursively clean element nodes
|
||||||
|
else if (node.nodeType === Node.ELEMENT_NODE) {
|
||||||
|
this.cleanXMLNodes(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove collected nodes
|
||||||
|
nodesToRemove.forEach(node => {
|
||||||
|
element.removeChild(node);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract package names from URDF content
|
||||||
|
* @param {string} urdfContent - URDF content
|
||||||
|
* @returns {Set<string>}
|
||||||
|
*/
|
||||||
|
static extractPackagesFromURDF(urdfContent) {
|
||||||
|
const packages = new Set();
|
||||||
|
const packageRegex = /package:\/\/([^\/]+)/g;
|
||||||
|
let match;
|
||||||
|
while ((match = packageRegex.exec(urdfContent)) !== null) {
|
||||||
|
packages.add(match[1]);
|
||||||
|
}
|
||||||
|
return packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find file in fileMap by path
|
||||||
|
* @param {string} path - File path
|
||||||
|
* @param {Map} fileMap - File map
|
||||||
|
* @param {string} urdfDir - URDF directory
|
||||||
|
* @returns {Promise<File|null>}
|
||||||
|
*/
|
||||||
|
static async findFileInMapByPath(path, fileMap, urdfDir) {
|
||||||
|
let meshPath = path;
|
||||||
|
|
||||||
|
// Remove blob: prefix
|
||||||
|
meshPath = meshPath.replace(/^blob:[^\/]+\//, '');
|
||||||
|
|
||||||
|
// Remove package:// prefix
|
||||||
|
if (meshPath.startsWith('package://')) {
|
||||||
|
meshPath = meshPath.replace(/^package:\/\//, '');
|
||||||
|
const parts = meshPath.split('/');
|
||||||
|
if (parts.length > 1) {
|
||||||
|
meshPath = parts.slice(1).join('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove leading ./
|
||||||
|
meshPath = meshPath.replace(/^\.\//, '');
|
||||||
|
|
||||||
|
// Build full path
|
||||||
|
const fullPath = urdfDir + meshPath;
|
||||||
|
|
||||||
|
// Try full path
|
||||||
|
let file = fileMap.get(fullPath);
|
||||||
|
if (file) return file;
|
||||||
|
|
||||||
|
// Try path without directory
|
||||||
|
file = fileMap.get(meshPath);
|
||||||
|
if (file) return file;
|
||||||
|
|
||||||
|
// Try filename match
|
||||||
|
const targetFileName = meshPath.split('/').pop();
|
||||||
|
for (const [key, f] of fileMap.entries()) {
|
||||||
|
const keyFileName = key.split('/').pop();
|
||||||
|
if (keyFileName === targetFileName) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load mesh file asynchronously
|
||||||
|
* @param {File} file - File object
|
||||||
|
* @param {string} ext - File extension
|
||||||
|
* @param {THREE.LoadingManager} manager - Loading manager
|
||||||
|
* @returns {Promise<THREE.Object3D>}
|
||||||
|
*/
|
||||||
|
static async loadMeshFileAsync(file, ext, manager) {
|
||||||
|
const THREE = await import('three');
|
||||||
|
const blobUrl = URL.createObjectURL(file);
|
||||||
|
|
||||||
|
try {
|
||||||
|
let meshObject = null;
|
||||||
|
|
||||||
|
switch (ext) {
|
||||||
|
case 'stl': {
|
||||||
|
const { STLLoader } = await import('three/examples/jsm/loaders/STLLoader.js');
|
||||||
|
const stlLoader = new STLLoader(manager);
|
||||||
|
const stlGeometry = await new Promise((resolve, reject) => {
|
||||||
|
stlLoader.load(blobUrl, resolve, undefined, reject);
|
||||||
|
});
|
||||||
|
const stlMaterial = new THREE.MeshPhongMaterial();
|
||||||
|
meshObject = new THREE.Mesh(stlGeometry, stlMaterial);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'dae': {
|
||||||
|
const { ColladaLoader } = await import('three/examples/jsm/loaders/ColladaLoader.js');
|
||||||
|
const colladaLoader = new ColladaLoader(manager);
|
||||||
|
const colladaModel = await new Promise((resolve, reject) => {
|
||||||
|
colladaLoader.load(blobUrl, resolve, undefined, reject);
|
||||||
|
});
|
||||||
|
meshObject = colladaModel.scene;
|
||||||
|
|
||||||
|
// Remove lights
|
||||||
|
if (meshObject && meshObject.traverse) {
|
||||||
|
const lightsToRemove = [];
|
||||||
|
meshObject.traverse(child => {
|
||||||
|
if (child.isLight) {
|
||||||
|
lightsToRemove.push(child);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lightsToRemove.forEach(light => {
|
||||||
|
if (light.parent) {
|
||||||
|
light.parent.remove(light);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'obj': {
|
||||||
|
const { OBJLoader } = await import('three/examples/jsm/loaders/OBJLoader.js');
|
||||||
|
const objLoader = new OBJLoader(manager);
|
||||||
|
meshObject = await new Promise((resolve, reject) => {
|
||||||
|
objLoader.load(blobUrl, resolve, undefined, reject);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'gltf':
|
||||||
|
case 'glb': {
|
||||||
|
const { GLTFLoader } = await import('three/examples/jsm/loaders/GLTFLoader.js');
|
||||||
|
const gltfLoader = new GLTFLoader(manager);
|
||||||
|
const gltfModel = await new Promise((resolve, reject) => {
|
||||||
|
gltfLoader.load(blobUrl, resolve, undefined, reject);
|
||||||
|
});
|
||||||
|
meshObject = gltfModel.scene;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.warn(`Unsupported file format: ${ext}`);
|
||||||
|
URL.revokeObjectURL(blobUrl);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
URL.revokeObjectURL(blobUrl);
|
||||||
|
return meshObject;
|
||||||
|
} catch (error) {
|
||||||
|
URL.revokeObjectURL(blobUrl);
|
||||||
|
console.error(`Failed to load mesh file: ${file.name}`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject Python-style boolean constants (True/False) into xacro content
|
||||||
|
* Some xacro files use capitalized True/False in conditional expressions
|
||||||
|
* The parameters are passed as strings ("True", "False") but compared to constants
|
||||||
|
* We define the constants to match the string values for comparison to work
|
||||||
|
* @param {string} xacroContent - Original xacro content
|
||||||
|
* @returns {string} - Modified xacro content with boolean constants defined
|
||||||
|
*/
|
||||||
|
static injectBooleanConstants(xacroContent) {
|
||||||
|
// Find the robot tag opening
|
||||||
|
const robotTagMatch = xacroContent.match(/(<robot[^>]*>)/);
|
||||||
|
if (!robotTagMatch) {
|
||||||
|
return xacroContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define True/False as string properties for comparison
|
||||||
|
// When mirror_dae="True" is passed, it becomes the string "True"
|
||||||
|
// We want ${mirror_dae == True} to work, so True must also be "True"
|
||||||
|
const booleanProperties = `
|
||||||
|
<!-- Injected by XacroAdapter: Python-style boolean constants -->
|
||||||
|
<xacro:property name="True" value="True"/>
|
||||||
|
<xacro:property name="False" value="False"/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const insertPosition = robotTagMatch.index + robotTagMatch[0].length;
|
||||||
|
return xacroContent.substring(0, insertPosition) +
|
||||||
|
booleanProperties +
|
||||||
|
xacroContent.substring(insertPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract xacro arguments and their default values from xacro content
|
||||||
|
* Xacro files can define arguments using <xacro:arg name="..." default="..."/>
|
||||||
|
* These need to be provided to the parser via parser.arguments
|
||||||
|
* @param {string} xacroContent - Xacro file content
|
||||||
|
* @returns {Object} - Object with argument names as keys and default values
|
||||||
|
*/
|
||||||
|
static extractXacroArguments(xacroContent) {
|
||||||
|
const args = {};
|
||||||
|
|
||||||
|
// Match <xacro:arg name="NAME" default="VALUE"/>
|
||||||
|
// Also match <arg name="NAME" default="VALUE"/> (without xacro: prefix)
|
||||||
|
const argPattern = /<(?:xacro:)?arg\s+name=["']([^"']+)["'](?:\s+default=["']([^"']*)["'])?/g;
|
||||||
|
|
||||||
|
let match;
|
||||||
|
while ((match = argPattern.exec(xacroContent)) !== null) {
|
||||||
|
const argName = match[1];
|
||||||
|
const defaultValue = match[2] || 'false'; // Default to 'false' if no default specified
|
||||||
|
args[argName] = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
46
src/api/corpusManger/corpus.js
Normal file
46
src/api/corpusManger/corpus.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function addCategory(data) {
|
||||||
|
return request({
|
||||||
|
url: '/tts/corpus/category',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCategoryTreeApi() {
|
||||||
|
return request({
|
||||||
|
url: '/tts/corpus/category/tree',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateCategoryTreeApi(data) {
|
||||||
|
return request({
|
||||||
|
url: '/tts/corpus/category',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteCategory(id) {
|
||||||
|
return request({
|
||||||
|
url: `/tts/corpus/category/${id}`,
|
||||||
|
method: 'delete',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCorpusListApi(params) {
|
||||||
|
return request({
|
||||||
|
url: '/tts/corpus/list',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDashboardApi() {
|
||||||
|
return request({
|
||||||
|
url: '/tts/corpus/dashboard/stats',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
69
src/api/corpusManger/speech_synthesis.js
Normal file
69
src/api/corpusManger/speech_synthesis.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function taskApi(data) {
|
||||||
|
return request({
|
||||||
|
url: '/tts/task',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function taskListApi(params) {
|
||||||
|
return request({
|
||||||
|
url: '/tts/task/list',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDashboardApi(params) {
|
||||||
|
return request({
|
||||||
|
url: '/tts/task/dashboard/stats',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function downloadWavApi(id) {
|
||||||
|
return request({
|
||||||
|
url: `/tts/task/audio/${id}`,
|
||||||
|
method: 'get',
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteTask(ids) {
|
||||||
|
return request({
|
||||||
|
url: `/tts/task/${ids}`,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function regenerateApi(id) {
|
||||||
|
return request({
|
||||||
|
url: `/tts/task/regenerate/${id}`,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generalizationApi(data) {
|
||||||
|
return request({
|
||||||
|
url: '/tts/task/llm/query',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function batchTaskApi(data) {
|
||||||
|
return request({
|
||||||
|
url: '/tts/task/batch',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function saveTaskApi(data) {
|
||||||
|
return request({
|
||||||
|
url: `/tts/task/save-to-corpus/${data.taskId}/${data.categoryId}`,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -16,3 +16,11 @@ export function status(data) {
|
|||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function clearFault(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/arm/clearFault',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
9
src/api/device/camera.js
Normal file
9
src/api/device/camera.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function getRgbStreamUrl(robotId, deviceId) {
|
||||||
|
return request({
|
||||||
|
url: '/api/edge/camera/rgb-stream-url',
|
||||||
|
method: 'get',
|
||||||
|
params: { robotId, deviceId }
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -1,45 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询设备配置信息列表
|
|
||||||
export function listProfile(query) {
|
|
||||||
return request({
|
|
||||||
url: '/device/profile/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询设备配置信息详细
|
|
||||||
export function getProfile(query) {
|
|
||||||
return request({
|
|
||||||
url: '/device/profile/parameterInfo/',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增设备配置信息
|
|
||||||
export function addProfile(data) {
|
|
||||||
return request({
|
|
||||||
url: '/device/profile',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改设备配置信息
|
|
||||||
export function updateProfile(data) {
|
|
||||||
return request({
|
|
||||||
url: '/device/profile',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除设备配置信息
|
|
||||||
export function delProfile(id) {
|
|
||||||
return request({
|
|
||||||
url: '/device/profile/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询设备注册列表
|
|
||||||
export function listRegister(query) {
|
|
||||||
return request({
|
|
||||||
url: '/device/register/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询设备注册详细
|
|
||||||
export function getRegister(id) {
|
|
||||||
return request({
|
|
||||||
url: '/device/register/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增设备注册
|
|
||||||
export function addRegister(data) {
|
|
||||||
return request({
|
|
||||||
url: '/device/register',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改设备注册
|
|
||||||
export function updateRegister(data) {
|
|
||||||
return request({
|
|
||||||
url: '/device/register',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除设备注册
|
|
||||||
export function delRegister(id) {
|
|
||||||
return request({
|
|
||||||
url: '/device/register/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设备示教
|
|
||||||
export function deviceTeach(id) {
|
|
||||||
return request({
|
|
||||||
url: '/device/profile/' + id,
|
|
||||||
method: 'get',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设备示教参数修改
|
|
||||||
export function deviceUpdateProfile(data) {
|
|
||||||
return request({
|
|
||||||
url: '/device/profile/updateProfile',
|
|
||||||
method: 'put',
|
|
||||||
data: data,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增音色
|
|
||||||
export function createTimbre(data) {
|
|
||||||
return request({
|
|
||||||
url: '/show/tts/create',
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data',
|
|
||||||
Authorization: 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImFiNmEyY2Y0LWM3MjQtNDgyMy1hM2NiLTk4N2NhZWNmMzZiNCJ9.oq-JVRbQuq_ujQ2V0h2jXC3woHPdMQKhnYJ8ixRm-C6Ez4GqJWyHYgmnkw5dbDyhWGdIUH02uv6XT8UiboHD4g',
|
|
||||||
isToken: false
|
|
||||||
},
|
|
||||||
data: data,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取音色
|
|
||||||
export function getTts() {
|
|
||||||
return request({
|
|
||||||
url: '/show/tts/query',
|
|
||||||
headers: {
|
|
||||||
Authorization: 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImFiNmEyY2Y0LWM3MjQtNDgyMy1hM2NiLTk4N2NhZWNmMzZiNCJ9.oq-JVRbQuq_ujQ2V0h2jXC3woHPdMQKhnYJ8ixRm-C6Ez4GqJWyHYgmnkw5dbDyhWGdIUH02uv6XT8UiboHD4g',
|
|
||||||
isToken: false
|
|
||||||
},
|
|
||||||
method: 'get',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生产语料
|
|
||||||
export function createCorpus(data) {
|
|
||||||
return request({
|
|
||||||
url: '/show/tts/corpus',
|
|
||||||
headers: {
|
|
||||||
Authorization: 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImFiNmEyY2Y0LWM3MjQtNDgyMy1hM2NiLTk4N2NhZWNmMzZiNCJ9.oq-JVRbQuq_ujQ2V0h2jXC3woHPdMQKhnYJ8ixRm-C6Ez4GqJWyHYgmnkw5dbDyhWGdIUH02uv6XT8UiboHD4g',
|
|
||||||
isToken: false
|
|
||||||
},
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getSynthesize(data, config = {}) {
|
|
||||||
return request({
|
|
||||||
url: '/show/tts/synthesize',
|
|
||||||
headers: {
|
|
||||||
Authorization: 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImFiNmEyY2Y0LWM3MjQtNDgyMy1hM2NiLTk4N2NhZWNmMzZiNCJ9.oq-JVRbQuq_ujQ2V0h2jXC3woHPdMQKhnYJ8ixRm-C6Ez4GqJWyHYgmnkw5dbDyhWGdIUH02uv6XT8UiboHD4g',
|
|
||||||
isToken: false
|
|
||||||
},
|
|
||||||
responseType: 'blob',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
}, {
|
|
||||||
...config
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createAdvancedCorpus(data) {
|
|
||||||
return request({
|
|
||||||
url: '/show/tts/corpus/advanced',
|
|
||||||
headers: {
|
|
||||||
Authorization: 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImFiNmEyY2Y0LWM3MjQtNDgyMy1hM2NiLTk4N2NhZWNmMzZiNCJ9.oq-JVRbQuq_ujQ2V0h2jXC3woHPdMQKhnYJ8ixRm-C6Ez4GqJWyHYgmnkw5dbDyhWGdIUH02uv6XT8UiboHD4g',
|
|
||||||
isToken: false
|
|
||||||
},
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAdvancedSynthesize(data, config = {}) {
|
|
||||||
return request({
|
|
||||||
url: '/show/tts/synthesize/advanced',
|
|
||||||
headers: {
|
|
||||||
Authorization: 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImFiNmEyY2Y0LWM3MjQtNDgyMy1hM2NiLTk4N2NhZWNmMzZiNCJ9.oq-JVRbQuq_ujQ2V0h2jXC3woHPdMQKhnYJ8ixRm-C6Ez4GqJWyHYgmnkw5dbDyhWGdIUH02uv6XT8UiboHD4g',
|
|
||||||
isToken: false
|
|
||||||
},
|
|
||||||
responseType: 'blob',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
}, {
|
|
||||||
...config
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getFlowById = (id) => {
|
|
||||||
return request.get(import.meta.env.VITE_NODE_RED_URL + '/flow/' + id, {})
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询机器人配置列表
|
|
||||||
export function listRobot(query) {
|
|
||||||
return request({
|
|
||||||
url: '/device/robot/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询机器人配置详细
|
|
||||||
export function getRobot(id) {
|
|
||||||
return request({
|
|
||||||
url: '/device/robot/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增机器人配置
|
|
||||||
export function addRobot(data) {
|
|
||||||
return request({
|
|
||||||
url: '/device/robot',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改机器人配置
|
|
||||||
export function updateRobot(data) {
|
|
||||||
return request({
|
|
||||||
url: '/device/robot',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除机器人配置
|
|
||||||
export function delRobot(id) {
|
|
||||||
return request({
|
|
||||||
url: '/device/robot/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
31
src/api/device/system.js
Normal file
31
src/api/device/system.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function getSafetyState(robotId) {
|
||||||
|
return request({
|
||||||
|
url: '/api/system/safetyState',
|
||||||
|
method: 'get',
|
||||||
|
params: { robotId },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复机器人运行状态;payload 与旧 recoverSafetyState 保持一致,便于调用方渐进迁移。
|
||||||
|
*/
|
||||||
|
export function restoreOperationalState(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/system/restoreOperationalState',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated 请改用 restoreOperationalState,旧接口仅保留给未迁移调用方。
|
||||||
|
*/
|
||||||
|
export function recoverSafetyState(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/system/recoverSafetyState',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -1,86 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// 查询设备终端配置列表
|
|
||||||
export function listTerminal(query) {
|
|
||||||
return request({
|
|
||||||
url: '/device/terminal/list',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询设备终端配置详细
|
|
||||||
export function getTerminal(id) {
|
|
||||||
return request({
|
|
||||||
url: '/device/terminal/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增设备终端配置
|
|
||||||
export function addTerminal(data) {
|
|
||||||
return request({
|
|
||||||
url: '/device/terminal',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改设备终端配置
|
|
||||||
export function updateTerminal(data) {
|
|
||||||
return request({
|
|
||||||
url: '/device/terminal',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除设备终端配置
|
|
||||||
export function delTerminal(id) {
|
|
||||||
return request({
|
|
||||||
url: '/device/terminal/' + id,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取实例信息
|
|
||||||
export function getInstInfo(id) {
|
|
||||||
return request({
|
|
||||||
url: '/test/inst/context/' + id,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 暂停任务
|
|
||||||
export function pauseInst(id) {
|
|
||||||
return request({
|
|
||||||
url: `/test/inst/pause/${id}`,
|
|
||||||
method: 'post'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 恢复任务
|
|
||||||
export function resumeInst(id) {
|
|
||||||
return request({
|
|
||||||
url: `/test/inst/resume/${id}`,
|
|
||||||
method: 'post'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 恢复任务
|
|
||||||
export function stopInst(id) {
|
|
||||||
return request({
|
|
||||||
url: `/test/inst/stop/${id}`,
|
|
||||||
method: 'post'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getFlowParamsApi(taskId) {
|
|
||||||
return request({
|
|
||||||
url: '/test/orchestration',
|
|
||||||
method: 'get',
|
|
||||||
params: {
|
|
||||||
taskId
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -9,6 +9,34 @@ export function flowDeploy(data) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function flowSaveDraft(data) {
|
||||||
|
return request({ url: '/flow/draft', method: 'put', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function flowVersionList(itemId) {
|
||||||
|
return request({ url: `/flow/versions/${itemId}`, method: 'get' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function flowVersionDetail(versionId) {
|
||||||
|
return request({ url: `/flow/version/${versionId}`, method: 'get' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function flowSubFlowOptions(currentItemId) {
|
||||||
|
return request({
|
||||||
|
url: '/flow/subflows',
|
||||||
|
method: 'get',
|
||||||
|
params: { currentItemId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function flowRestoreDraft(versionId, data) {
|
||||||
|
return request({ url: `/flow/version/${versionId}/restore-draft`, method: 'post', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function flowRollbackVersion(versionId, data) {
|
||||||
|
return request({ url: `/flow/version/${versionId}/rollback`, method: 'post', data })
|
||||||
|
}
|
||||||
|
|
||||||
export function flowExecute(data) {
|
export function flowExecute(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/flow/execute',
|
url: '/flow/execute',
|
||||||
@ -69,3 +97,27 @@ export function getArmStatus(params) {
|
|||||||
params: params
|
params: params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAgvStatus(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/agv/getRuntimeState',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAgvStations(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/agv/listStations',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getArmJointState(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/arm/getJointState',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
5
src/api/flow/nodeRed.js
Normal file
5
src/api/flow/nodeRed.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function getNodeRedFlowById(id) {
|
||||||
|
return request.get(`${import.meta.env.VITE_NODE_RED_URL}/flow/${id}`, {})
|
||||||
|
}
|
||||||
97
src/api/inspection/cockpit.js
Normal file
97
src/api/inspection/cockpit.js
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function getPoseApi(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/arm/getPose',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getJointStateApi(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/arm/getJointState',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function speedLApi(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/arm/speedL',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function moveJApi(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/arm/moveJ',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function stopMotionApi(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/arm/stopMotion',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function torqueOnApi(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/arm/torqueOn',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function speedJApi(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/arm/speedJ',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearFault(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/arm/clearFault',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMicVolume(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/Microphone/volume',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setMicVolume(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/Microphone/volume',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSpeakerVolume(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/Speaker/volume',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setSpeakerVolume(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/Speaker/volume',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -1,33 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
|
|
||||||
export function getMapList(params) {
|
|
||||||
return request({
|
|
||||||
url: '/inspection/map/list',
|
|
||||||
method: 'get',
|
|
||||||
params: params
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addMap(data) {
|
|
||||||
return request({
|
|
||||||
url: '/inspection/map',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateMap(data) {
|
|
||||||
return request({
|
|
||||||
url: '/inspection/map',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteMap(id) {
|
|
||||||
return request({
|
|
||||||
url: `/inspection/map/${id}`,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -30,3 +30,10 @@ export function deletePoint(id) {
|
|||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function copyPoint(id) {
|
||||||
|
return request({
|
||||||
|
url: `/inspection/waypoint/copy/${id}`,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
23
src/api/inspection/result.js
Normal file
23
src/api/inspection/result.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询巡检结果列表。
|
||||||
|
*/
|
||||||
|
export function getInspectionResultList(params) {
|
||||||
|
return request({
|
||||||
|
url: '/inspection/result/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交人工复核结果。
|
||||||
|
*/
|
||||||
|
export function reviewInspectionResult(id, data) {
|
||||||
|
return request({
|
||||||
|
url: `/inspection/result/${id}/review`,
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -1,57 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
export function getRobotList(params) {
|
|
||||||
return request({
|
|
||||||
url: '/inspection/robot/list',
|
|
||||||
method: 'get',
|
|
||||||
params: params
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addRobot(data) {
|
|
||||||
return request({
|
|
||||||
url: '/inspection/robot',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateRobot(data) {
|
|
||||||
return request({
|
|
||||||
url: '/inspection/robot',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteRobot(id) {
|
|
||||||
return request({
|
|
||||||
url: `/inspection/robot/${id}`,
|
|
||||||
method: 'delete'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取机器人地图
|
|
||||||
* @param {*} robotId
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getMapByRobot(robotId) {
|
|
||||||
return request({
|
|
||||||
url: `/inspection/robot/${robotId}/maps`,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取地图JSON数据
|
|
||||||
* @param {*} params
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getMapJson(params) {
|
|
||||||
return request({
|
|
||||||
url: `/inspection/robot/${params.robotId}/download-map`,
|
|
||||||
method: 'get',
|
|
||||||
params
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -38,10 +38,18 @@ export function deleteRunTask(id) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startRunTask(id) {
|
export function startRunTask(id, data) {
|
||||||
return request({
|
return request({
|
||||||
url: `/inspection/taskInstance/start/${id}`,
|
url: `/inspection/taskInstance/start/${id}`,
|
||||||
method: 'put'
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rerunRunTask(id) {
|
||||||
|
return request({
|
||||||
|
url: `/inspection/taskInstance/rerun/${id}`,
|
||||||
|
method: 'post'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,3 +45,10 @@ export function bindWaypointsToTask(taskId, waypointIds) {
|
|||||||
data: waypointIds
|
data: waypointIds
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function copyTask(id) {
|
||||||
|
return request({
|
||||||
|
url: `/inspection/task/copy/${id}`,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import { method } from 'lodash'
|
|
||||||
|
|
||||||
export function addTaskinstance(data) {
|
export function addTaskinstance(data) {
|
||||||
return request({
|
return request({
|
||||||
@ -27,15 +26,23 @@ export function updateTaskinstance(data) {
|
|||||||
|
|
||||||
export function deleteTaskinstance(ids) {
|
export function deleteTaskinstance(ids) {
|
||||||
return request({
|
return request({
|
||||||
url: `/aima/taskinstance/{ids}`,
|
url: `/aima/taskinstance/${ids}`,
|
||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startTaskinstance(id) {
|
export function startTaskinstance(id, data) {
|
||||||
return request({
|
return request({
|
||||||
url: `/aima/taskinstance/start/${id}`,
|
url: `/aima/taskinstance/start/${id}`,
|
||||||
method: 'put'
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rerunTaskinstance(id) {
|
||||||
|
return request({
|
||||||
|
url: `/aima/taskinstance/rerun/${id}`,
|
||||||
|
method: 'post'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,3 +45,10 @@ export function bindTastCase(taskId, ids) {
|
|||||||
data: ids
|
data: ids
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function copyTask(id) {
|
||||||
|
return request({
|
||||||
|
url: `/aima/task/copy/${id}`,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -30,3 +30,10 @@ export function deleteTestCase(ids) {
|
|||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function copyTestCase(id) {
|
||||||
|
return request({
|
||||||
|
url: `/aima/testcase/copy/${id}`,
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -39,6 +39,15 @@ export function getInfo() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解锁屏幕
|
||||||
|
export function unlockScreen(password) {
|
||||||
|
return request({
|
||||||
|
url: '/unlockscreen',
|
||||||
|
method: 'post',
|
||||||
|
data: { password }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 退出方法
|
// 退出方法
|
||||||
export function logout() {
|
export function logout() {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
13
src/api/resource/device.js
Normal file
13
src/api/resource/device.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function listResourceDevices(params) {
|
||||||
|
return request({ url: '/resource/devices', method: 'get', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getResourceDevice(id) {
|
||||||
|
return request({ url: `/resource/devices/${encodeURIComponent(id)}`, method: 'get' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateResourceDevice(id, data) {
|
||||||
|
return request({ url: `/resource/devices/${encodeURIComponent(id)}`, method: 'put', data })
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user