progress
This commit is contained in:
parent
559262db34
commit
50822a031d
65 changed files with 7738 additions and 1412 deletions
76
.vscode/launch.json
vendored
76
.vscode/launch.json
vendored
|
@ -1,40 +1,40 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
|
||||
"configurations": [
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "server-dev",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": [
|
||||
"run-script", "dev"
|
||||
],
|
||||
"cwd": "${workspaceRoot}/server/",
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "server-test-watch",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": [
|
||||
"run-script", "test:watch"
|
||||
],
|
||||
"cwd": "${workspaceRoot}/server/",
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "ui-dev",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": [
|
||||
"run-script", "dev"
|
||||
],
|
||||
"cwd": "${workspaceRoot}/ui/",
|
||||
}
|
||||
]
|
||||
}
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "server-dev",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run-script", "dev"],
|
||||
"cwd": "${workspaceRoot}/server/"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "server-test-watch",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run-script", "test:watch"],
|
||||
"cwd": "${workspaceRoot}/server/"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "ui-dev",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run-script", "dev"],
|
||||
"cwd": "${workspaceRoot}/ui/"
|
||||
},
|
||||
{
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"name": "Launch debug chrome",
|
||||
"url": "http://localhost:3000",
|
||||
"webRoot": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ export class ExecDatasetProcessScenario extends CallbackStrategyWithIdQuery {
|
|||
return (await new IsHaveActiveProcessUseCase().call()).map(async () => {
|
||||
await DatasetDBModel.findById(id).updateOne({ processStatus: "RUN" });
|
||||
model.local_path = `${model.local_path}/${FolderStructure.datasets}/`;
|
||||
|
||||
return new ExecProcessUseCase().call(
|
||||
`${model.project.rootDir}/`,
|
||||
`blenderproc run $PYTHON_BLENDER_PROC --cfg '${JSON.stringify(model)}'`,
|
||||
|
|
|
@ -12,6 +12,9 @@ export interface Parts {
|
|||
stlUrl: string;
|
||||
image: string;
|
||||
glUrl: string;
|
||||
daeUrl: string;
|
||||
objUrl: string;
|
||||
solidType: string;
|
||||
}
|
||||
|
||||
export class RobossemblerAssetsNetworkMapperScenario extends CallbackStrategyWithEmpty {
|
||||
|
@ -35,7 +38,10 @@ export class RobossemblerAssetsNetworkMapperScenario extends CallbackStrategyWit
|
|||
|
||||
el.stlUrl = `${assetAddress}${el.part_path}`;
|
||||
el.glUrl = `${assetLibsAddress}.glb`;
|
||||
el.daeUrl = `${assetLibsAddress}.dae`;
|
||||
el.objUrl = `${assetLibsAddress}.obj`;
|
||||
el.image = `${assetLibsAddress}.png`;
|
||||
el.solidType = 'active'
|
||||
return el;
|
||||
});
|
||||
return Result.ok(model);
|
||||
|
|
|
@ -13,6 +13,7 @@ export enum FolderStructure {
|
|||
weights = "weights",
|
||||
datasets = "datasets",
|
||||
behaviorTrees = "behavior_trees",
|
||||
robots = "robots",
|
||||
}
|
||||
|
||||
export class UploadCadFileToProjectScenario extends CallbackStrategyWithFileUpload {
|
||||
|
@ -20,24 +21,23 @@ export class UploadCadFileToProjectScenario extends CallbackStrategyWithFileUplo
|
|||
idValidationExpression = new MongoIdValidation();
|
||||
|
||||
async call(file: IFile, id: string): ResponseBase {
|
||||
return (await new ReadByIdDataBaseModelUseCase<IProjectModel>(ProjectDBModel).call(id)).map(
|
||||
async (databaseModel) =>
|
||||
(await new CreateFileUseCase().call(`${databaseModel.rootDir}/${file.name}`, file.data)).map(async () =>
|
||||
(
|
||||
await new ExecProcessUseCase().call(
|
||||
`${databaseModel.rootDir}/`,
|
||||
`python3 $PYTHON_BLENDER --path '${databaseModel.rootDir}/assets/'`,
|
||||
""
|
||||
)
|
||||
).map(async () =>
|
||||
(
|
||||
await new CreateManyFolderScenario().call(
|
||||
databaseModel.rootDir,
|
||||
Object.keys(FolderStructure).map((el) => `/${el}`)
|
||||
)
|
||||
).map(() => Result.ok("file upload and save"))
|
||||
return (await new ReadByIdDataBaseModelUseCase<IProjectModel>(ProjectDBModel).call(id)).map(async (databaseModel) =>
|
||||
(await new CreateFileUseCase().call(`${databaseModel.rootDir}/${file.name}`, file.data)).map(async () =>
|
||||
(
|
||||
await new ExecProcessUseCase().call(
|
||||
`${databaseModel.rootDir}/`,
|
||||
`python3 $PYTHON_BLENDER --path '${databaseModel.rootDir}/assets/'`,
|
||||
""
|
||||
)
|
||||
).map(async () =>
|
||||
(
|
||||
await new CreateManyFolderScenario().call(
|
||||
databaseModel.rootDir,
|
||||
Object.keys(FolderStructure).map((el) => `/${el}`)
|
||||
)
|
||||
).map(() => Result.ok("file upload and save"))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
1035
ui/package-lock.json
generated
1035
ui/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -7,22 +7,9 @@
|
|||
"@foxglove/rosmsg": "^5.0.4",
|
||||
"@foxglove/rosmsg2-serialization": "^2.0.3",
|
||||
"@foxglove/ws-protocol": "^0.7.3",
|
||||
"@monaco-editor/react": "^4.6.0",
|
||||
"@testing-library/jest-dom": "^5.17.0",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^16.18.46",
|
||||
"@types/react": "^18.2.21",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@types/socket.io-client": "^3.0.0",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"babylonjs": "^7.11.2",
|
||||
"babylonjs-loaders": "^7.11.2",
|
||||
"babylonjs-serializers": "^7.11.2",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.0",
|
||||
"formik-antd": "^2.0.4",
|
||||
"antd": "^4.24.15",
|
||||
"i18next": "^23.6.0",
|
||||
"just-clone": "^6.2.0",
|
||||
"mobx": "^6.10.0",
|
||||
|
@ -31,8 +18,6 @@
|
|||
"pattern-matching-ts": "^2.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-accessible-treeview": "^2.8.3",
|
||||
"react-dnd": "^16.0.1",
|
||||
"react-dnd-html5-backend": "^16.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-i18next": "^13.3.1",
|
||||
"react-infinite-scroll-component": "^6.1.0",
|
||||
|
@ -42,23 +27,21 @@
|
|||
"rete-connection-plugin": "^2.0.0",
|
||||
"rete-react-plugin": "^2.0.4",
|
||||
"rete-render-utils": "^2.0.1",
|
||||
"sass": "^1.66.1",
|
||||
"serve": "^14.2.1",
|
||||
"socket.io-client": "^4.7.2",
|
||||
"source-map-loader": "^5.0.0",
|
||||
"styled-components": "^6.1.8",
|
||||
"three": "^0.165.0",
|
||||
"three-stdlib": "^2.28.9",
|
||||
"three-transform-controls": "^1.0.4",
|
||||
"ts-pattern": "^5.1.1",
|
||||
"typescript": "^5.4",
|
||||
"typescript-mixin": "^1.0.3",
|
||||
"typescript": "^5.0.2",
|
||||
"urdf-loader": "^0.12.1",
|
||||
"uuid": "^9.0.1",
|
||||
"web-vitals": "^2.1.4",
|
||||
"ws": "^8.17.0",
|
||||
"xml-formatter": "^3.6.2"
|
||||
},
|
||||
"overrides": {
|
||||
"typescript": "^5.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
|
@ -68,7 +51,8 @@
|
|||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app" ]
|
||||
"react-app"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
@ -83,6 +67,12 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/three": "^0.158.3"
|
||||
"@types/three": "^0.158.3",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^16.18.46",
|
||||
"@types/react": "^18.2.21",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@types/socket.io-client": "^3.0.0",
|
||||
"@types/uuid": "^9.0.2"
|
||||
}
|
||||
}
|
||||
}
|
15
ui/readme.md
15
ui/readme.md
|
@ -1,7 +1,9 @@
|
|||
# Установка зависимостей
|
||||
# Установка зависимостей
|
||||
|
||||
```
|
||||
brew install mason
|
||||
```
|
||||
|
||||
### Инициализация
|
||||
|
||||
В корне проекта вызовите команду `init`, которая создаст папку `.mason/`
|
||||
|
@ -39,9 +41,14 @@ mason new my_brick_name
|
|||
|
||||
Для большей информации [читайте и смотрите примеры](https://github.com/felangel/mason/blob/master/packages/mason_cli/README.md)
|
||||
|
||||
# Добавить новую форму в деревья поведения
|
||||
|
||||
mason make form -o ./src/features/behavior_tree_builder/presentation/ui/forms
|
||||
|
||||
# Добавить новую форму в Scene Manager
|
||||
|
||||
mason make form -o ./src/features/scene_manager/presentation/forms
|
||||
|
||||
# Добавить новую форму
|
||||
mason make form -o ./src/features/behavior_tree_builder/presentation/ui/forms
|
||||
# Добавить новый экран
|
||||
mason make base_feature -o ./src/features/
|
||||
|
||||
mason make base_feature -o ./src/features/
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
|
||||
<svg width="64px" height="12" "strokeWidth="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>strokeWidth
|
||||
<g id="SVGRepo_bgCarrier" strokeWidth="0"/>strokeWidth
|
||||
|
||||
<g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
|
||||
<g id="SVGRepo_iconCarrier"> <g id="Interface / Check"> <path id="Vector" d="M6 12L10.2426 16.2426L18.727 7.75732" stroke="#f8f9fa" stroke-width="2" strokeLinecap="round" strokeLinejoin="round"/> </g> </g>
|
||||
<g id="SVGRepo_iconCarrier"> <g id="Interface / Check"> <path id="Vector" d="M6 12L10.2426 16.2426L18.727 7.75732" stroke="#f8f9fa" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/> </g> </g>
|
||||
|
||||
</svg>
|
Before Width: | Height: | Size: 638 B After Width: | Height: | Size: 636 B |
|
@ -3,7 +3,7 @@
|
|||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
|
||||
<svg width="64px" height="6strokeWidth="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
||||
<g id="SVGRepo_bgCarrier" strokeWidth="0"/>
|
||||
|
||||
<g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
|
||||
|
|
Before Width: | Height: | Size: 661 B After Width: | Height: | Size: 660 B |
|
@ -34,6 +34,7 @@ declare global {
|
|||
isNegative(): boolean;
|
||||
isEven(): boolean;
|
||||
isOdd(): boolean;
|
||||
isEqualR(num: number): Result<void, void>;
|
||||
}
|
||||
|
||||
interface String {
|
||||
|
@ -45,6 +46,7 @@ declare global {
|
|||
hasPattern(pattern: string): boolean;
|
||||
hasNoPattern(pattern: string): boolean;
|
||||
divideByIndex(index: number): string[];
|
||||
isEqualR(str: string): Result<void, string>;
|
||||
}
|
||||
|
||||
interface Map<K, V> {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { Result } from "../helper/result";
|
||||
|
||||
export const NumberExtensions = () => {
|
||||
if (Number().fromArray === undefined) {
|
||||
Number.prototype.fromArray = function () {
|
||||
|
@ -15,6 +17,14 @@ export const NumberExtensions = () => {
|
|||
return `${date.getUTCFullYear()}.${date.getMonth()}.${date.getDay()} ${date.getHours()}:${date.getMinutes()}`;
|
||||
};
|
||||
}
|
||||
if (Number().isEqualR === undefined) {
|
||||
Number.prototype.isEqualR = function (num) {
|
||||
if(this === num) {
|
||||
return Result.ok(undefined)
|
||||
}
|
||||
return Result.error(undefined)
|
||||
};
|
||||
}
|
||||
if (Number().isValid === undefined) {
|
||||
Number.prototype.isValid = function (str: string) {
|
||||
return !isNaN(Number(str));
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { Result } from "../helper/result";
|
||||
|
||||
/* eslint-disable no-extend-native */
|
||||
export const StringExtensions = () => {
|
||||
if ("".isEmpty === undefined) {
|
||||
|
@ -10,6 +12,14 @@ export const StringExtensions = () => {
|
|||
return this.length !== 0;
|
||||
};
|
||||
}
|
||||
if ("".isEqualR === undefined) {
|
||||
String.prototype.isEqualR = function (str) {
|
||||
if (this === str) {
|
||||
return Result.ok(String(this));
|
||||
}
|
||||
return Result.error(undefined);
|
||||
};
|
||||
}
|
||||
if ("".replaceMany === undefined) {
|
||||
String.prototype.replaceMany = function (searchValues: string[], replaceValue: string) {
|
||||
let result = this as string;
|
||||
|
@ -44,13 +54,13 @@ export const StringExtensions = () => {
|
|||
return !this.hasPattern(pattern);
|
||||
};
|
||||
}
|
||||
if (''.divideByIndex === undefined) {
|
||||
if ("".divideByIndex === undefined) {
|
||||
String.prototype.divideByIndex = function (index) {
|
||||
if (this.at(index) === undefined) {
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
|
||||
return [this.slice(0, index), this.slice(index+1, this.length)]
|
||||
}
|
||||
return [this.slice(0, index), this.slice(index + 1, this.length)];
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
3
ui/src/core/model/spawn_position_types.ts
Normal file
3
ui/src/core/model/spawn_position_types.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export enum SpawnPositionTypes {
|
||||
BoundBox = "BoundBox",
|
||||
}
|
|
@ -1,36 +1,36 @@
|
|||
import { Scene, Engine, MeshBuilder, FreeCamera, HemisphericLight, Vector3, SceneLoader } from 'babylonjs';
|
||||
import { GLTFFileLoader } from 'babylonjs-loaders';
|
||||
// import { Scene, Engine, MeshBuilder, FreeCamera, HemisphericLight, Vector3, SceneLoader } from 'babylonjs';
|
||||
// import { GLTFFileLoader } from 'babylonjs-loaders';
|
||||
|
||||
|
||||
export class BabylonRepository {
|
||||
engine: Engine;
|
||||
canvas: HTMLCanvasElement;
|
||||
scene: Scene;
|
||||
sceneLoader: SceneLoader
|
||||
constructor(canvas: HTMLCanvasElement) {
|
||||
this.sceneLoader = new SceneLoader();
|
||||
this.engine = new Engine(canvas, true);
|
||||
this.scene = new Scene(this.engine);
|
||||
this.engine.runRenderLoop(() => {
|
||||
this.scene.render();
|
||||
});
|
||||
this.scene.createDefaultCameraOrLight(true, true, true);
|
||||
new HemisphericLight("hemiLight", new Vector3(0, 1, 0));
|
||||
SceneLoader.RegisterPlugin(new GLTFFileLoader())
|
||||
SceneLoader.ImportMeshAsync("",
|
||||
"http://localhost:4001/1dfc4e1a-9c1a-4fa2-96b2-19c86acb6ea4/assets/libs/objects/",
|
||||
"sol_gear.glb", this.scene)
|
||||
// export class BabylonRepository {
|
||||
// engine: Engine;
|
||||
// canvas: HTMLCanvasElement;
|
||||
// scene: Scene;
|
||||
// sceneLoader: SceneLoader
|
||||
// constructor(canvas: HTMLCanvasElement) {
|
||||
// this.sceneLoader = new SceneLoader();
|
||||
// this.engine = new Engine(canvas, true);
|
||||
// this.scene = new Scene(this.engine);
|
||||
// this.engine.runRenderLoop(() => {
|
||||
// this.scene.render();
|
||||
// });
|
||||
// this.scene.createDefaultCameraOrLight(true, true, true);
|
||||
// new HemisphericLight("hemiLight", new Vector3(0, 1, 0));
|
||||
// SceneLoader.RegisterPlugin(new GLTFFileLoader())
|
||||
// SceneLoader.ImportMeshAsync("",
|
||||
// "http://localhost:4001/1dfc4e1a-9c1a-4fa2-96b2-19c86acb6ea4/assets/libs/objects/",
|
||||
// "sol_gear.glb", this.scene)
|
||||
|
||||
}
|
||||
deleteAllObjectsScene = () => this.scene.meshes.forEach((el) => this.scene.removeMesh(el, true))
|
||||
// }
|
||||
// deleteAllObjectsScene = () => this.scene.meshes.forEach((el) => this.scene.removeMesh(el, true))
|
||||
|
||||
loadHttp = (url: string) => {
|
||||
const divide = url.divideByIndex(url.lastIndexOf('/'))
|
||||
// loadHttp = (url: string) => {
|
||||
// const divide = url.divideByIndex(url.lastIndexOf('/'))
|
||||
|
||||
SceneLoader.ImportMeshAsync("",
|
||||
`${divide.at(0)}/`,
|
||||
`${divide.at(1)}`, this.scene).then((frame) => {
|
||||
});
|
||||
// SceneLoader.ImportMeshAsync("",
|
||||
// `${divide.at(0)}/`,
|
||||
// `${divide.at(1)}`, this.scene).then((frame) => {
|
||||
// });
|
||||
|
||||
}
|
||||
}
|
||||
// }
|
||||
// }
|
|
@ -21,23 +21,26 @@ import {
|
|||
Quaternion,
|
||||
MeshBasicMaterial,
|
||||
BoxGeometry,
|
||||
MeshStandardMaterial
|
||||
MeshStandardMaterial,
|
||||
} from "three";
|
||||
import { TypedEvent } from "../helper/typed_event";
|
||||
import { Result } from "../helper/result";
|
||||
import { GLTFLoader, OrbitControls, TransformControls, OBJLoader, STLLoader, ColladaLoader } from "three-stdlib";
|
||||
import { ColladaLoader } from "three/examples/jsm/loaders/ColladaLoader";
|
||||
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
||||
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
|
||||
import { STLLoader } from "three/examples/jsm/loaders/STLLoader";
|
||||
import { OrbitControls, TransformControls } from "three/examples/jsm/Addons";
|
||||
import {
|
||||
BaseSceneItemModel,
|
||||
CameraViewModel,
|
||||
StaticAssetItemModel,
|
||||
} from "../../features/scene_manager/model/scene_assets";
|
||||
import { SceneMode } from "../../features/scene_manager/model/scene_view";
|
||||
import { throttle } from "../helper/throttle";
|
||||
import { Asset, InstanceRgbCamera, RobossemblerAssets, SceneSimpleObject } from "../model/robossembler_assets";
|
||||
import { LoadingManager } from 'three';
|
||||
import { UrdfTransforms, coordsToQuaternion } from "../../features/simulations/tranforms_model";
|
||||
import URDFLoader, { URDFLink } from 'urdf-loader';
|
||||
import { LoadingManager } from "three";
|
||||
|
||||
import { SceneMode } from "../../features/scene_manager/model/scene_view";
|
||||
import { UrdfTransforms, coordsToQuaternion } from "../../features/simulations/tranforms_model";
|
||||
import URDFLoader, { URDFLink } from "urdf-loader";
|
||||
import { ISolidSpawnHelper } from "../../features/scene_manager/presentation/scene_manager_store";
|
||||
|
||||
Object3D.DEFAULT_UP = new Vector3(0, 0, 1);
|
||||
|
||||
|
@ -45,7 +48,7 @@ export enum UserData {
|
|||
selectedObject = "selected_object",
|
||||
cameraInitialization = "camera_initialization",
|
||||
objectForMagnetism = "object_for_magnetism",
|
||||
loadObject = 'load_object'
|
||||
loadObject = "load_object",
|
||||
}
|
||||
|
||||
interface IEventDraggingChange {
|
||||
|
@ -58,10 +61,7 @@ interface IEmissiveCache {
|
|||
status: boolean;
|
||||
object3d: Object3D<Object3DEventMap>;
|
||||
}
|
||||
type SceneFrames = { [K in string]: URDFLink; }
|
||||
|
||||
|
||||
|
||||
type SceneFrames = { [K in string]: URDFLink };
|
||||
|
||||
export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
||||
scene = new Scene();
|
||||
|
@ -110,19 +110,22 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
|||
}
|
||||
|
||||
deleteAllObjectsScene = () => {
|
||||
|
||||
|
||||
this.getAllSceneNameModels().forEach((el) => this.scene.remove(this.scene.getObjectByName(el) as Object3D<Object3DEventMap>))
|
||||
}
|
||||
|
||||
this.getAllSceneNameModels().forEach((el) =>
|
||||
this.scene.remove(this.scene.getObjectByName(el) as Object3D<Object3DEventMap>)
|
||||
);
|
||||
};
|
||||
raiseAnObjectAboveZeroVector = (name: string) => {
|
||||
const mesh = this.scene.getObjectByName(name) as Object3D;
|
||||
mesh.position.sub(new Box3().setFromObject(mesh).min);
|
||||
};
|
||||
drawPoint(point: Vector3): Mesh<BoxGeometry, MeshBasicMaterial, Object3DEventMap> {
|
||||
var cube = new Mesh(new BoxGeometry(0.5, 0.5, 0.5), new MeshBasicMaterial({ color: 0x0095dd }));
|
||||
cube.position.add(point);
|
||||
this.scene.add(cube);
|
||||
return cube;
|
||||
}
|
||||
getCenterPoint = (object: Object3D<Object3DEventMap>) => object.getWorldPosition(new Box3().setFromObject(object).getCenter(object.position));
|
||||
|
||||
getCenterPoint = (object: Object3D<Object3DEventMap>) =>
|
||||
object.getWorldPosition(new Box3().setFromObject(object).getCenter(object.position));
|
||||
|
||||
makeCube(inc: number, vector?: Vector3, color?: string, size?: number) {
|
||||
const cube = new Mesh(
|
||||
|
@ -151,55 +154,34 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
|||
cube.position.copy(vector);
|
||||
}
|
||||
this.scene.add(cube);
|
||||
}
|
||||
deleteSceneItem = (item: string) =>
|
||||
this.scene.children.forEach((el) => el.name.isEqualR(item).map(() => this.scene.remove(el)));
|
||||
|
||||
}
|
||||
deleteSceneItem(item: BaseSceneItemModel) {
|
||||
const updateScene = this.scene;
|
||||
updateScene.children = item.deleteToScene(updateScene);
|
||||
}
|
||||
loadUrdf = (urlPath: string) => {
|
||||
this.urdfLoader.load(
|
||||
urlPath,
|
||||
robot => {
|
||||
|
||||
this.scene.add(robot)
|
||||
// @ts-expect-error
|
||||
this.sceneFrame = robot.frames
|
||||
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
loadInstances(robossemblerAssets: RobossemblerAssets) {
|
||||
robossemblerAssets.instances.forEach(async (el) => {
|
||||
if (el instanceof InstanceRgbCamera) {
|
||||
const cameraModel = CameraViewModel.fromInstanceRgbCamera(el);
|
||||
cameraModel.mapPerspectiveCamera(this.htmlSceneWidth, this.htmlSceneHeight).forEach((el) => this.scene.add(el));
|
||||
this.emit(cameraModel);
|
||||
}
|
||||
if (el instanceof SceneSimpleObject) {
|
||||
const asset = robossemblerAssets.getAssetAtInstance(el.instanceAt as string);
|
||||
this.loader(
|
||||
asset.meshPath,
|
||||
() => { },
|
||||
asset.name,
|
||||
new Vector3(el.position.x, el.position.y, el.position.z),
|
||||
new Quaternion(el.quaternion[0], el.quaternion[1], el.quaternion[2], el.quaternion[3])
|
||||
);
|
||||
}
|
||||
this.urdfLoader.load(urlPath, (robot) => {
|
||||
this.scene.add(robot);
|
||||
// @ts-expect-error
|
||||
this.sceneFrame = robot.frames;
|
||||
});
|
||||
}
|
||||
loadInstance(asset: Asset, loadCallback?: Function) {
|
||||
};
|
||||
|
||||
solidSpawn(
|
||||
solidSpawn: ISolidSpawnHelper,
|
||||
loadCallback?: (obj: Object3D<Object3DEventMap> | undefined) => void,
|
||||
vector3?: Vector3
|
||||
) {
|
||||
this.loader(
|
||||
asset.meshPath,
|
||||
loadCallback ? loadCallback : () => { },
|
||||
asset.name,
|
||||
new Vector3(Number(asset.posX), Number(asset.posY), Number(asset.posZ)),
|
||||
new Quaternion(0, 0, 0, 0)
|
||||
solidSpawn.url,
|
||||
() => {
|
||||
this.raiseAnObjectAboveZeroVector(solidSpawn.name);
|
||||
if (loadCallback) loadCallback(this.scene.getObjectByName(solidSpawn.name));
|
||||
},
|
||||
solidSpawn.name,
|
||||
vector3
|
||||
);
|
||||
}
|
||||
loadHttpAndPreview(path: string, name: string, loadCallback?: Function) {
|
||||
|
||||
this.loader(
|
||||
path,
|
||||
() => {
|
||||
|
@ -209,7 +191,6 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
|||
name,
|
||||
new Vector3(0, 0, 0)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
setTransformMode(mode?: SceneMode) {
|
||||
|
@ -218,10 +199,10 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
|||
this.transformControls.detach();
|
||||
this.transformControls.dispose();
|
||||
break;
|
||||
case SceneMode.MOVING:
|
||||
case SceneMode.Move:
|
||||
this.transformControls.setMode("translate");
|
||||
break;
|
||||
case SceneMode.ROTATE:
|
||||
case SceneMode.Rotate:
|
||||
this.transformControls.setMode("rotate");
|
||||
break;
|
||||
}
|
||||
|
@ -275,7 +256,7 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
|||
}
|
||||
}
|
||||
|
||||
setRayCast(vector: Vector2): Result<void, Intersection<Object3D<Object3DEventMap>>[]> {
|
||||
setRayCast = (vector: Vector2): Result<void, Intersection<Object3D<Object3DEventMap>>[]> => {
|
||||
const raycaster = new Raycaster();
|
||||
raycaster.setFromCamera(vector, this.camera);
|
||||
const intersects = raycaster.intersectObjects(this.scene.children);
|
||||
|
@ -284,16 +265,17 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
|||
}
|
||||
|
||||
return Result.error(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
setRayCastAndGetFirstObjectAndPointToObject(vector: Vector2): Result<void, Vector3> {
|
||||
this.setRayCast(vector).map((intersects) => {
|
||||
if (intersects.length > 0) {
|
||||
return Result.ok(intersects[0].point);
|
||||
}
|
||||
});
|
||||
return Result.error(undefined);
|
||||
}
|
||||
setRayCastAndGetFirstObjectAndPointToObject = (vector: Vector2): Result<void, Vector3> =>
|
||||
this.setRayCast(vector).fold(
|
||||
(intersects) => {
|
||||
if (intersects.isNotEmpty()) {
|
||||
return Result.ok(intersects[0].point);
|
||||
}
|
||||
},
|
||||
() => Result.error(undefined)
|
||||
) as Result<void, Vector3>;
|
||||
|
||||
light() {
|
||||
const ambientLight = new AmbientLight(0xffffff, 0.7);
|
||||
|
@ -321,12 +303,7 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
|||
this.orbitControls.enabled = !e.value;
|
||||
});
|
||||
this.transformControls.addEventListener("objectChange", (event) => {
|
||||
//@ts-expect-error
|
||||
const sceneObject = event.target.object;
|
||||
//TODO:(IDONTSUDO) Trotting doesn't work, need to figure out why
|
||||
const fn = () => this.watcherSceneEditorObject(sceneObject);
|
||||
const [throttleFn] = throttle(fn, 1000);
|
||||
throttleFn();
|
||||
this.watcherSceneEditorObject(event.target.object);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -334,10 +311,10 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
|||
this.light();
|
||||
this.addListeners();
|
||||
const floor = new GridHelper(1000, 100, 0x888888, 0x444444);
|
||||
floor.geometry.rotateX(Math.PI * 0.5)
|
||||
floor.geometry.rotateX(Math.PI * 0.5);
|
||||
floor.userData = {};
|
||||
floor.userData[UserData.cameraInitialization] = true;
|
||||
floor.up.copy(new Vector3(0, 0, 1))
|
||||
floor.up.copy(new Vector3(0, 0, 1));
|
||||
|
||||
this.scene.add(floor);
|
||||
}
|
||||
|
@ -372,10 +349,10 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
|||
this.glbLoader.load(
|
||||
url,
|
||||
(result) => {
|
||||
this.scene.add(result.scene)
|
||||
callBack()
|
||||
this.scene.add(result.scene);
|
||||
callBack();
|
||||
},
|
||||
(err) => { }
|
||||
(err) => {}
|
||||
);
|
||||
break;
|
||||
case "obj":
|
||||
|
@ -392,51 +369,47 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
|||
|
||||
this.emit(new StaticAssetItemModel(el.name, el.position, el.quaternion));
|
||||
this.scene.add(el);
|
||||
callBack()
|
||||
callBack();
|
||||
});
|
||||
},
|
||||
(err) => { }
|
||||
(err) => {}
|
||||
);
|
||||
break;
|
||||
case "dae":
|
||||
this.daeLoader.load(
|
||||
url,
|
||||
(result) => {
|
||||
this.scene.add(result.scene.children[0])
|
||||
this.scene.add(result.scene);
|
||||
},
|
||||
(err) => { }
|
||||
(err) => console.log(err)
|
||||
);
|
||||
break;
|
||||
case "stl":
|
||||
this.stlLoader.load(
|
||||
url,
|
||||
(result) => {
|
||||
|
||||
const material = new MeshStandardMaterial({
|
||||
color: 'red',
|
||||
metalness: 0.35,
|
||||
roughness: 1,
|
||||
opacity: 1.0,
|
||||
transparent: false,
|
||||
});
|
||||
|
||||
|
||||
const mesh = new Mesh(result, material);
|
||||
const mesh = new Mesh(
|
||||
result,
|
||||
new MeshStandardMaterial({
|
||||
color: "red",
|
||||
metalness: 0.35,
|
||||
roughness: 1,
|
||||
opacity: 1.0,
|
||||
transparent: false,
|
||||
})
|
||||
);
|
||||
mesh.name = name;
|
||||
|
||||
|
||||
|
||||
|
||||
// var geometry = mesh.geometry;
|
||||
// geometry.computeBoundingBox(); // Вычисляем ограничивающий параллелепипед для геометрии
|
||||
|
||||
if (position) mesh.position.copy(position)
|
||||
if (position) mesh.position.copy(position);
|
||||
|
||||
this.scene.add(mesh);
|
||||
callBack()
|
||||
callBack();
|
||||
},
|
||||
|
||||
(err) => { }
|
||||
(err) => {}
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
@ -526,11 +499,10 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
|
|||
urdfTransforms = (urdfTransforms: UrdfTransforms) => {
|
||||
urdfTransforms.transforms.forEach((transform) => {
|
||||
if (this.sceneFrame) {
|
||||
const currentLink = this.sceneFrame[transform?.child_frame_id ?? ""]
|
||||
const currentLink = this.sceneFrame[transform?.child_frame_id ?? ""];
|
||||
|
||||
currentLink.quaternion.copy(coordsToQuaternion(transform.transform.rotation))
|
||||
currentLink.quaternion.copy(coordsToQuaternion(transform.transform.rotation));
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,11 +5,12 @@ import { IStyle } from "../../model/style";
|
|||
export interface IIconsProps extends IStyle {
|
||||
type: string;
|
||||
onClick?: Function;
|
||||
height?: number;
|
||||
width?: number;
|
||||
}
|
||||
|
||||
export function Icon(props: IIconsProps) {
|
||||
const icon = getIconSvg(props.type);
|
||||
return icon.fold(
|
||||
return getIconSvg(props.type, props.height, props.width).fold(
|
||||
(node) => {
|
||||
return (
|
||||
<div
|
||||
|
@ -41,7 +42,11 @@ export function Icon(props: IIconsProps) {
|
|||
)
|
||||
);
|
||||
}
|
||||
const getIconSvg = (type: string): Result<undefined, React.JSX.Element> => {
|
||||
const getIconSvg = (
|
||||
type: string,
|
||||
height: number | undefined,
|
||||
width: number | undefined
|
||||
): Result<undefined, React.JSX.Element> => {
|
||||
switch (type) {
|
||||
case "":
|
||||
return Result.ok();
|
||||
|
@ -51,9 +56,9 @@ const getIconSvg = (type: string): Result<undefined, React.JSX.Element> => {
|
|||
<path
|
||||
d="M5 12H19M19 12L13 6M19 12L13 18"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
@ -64,65 +69,65 @@ const getIconSvg = (type: string): Result<undefined, React.JSX.Element> => {
|
|||
<path
|
||||
d="M17 18C17 18.5523 17.4477 19 18 19C18.5523 19 19 18.5523 19 18C19 17.4477 18.5523 17 18 17C17.4477 17 17 17.4477 17 18Z"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M11 18C11 18.5523 11.4477 19 12 19C12.5523 19 13 18.5523 13 18C13 17.4477 12.5523 17 12 17C11.4477 17 11 17.4477 11 18Z"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M5 18C5 18.5523 5.44772 19 6 19C6.55228 19 7 18.5523 7 18C7 17.4477 6.55228 17 6 17C5.44772 17 5 17.4477 5 18Z"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M17 12C17 12.5523 17.4477 13 18 13C18.5523 13 19 12.5523 19 12C19 11.4477 18.5523 11 18 11C17.4477 11 17 11.4477 17 12Z"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M11 12C11 12.5523 11.4477 13 12 13C12.5523 13 13 12.5523 13 12C13 11.4477 12.5523 11 12 11C11.4477 11 11 11.4477 11 12Z"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M5 12C5 12.5523 5.44772 13 6 13C6.55228 13 7 12.5523 7 12C7 11.4477 6.55228 11 6 11C5.44772 11 5 11.4477 5 12Z"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M17 6C17 6.55228 17.4477 7 18 7C18.5523 7 19 6.55228 19 6C19 5.44772 18.5523 5 18 5C17.4477 5 17 5.44772 17 6Z"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M11 6C11 6.55228 11.4477 7 12 7C12.5523 7 13 6.55228 13 6C13 5.44772 12.5523 5 12 5C11.4477 5 11 5.44772 11 6Z"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M5 6C5 6.55228 5.44772 7 6 7C6.55228 7 7 6.55228 7 6C7 5.44772 6.55228 5 6 5C5.44772 5 5 5.44772 5 6Z"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
@ -132,9 +137,9 @@ const getIconSvg = (type: string): Result<undefined, React.JSX.Element> => {
|
|||
<path
|
||||
d="M21 21L12 12M12 12L3 3M12 12L21.0001 3M12 12L3 21.0001"
|
||||
stroke="white"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
@ -367,7 +372,13 @@ const getIconSvg = (type: string): Result<undefined, React.JSX.Element> => {
|
|||
);
|
||||
case "DeleteCircle":
|
||||
return Result.ok(
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg
|
||||
width={width ? width : "20"}
|
||||
height={height ? height : "20"}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
|
@ -451,6 +462,24 @@ const getIconSvg = (type: string): Result<undefined, React.JSX.Element> => {
|
|||
</g>
|
||||
</svg>
|
||||
);
|
||||
case "Solid":
|
||||
return Result.ok(
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={width ? width : "20"}
|
||||
height={height ? height : "20"}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M12 10.2308L3.08495 7.02346M12 10.2308L20.9178 7.03406M12 10.2308V20.8791M5.13498 18.5771L10.935 20.6242C11.3297 20.7635 11.527 20.8331 11.7294 20.8608C11.909 20.8853 12.091 20.8853 12.2706 20.8608C12.473 20.8331 12.6703 20.7635 13.065 20.6242L18.865 18.5771C19.6337 18.3058 20.018 18.1702 20.3018 17.9269C20.5523 17.7121 20.7459 17.4386 20.8651 17.1308C21 16.7823 21 16.3747 21 15.5595V8.44058C21 7.62542 21 7.21785 20.8651 6.86935C20.7459 6.56155 20.5523 6.28804 20.3018 6.0732C20.018 5.82996 19.6337 5.69431 18.865 5.42301L13.065 3.37595C12.6703 3.23665 12.473 3.167 12.2706 3.13936C12.091 3.11484 11.909 3.11484 11.7294 3.13936C11.527 3.167 11.3297 3.23665 10.935 3.37595L5.13498 5.42301C4.36629 5.69431 3.98195 5.82996 3.69824 6.0732C3.44766 6.28804 3.25414 6.56155 3.13495 6.86935C3 7.21785 3 7.62542 3 8.44058V15.5595C3 16.3747 3 16.7823 3.13495 17.1308C3.25414 17.4386 3.44766 17.7121 3.69824 17.9269C3.98195 18.1702 4.36629 18.3058 5.13498 18.5771Z"
|
||||
stroke="#000000"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
case "Camera":
|
||||
return Result.ok(
|
||||
<svg width="18" height="14" viewBox="0 0 18 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
@ -460,6 +489,42 @@ const getIconSvg = (type: string): Result<undefined, React.JSX.Element> => {
|
|||
/>
|
||||
</svg>
|
||||
);
|
||||
case "Move":
|
||||
return Result.ok(
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" xmlSpace="preserve">
|
||||
<g fill="#ffffff">
|
||||
<path
|
||||
fill="#ffffff"
|
||||
d="M178.492 368a.5.5 0 0 0-.346.146l-2 2a.5.5 0 1 0 .708.708l1.146-1.147v7.586l-3 3V378.5a.5.5 0 0 0-.508-.508.5.5 0 0 0-.492.508v3a.5.5 0 0 0 .5.5h3a.5.5 0 1 0 0-1h-1.793l3-3h7.586l-1.147 1.146a.5.5 0 1 0 .708.708l2-2a.5.5 0 0 0 0-.708l-2-2a.5.5 0 0 0-.36-.152.5.5 0 0 0-.348.86l1.147 1.146H179v-7.293l1.146 1.147a.5.5 0 1 0 .708-.708l-2-2a.5.5 0 0 0-.362-.146z"
|
||||
transform="translate(-171 -365)"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
case "Save":
|
||||
return Result.ok(
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M18.1716 1C18.702 1 19.2107 1.21071 19.5858 1.58579L22.4142 4.41421C22.7893 4.78929 23 5.29799 23 5.82843V20C23 21.6569 21.6569 23 20 23H4C2.34315 23 1 21.6569 1 20V4C1 2.34315 2.34315 1 4 1H18.1716ZM4 3C3.44772 3 3 3.44772 3 4V20C3 20.5523 3.44772 21 4 21L5 21L5 15C5 13.3431 6.34315 12 8 12L16 12C17.6569 12 19 13.3431 19 15V21H20C20.5523 21 21 20.5523 21 20V6.82843C21 6.29799 20.7893 5.78929 20.4142 5.41421L18.5858 3.58579C18.2107 3.21071 17.702 3 17.1716 3H17V5C17 6.65685 15.6569 8 14 8H10C8.34315 8 7 6.65685 7 5V3H4ZM17 21V15C17 14.4477 16.5523 14 16 14L8 14C7.44772 14 7 14.4477 7 15L7 21L17 21ZM9 3H15V5C15 5.55228 14.5523 6 14 6H10C9.44772 6 9 5.55228 9 5V3Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
case "Select":
|
||||
return Result.ok(
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" viewBox="0 0 24 24">
|
||||
<path d="M6 3v18l5-7h9zm4.485 10L7 17.88V5.058L17.108 13z" fillRule="evenodd" />
|
||||
<path fill="none" d="M0 0h24v24H0z" />
|
||||
</svg>
|
||||
);
|
||||
case "Rotate":
|
||||
return Result.ok(
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="white" viewBox="0 0 24 24">
|
||||
<path d="M11.2797426,15.9868494 L10.1464466,14.8535534 C9.95118446,14.6582912 9.95118446,14.3417088 10.1464466,14.1464466 C10.3417088,13.9511845 10.6582912,13.9511845 10.8535534,14.1464466 L12.8535534,16.1464466 C13.0488155,16.3417088 13.0488155,16.6582912 12.8535534,16.8535534 L10.8535534,18.8535534 C10.6582912,19.0488155 10.3417088,19.0488155 10.1464466,18.8535534 C9.95118446,18.6582912 9.95118446,18.3417088 10.1464466,18.1464466 L11.3044061,16.9884871 C10.3667147,16.9573314 9.46306739,16.8635462 8.61196501,16.7145167 C9.33747501,19.2936084 10.6229353,21 12,21 C14.0051086,21 15.8160018,17.3821896 15.9868494,12.7202574 L14.8535534,13.8535534 C14.6582912,14.0488155 14.3417088,14.0488155 14.1464466,13.8535534 C13.9511845,13.6582912 13.9511845,13.3417088 14.1464466,13.1464466 L16.1464466,11.1464466 C16.3417088,10.9511845 16.6582912,10.9511845 16.8535534,11.1464466 L18.8535534,13.1464466 C19.0488155,13.3417088 19.0488155,13.6582912 18.8535534,13.8535534 C18.6582912,14.0488155 18.3417088,14.0488155 18.1464466,13.8535534 L16.9884871,12.6955939 C16.8167229,17.8651676 14.7413901,22 12,22 C9.97580598,22 8.3147521,19.7456544 7.515026,16.484974 C4.2543456,15.6852479 2,14.024194 2,12 C2,9.97580598 4.2543456,8.3147521 7.515026,7.515026 C8.3147521,4.2543456 9.97580598,2 12,2 C13.5021775,2 14.8263891,3.23888365 15.7433738,5.30744582 C15.8552836,5.55989543 15.7413536,5.8552671 15.4889039,5.96717692 C15.2364543,6.07908673 14.9410827,5.96515672 14.8291729,5.71270711 C14.0550111,3.96632921 13.0221261,3 12,3 C10.6229353,3 9.33747501,4.70639159 8.61196501,7.28548333 C9.67174589,7.09991387 10.812997,7 12,7 C17.4892085,7 22,9.13669069 22,12 C22,13.5021775 20.7611164,14.8263891 18.6925542,15.7433738 C18.4401046,15.8552836 18.1447329,15.7413536 18.0328231,15.4889039 C17.9209133,15.2364543 18.0348433,14.9410827 18.2872929,14.8291729 C20.0336708,14.0550111 21,13.0221261 21,12 C21,9.89274656 17.0042017,8 12,8 C10.6991081,8 9.46636321,8.12791023 8.35424759,8.35424759 C8.12791023,9.46636321 8,10.6991081 8,12 C8,13.3008919 8.12791023,14.5336368 8.35424759,15.6457524 C9.25899447,15.8298862 10.2435788,15.9488767 11.2797426,15.9868494 Z M7.28548333,8.61196501 C4.70639159,9.33747501 3,10.6229353 3,12 C3,13.3770647 4.70639159,14.662525 7.28548333,15.388035 C7.09991387,14.3282541 7,13.187003 7,12 C7,10.812997 7.09991387,9.67174589 7.28548333,8.61196501 L7.28548333,8.61196501 Z" />
|
||||
</svg>
|
||||
);
|
||||
case "Settings":
|
||||
return Result.ok(
|
||||
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
|
|
@ -55,7 +55,7 @@ export class AllProjectStore extends ModalStore {
|
|||
}
|
||||
if (this.file === undefined) {
|
||||
message.error("загрузите файл");
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
this.isLoading = true;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { extensions } from "../../../core/extensions/extensions";
|
||||
import { Form } from "../presentation/ui/forms/forms";
|
||||
import { ISkillView } from "../presentation/ui/skill_tree/skill_tree";
|
||||
|
||||
extensions();
|
||||
|
|
|
@ -6,6 +6,10 @@ export interface Parts {
|
|||
material_path: string;
|
||||
stlUrl: string;
|
||||
image: string;
|
||||
glUrl: string;
|
||||
solidType: string;
|
||||
daeUrl: string;
|
||||
objUrl: string;
|
||||
}
|
||||
|
||||
export class DetailsHttpRepository extends CoreHttpRepository {
|
||||
|
|
|
@ -29,6 +29,9 @@ export class DetailsStore extends UiDrawerFormState<EnvelopmentViewModel, CoreEr
|
|||
errorHandingStrategy = (error: CoreError) => {};
|
||||
init = async (navigate?: NavigateFunction | undefined): Promise<void> => {
|
||||
await this.mapOk("parts", this.detailsHttpRepository.getAssetsActiveProject());
|
||||
|
||||
|
||||
|
||||
this.detailsViewModel = this.parts.map((el) => {
|
||||
return {
|
||||
label: el.name,
|
||||
|
|
|
@ -2,20 +2,14 @@ import { Box3, GridHelper, Mesh, Object3D, Vector3 } from "three";
|
|||
import { CoreThreeRepository } from "../../core/repository/core_three_repository";
|
||||
|
||||
export class DetailsThreeRepository extends CoreThreeRepository {
|
||||
raiseAnObjectAboveZeroVector = (name: string) => {
|
||||
const mesh = this.scene.getObjectByName(name) as Object3D;
|
||||
mesh.position.sub(new Box3().setFromObject(mesh).min)
|
||||
}
|
||||
matchTwoPlacesInTheCenter = () => {
|
||||
|
||||
}
|
||||
|
||||
loadHttpAndPreview = (path: string, name: string, loadCallback?: Function) => {
|
||||
|
||||
this.loader(
|
||||
path,
|
||||
() => {
|
||||
this.raiseAnObjectAboveZeroVector(name)
|
||||
console.log(this.getCenterPoint(this.scene.children.filter((el) => el instanceof GridHelper).at(0) as Object3D))
|
||||
this.getCenterPoint(this.scene.children.filter((el) => el instanceof GridHelper).at(0) as Object3D)
|
||||
},
|
||||
name,
|
||||
new Vector3(0, 0, 0)
|
||||
|
|
30
ui/src/features/scene_manager/model/camera_view_model.ts
Normal file
30
ui/src/features/scene_manager/model/camera_view_model.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { Quaternion, Vector3 } from "three";
|
||||
import { SceneModelsTypes } from "./solid_body_model";
|
||||
import { Result } from "../../../core/helper/result";
|
||||
export enum CameraTypes {
|
||||
RGB = "RGB",
|
||||
}
|
||||
export class CameraModel {
|
||||
type = SceneModelsTypes.CAMERA;
|
||||
|
||||
constructor(
|
||||
public quaternion: Quaternion,
|
||||
public vector3: Vector3,
|
||||
public name: string,
|
||||
public cameraType: CameraTypes,
|
||||
public width: number,
|
||||
public updateRate: number,
|
||||
public fov: number,
|
||||
public near: number,
|
||||
public far: number,
|
||||
public height: number,
|
||||
public topic: string,
|
||||
public parent?: string,
|
||||
public fixed?: string
|
||||
) {}
|
||||
validate = (): Result<string, CameraModel> => {
|
||||
return Result.ok(this);
|
||||
};
|
||||
static empty = () =>
|
||||
new CameraModel(new Quaternion(0, 0, 0, 0), new Vector3(0, 0, 0), "", CameraTypes.RGB, 0, 0, 0, 0, 0, 0, "");
|
||||
}
|
|
@ -20,9 +20,8 @@ export interface SceneManagerView {
|
|||
}
|
||||
|
||||
export enum SceneMode {
|
||||
ROTATE = "Rotate",
|
||||
MOVING = "Moving",
|
||||
EMPTY = "Empty",
|
||||
ADD_CAMERA = "Add camera",
|
||||
MAGNETISM_MARKING = "magnetism_marking",
|
||||
Rotate = "Rotate",
|
||||
Move = "Move",
|
||||
Select = "Select",
|
||||
Save = 'Save',
|
||||
}
|
||||
|
|
30
ui/src/features/scene_manager/model/solid_body_model.ts
Normal file
30
ui/src/features/scene_manager/model/solid_body_model.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { Quaternion, Vector3 } from "three";
|
||||
|
||||
export enum SceneModelsTypes {
|
||||
SOLID = "SOLID",
|
||||
ROBOT = "ROBOT",
|
||||
LIGHT = "LIGHT",
|
||||
CAMERA = 'CAMERA'
|
||||
}
|
||||
export enum SolidBodyTypes {
|
||||
ACTIVE = "ACTIVE",
|
||||
STATIC = "STATIC",
|
||||
}
|
||||
interface ISpawnTypes {
|
||||
type: "POINT";
|
||||
name: "123";
|
||||
}
|
||||
export class SolidBodyModel {
|
||||
type = SceneModelsTypes.SOLID;
|
||||
spawn?: ISpawnTypes;
|
||||
constructor(
|
||||
public quaternion: Quaternion,
|
||||
public vector3: Vector3,
|
||||
public name: string,
|
||||
public solidType: SolidBodyTypes | string,
|
||||
public mesh: string,
|
||||
public collisionMesh: string,
|
||||
public inertia?: number,
|
||||
public mass?: number
|
||||
) {}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { SpawnPositionTypes } from "../../../../core/model/spawn_position_types";
|
||||
import { CoreButton } from "../../../../core/ui/button/button";
|
||||
import { CoreText, CoreTextType } from "../../../../core/ui/text/text";
|
||||
|
||||
export const SpawnPositionTypesForm = ({ onClick: onClick }: { onClick: Function }) => {
|
||||
return (
|
||||
<>
|
||||
<CoreText text={"Тип размещения"} type={CoreTextType.header} />
|
||||
{Object.entries(SpawnPositionTypes).map(([_, value], i) => (
|
||||
<CoreButton key={i} text={value} onClick={() => onClick(value)} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -1,31 +1,60 @@
|
|||
import { NavigateFunction } from "react-router-dom";
|
||||
import { CoreError, FormState, UiDrawerFormState } from "../../../../../core/store/base_store";
|
||||
import { CoreError, FormState } from "../../../../../core/store/base_store";
|
||||
import { CoreButton } from "../../../../../core/ui/button/button";
|
||||
import { CameraViewModel } from "../../../model/scene_assets";
|
||||
import { IDefaultSceneManagerProps } from "../scene_manager_forms";
|
||||
import { IDefaultSceneManagerFormProps } from "../scene_manager_forms";
|
||||
import React from "react";
|
||||
import { CoreInput } from "../../../../../core/ui/input/input";
|
||||
import { CoreText, CoreTextType } from "../../../../../core/ui/text/text";
|
||||
import { message } from "antd";
|
||||
import { CameraModel, CameraTypes } from "../../../model/camera_view_model";
|
||||
import { CoreSelect } from "../../../../../core/ui/select/select";
|
||||
|
||||
class CameraFormStore extends FormState<CameraViewModel, CoreError> {
|
||||
class CameraFormStore extends FormState<CameraModel, CoreError> {
|
||||
errorHandingStrategy = (error: CoreError) => {};
|
||||
init = async (navigate?: NavigateFunction | undefined) => {};
|
||||
viewModel: CameraViewModel = CameraViewModel.empty();
|
||||
viewModel: CameraModel = CameraModel.empty();
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
export const CameraForm = (props: IDefaultSceneManagerProps) => {
|
||||
export const CameraForm = (props: IDefaultSceneManagerFormProps) => {
|
||||
const [store] = React.useState(() => new CameraFormStore());
|
||||
|
||||
React.useEffect(() => {
|
||||
store.init();
|
||||
}, []);
|
||||
return (
|
||||
<div style={{ margin: 10, padding: 10 }}>
|
||||
<div style={{ margin: 10, padding: 10, overflowY: "auto", height: "100%" }}>
|
||||
<CoreText text="Камера" type={CoreTextType.header} />
|
||||
<CoreInput label={"Камера линк"} onChange={(text) => store.updateForm({ cameraLink: text })} />
|
||||
|
||||
<CoreInput value={store.viewModel.topic} label={"Топик"} onChange={(text) => store.updateForm({ topic: text })} />
|
||||
<CoreInput value={store.viewModel.name} label={"Имя"} onChange={(text) => store.updateForm({ name: text })} />
|
||||
<CoreInput
|
||||
value={String(store.viewModel.updateRate)}
|
||||
validation={(text) => Number().isValid(text)}
|
||||
label={"Update Rate"}
|
||||
onChange={(text) => store.updateForm({ updateRate: Number(text) })}
|
||||
/>
|
||||
<CoreInput
|
||||
value={String(store.viewModel.height)}
|
||||
validation={(text) => Number().isValid(text)}
|
||||
label={"Height"}
|
||||
onChange={(text) => store.updateForm({ height: Number(text) })}
|
||||
/>
|
||||
<CoreInput
|
||||
value={String(store.viewModel.width)}
|
||||
|
||||
validation={(text) => Number().isValid(text)}
|
||||
label={"Width"}
|
||||
onChange={(text) => store.updateForm({ width: Number(text) })}
|
||||
/>
|
||||
<CoreSelect
|
||||
items={Object.entries(CameraTypes).map(([_, v]) => v)}
|
||||
value={store.viewModel.cameraType}
|
||||
label={"Типы камер"}
|
||||
onChange={(text) => store.updateForm({ cameraType: text as CameraTypes })}
|
||||
/>
|
||||
<div style={{ height: 10 }} />
|
||||
<CoreButton
|
||||
text="Создать"
|
||||
|
@ -33,7 +62,7 @@ export const CameraForm = (props: IDefaultSceneManagerProps) => {
|
|||
onClick={() =>
|
||||
store.viewModel.validate().fold(
|
||||
(model) => {
|
||||
props.store.addNewCamera(model);
|
||||
// props.store.addNewCamera(model);
|
||||
},
|
||||
(error) => message.error(error)
|
||||
)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { IDefaultSceneManagerFormProps } from "../scene_manager_forms";
|
||||
|
||||
export const LightForm = observer((props: IDefaultSceneManagerFormProps) => {
|
||||
return <></>;
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
import { NavigateFunction } from "react-router-dom";
|
||||
import { FormState, CoreError } from "../../../../../core/store/base_store";
|
||||
import { LightViewModel } from "./light_view_model";
|
||||
|
||||
export class LightStore extends FormState<LightViewModel, CoreError> {
|
||||
viewModel: LightViewModel = LightViewModel.empty();
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
errorHandingStrategy = (error: CoreError) => {};
|
||||
init(navigate?: NavigateFunction | undefined): Promise<any> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import { Result } from "../../../../../core/helper/result";
|
||||
|
||||
export class LightViewModel {
|
||||
constructor() {}
|
||||
isValid = (): Result<void, LightViewModel> => {
|
||||
return Result.ok(this);
|
||||
};
|
||||
static empty = () => new LightViewModel();
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import React from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { PointStore, PointStoreType } from "./point_store";
|
||||
import { IDefaultSceneManagerFormProps } from "../scene_manager_forms";
|
||||
import { CoreText, CoreTextType } from "../../../../../core/ui/text/text";
|
||||
import { CoreInput } from "../../../../../core/ui/input/input";
|
||||
import { CoreButton } from "../../../../../core/ui/button/button";
|
||||
import { match } from "ts-pattern";
|
||||
import { SpawnPositionTypesForm } from "../../components/spawn_position_types";
|
||||
|
||||
export const PointForm = observer((props: IDefaultSceneManagerFormProps) => {
|
||||
const [store] = React.useState(() => new PointStore());
|
||||
React.useEffect(() => {
|
||||
store.init();
|
||||
}, [store]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{match(store.storeType)
|
||||
.with(PointStoreType.initNewPoint, () => (
|
||||
<>
|
||||
<CoreText text="Точка" type={CoreTextType.header} />
|
||||
<CoreInput label="Имя" onChange={(text) => store.updateForm({ name: text })} />
|
||||
<CoreButton
|
||||
text="Следующий этап"
|
||||
onClick={() => store.onClickNext(PointStoreType.makeSceneSolidAndEditPosition)}
|
||||
/>
|
||||
</>
|
||||
))
|
||||
.with(PointStoreType.makeSceneSolidAndEditPosition, () => (
|
||||
<>
|
||||
<SpawnPositionTypesForm onClick={store.selectSpawnType} />
|
||||
</>
|
||||
))
|
||||
.otherwise(() => (
|
||||
<></>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
});
|
|
@ -0,0 +1,6 @@
|
|||
import { HttpRepository } from "../../../../../core/repository/http_repository";
|
||||
|
||||
|
||||
export class PointHttpRepository extends HttpRepository {
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import makeAutoObservable from "mobx-store-inheritance";
|
||||
import { NavigateFunction } from "react-router-dom";
|
||||
import { PointViewModel } from "./point_view_model";
|
||||
import { PointHttpRepository } from "./point_http_repository";
|
||||
import { FormState, CoreError } from "../../../../../core/store/base_store";
|
||||
import { SpawnPositionTypes } from "../../../../../core/model/spawn_position_types";
|
||||
export enum PointStoreType {
|
||||
makeSceneSolidAndEditPosition = "makeSceneSolidAndEditPosition",
|
||||
initNewPoint = "initNewPoint",
|
||||
}
|
||||
export class PointStore extends FormState<PointViewModel, CoreError> {
|
||||
onClickNext = (pointStoreType: PointStoreType) => (this.storeType = pointStoreType);
|
||||
viewModel: PointViewModel = PointViewModel.empty();
|
||||
cameraDeviceHttpRepository: PointHttpRepository = new PointHttpRepository();
|
||||
storeType: PointStoreType = PointStoreType.initNewPoint;
|
||||
spawnPositionTypes: SpawnPositionTypes;
|
||||
constructor() {
|
||||
super();
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
selectSpawnType = (type: SpawnPositionTypes) => {
|
||||
this.spawnPositionTypes = type;
|
||||
};
|
||||
errorHandingStrategy = (error: CoreError) => {};
|
||||
init = async (navigate?: NavigateFunction | undefined) => {};
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { Quaternion, Vector3 } from "three";
|
||||
import { Result } from "../../../../../core/helper/result";
|
||||
|
||||
export class PointViewModel {
|
||||
type = "POINT";
|
||||
name: string;
|
||||
vector3: Vector3;
|
||||
quaternion: Quaternion;
|
||||
constructor() {}
|
||||
isValid(): Result<string, PointViewModel> {
|
||||
return Result.ok();
|
||||
}
|
||||
static empty() {
|
||||
return new PointViewModel();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { IDefaultSceneManagerProps } from "../scene_manager_forms";
|
||||
import { IDefaultSceneManagerFormProps } from "../scene_manager_forms";
|
||||
|
||||
|
||||
export const RobotForm = (props: IDefaultSceneManagerProps) => {
|
||||
export const RobotForm = (props: IDefaultSceneManagerFormProps) => {
|
||||
return <div>ROBOT</div>;
|
||||
};
|
||||
|
|
|
@ -1,23 +1,37 @@
|
|||
import { SceneMangerStore } from "../scene_manager_store";
|
||||
import { CameraForm } from "./camera/camera_form";
|
||||
import { LightForm } from "./light/light_form";
|
||||
import { PointForm } from "./point/point_form";
|
||||
import { RobotForm } from "./robot/robot_form";
|
||||
import { SolidBodyForm } from "./solid_body/solid_body_form";
|
||||
|
||||
import { Trajectory } from "./trajectory/trajectory_form";
|
||||
import { ZoneForm } from "./zone/zone_form";
|
||||
|
||||
export enum SceneManagerForms {
|
||||
robot = "robot",
|
||||
camera = "camera",
|
||||
solidBody = "solidBody",
|
||||
solidBody = "SolidBody",
|
||||
previewSolidBody = "previewSolidBody",
|
||||
light = "Light",
|
||||
point = "point",
|
||||
trajectory = "trajectory",
|
||||
zone = "zone",
|
||||
}
|
||||
interface IForms {
|
||||
name: string;
|
||||
component: JSX.Element;
|
||||
}
|
||||
export interface IDefaultSceneManagerProps {
|
||||
export interface IDefaultSceneManagerFormProps {
|
||||
dependency: Object;
|
||||
store: SceneMangerStore;
|
||||
}
|
||||
|
||||
export const sceneManagerForms = (props: Object, store: SceneMangerStore): IForms[] => [
|
||||
{ name: SceneManagerForms.camera, component: <CameraForm dependency={props} store={store} /> },
|
||||
{ name: SceneManagerForms.robot, component: <RobotForm dependency={props} store={store} /> },
|
||||
{ name: SceneManagerForms.solidBody, component: <SolidBodyForm dependency={props} store={store} /> },
|
||||
{ name: SceneManagerForms.point, component: <PointForm dependency={props} store={store} /> },
|
||||
{ name: SceneManagerForms.light, component: <LightForm dependency={props} store={store} /> },
|
||||
{ name: SceneManagerForms.zone, component: <ZoneForm dependency={props} store={store} /> },
|
||||
{ name: SceneManagerForms.trajectory, component: <Trajectory dependency={props} store={store} /> },
|
||||
];
|
||||
|
|
|
@ -1,5 +1,62 @@
|
|||
import { IDefaultSceneManagerProps } from "../scene_manager_forms";
|
||||
import React from "react";
|
||||
import { CoreText, CoreTextType } from "../../../../../core/ui/text/text";
|
||||
import { IDefaultSceneManagerFormProps } from "../scene_manager_forms";
|
||||
import { SolidBodyStore, SolidBodyStoreType } from "./solid_body_store";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { CoreButton } from "../../../../../core/ui/button/button";
|
||||
import { match } from "ts-pattern";
|
||||
import { SpawnPositionTypesForm } from "../../components/spawn_position_types";
|
||||
|
||||
export const SolidBodyForm = (props:IDefaultSceneManagerProps) => {
|
||||
return <></>;
|
||||
};
|
||||
export const SolidBodyForm = observer((props: IDefaultSceneManagerFormProps) => {
|
||||
const [store] = React.useState(() => new SolidBodyStore(props.store));
|
||||
React.useEffect(() => {
|
||||
store.init();
|
||||
}, []);
|
||||
return (
|
||||
<div style={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
|
||||
{Object.hasOwn(props.dependency, "type") && Object.hasOwn(props.dependency, "name") ? (
|
||||
<>
|
||||
x:{props.store.scene.find((el) => el.name.isEqual(props.store.selectedItemName ?? ""))?.vector3.x}
|
||||
y:{props.store.scene.find((el) => el.name.isEqual(props.store.selectedItemName ?? ""))?.vector3.y}
|
||||
y:{props.store.scene.find((el) => el.name.isEqual(props.store.selectedItemName ?? ""))?.vector3.z}
|
||||
solidType:{props.store.scene.find((el) => el.name.isEqual(props.store.selectedItemName ?? ""))?.solidType}
|
||||
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{match(store.solidBodyStoreType)
|
||||
.with(SolidBodyStoreType.selectBody, () => (
|
||||
<>
|
||||
<CoreText text={"Твердое тело"} type={CoreTextType.header} />
|
||||
|
||||
{store.parts.map((el, i) => (
|
||||
<div key={i} style={{ padding: 10, margin: 10 }}>
|
||||
<CoreText text={el.name} type={CoreTextType.medium} />
|
||||
<img src={el.image} />
|
||||
<CoreButton text="Выбрать" onClick={() => store.clickSelectBody(el)} />
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
))
|
||||
.with(SolidBodyStoreType.selectSpawnPositionType, () => (
|
||||
<>
|
||||
<SpawnPositionTypesForm onClick={store.selectSpawnType} />
|
||||
</>
|
||||
))
|
||||
.with(SolidBodyStoreType.spawn2DVector, () => (
|
||||
<>
|
||||
{props.store.mousePosition ? (
|
||||
""
|
||||
) : (
|
||||
<CoreText text={"Выберите точку размещения"} type={CoreTextType.header} />
|
||||
)}
|
||||
</>
|
||||
))
|
||||
.otherwise(() => (
|
||||
<></>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -4,14 +4,14 @@ import { FormState, CoreError } from "../../../../../core/store/base_store";
|
|||
import { CoreHttpRepository } from "../../../../../core/repository/http_repository";
|
||||
import { Parts } from "../../../../details/details_http_repository";
|
||||
import { Vector2 } from "three";
|
||||
import { SceneMangerStore } from "../../scene_manager_store";
|
||||
import { SpawnPositionTypes } from "../../../../../core/model/spawn_position_types";
|
||||
export enum SolidBodyStoreType {
|
||||
selectBody = "selectBody",
|
||||
selectSpawnPositionType = "selectSpawnPositionType",
|
||||
spawn2DVector = "spawn2DVector",
|
||||
}
|
||||
export enum SpawnPositionTypes {
|
||||
BoundBox = "BoundBox",
|
||||
}
|
||||
|
||||
export class SolidBodyStore extends FormState<SolidBodyViewModel, CoreError> {
|
||||
viewModel: SolidBodyViewModel = SolidBodyViewModel.empty();
|
||||
parts: Parts[] = [];
|
||||
|
@ -20,20 +20,33 @@ export class SolidBodyStore extends FormState<SolidBodyViewModel, CoreError> {
|
|||
solidBodyStoreType: SolidBodyStoreType = SolidBodyStoreType.selectBody;
|
||||
selectBody: Parts;
|
||||
spawnType: string;
|
||||
errorHandingStrategy = (error: CoreError) => {};
|
||||
constructor() {
|
||||
sceneManagerStore: SceneMangerStore;
|
||||
vector2d?: Vector2;
|
||||
|
||||
constructor(sceneManagerStore: SceneMangerStore) {
|
||||
super();
|
||||
this.sceneManagerStore = sceneManagerStore;
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
vector2d?: Vector2;
|
||||
init = async () => {
|
||||
this.mapOk("parts", this.coreHttpRepository.getAssetsActiveProject());
|
||||
};
|
||||
errorHandingStrategy = (error: CoreError) => {};
|
||||
|
||||
dispose = () => {};
|
||||
selectSpawnType = (type: string) => {
|
||||
this.spawnType = type;
|
||||
this.solidBodyStoreType = SolidBodyStoreType.spawn2DVector;
|
||||
this.sceneManagerStore.mousePositionAwait = true;
|
||||
this.sceneManagerStore.solidSpawnHelper = {
|
||||
url: this.selectBody.objUrl,
|
||||
name: this.selectBody.name,
|
||||
isFinished: false,
|
||||
solidType: this.selectBody.solidType,
|
||||
type: this.spawnType,
|
||||
};
|
||||
this.sceneManagerStore.activeFormType = undefined;
|
||||
};
|
||||
selectVector = () => {};
|
||||
clickSelectBody = (el: Parts) => {
|
||||
this.selectBody = el;
|
||||
this.solidBodyStoreType = SolidBodyStoreType.selectSpawnPositionType;
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import React from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { TrajectoryStore } from "./trajectory_store";
|
||||
import { IDefaultSceneManagerFormProps } from "../scene_manager_forms";
|
||||
|
||||
export const Trajectory = observer((props: IDefaultSceneManagerFormProps) => {
|
||||
const [store] = React.useState(() => new TrajectoryStore());
|
||||
React.useEffect(() => {
|
||||
store.init();
|
||||
}, [store]);
|
||||
|
||||
return <>Trajectory</>;
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
import { HttpRepository } from "../../../../../core/repository/http_repository";
|
||||
|
||||
export class TrajectoryHttpRepository extends HttpRepository {}
|
|
@ -0,0 +1,20 @@
|
|||
import makeAutoObservable from "mobx-store-inheritance";
|
||||
import { NavigateFunction } from "react-router-dom";
|
||||
import { TrajectoryViewModel } from "./trajectory_view_model";
|
||||
import { TrajectoryHttpRepository } from "./trajectory_http_repository";
|
||||
import { FormState, CoreError } from "../../../../../core/store/base_store";
|
||||
|
||||
export class TrajectoryStore extends FormState<TrajectoryViewModel, CoreError> {
|
||||
constructor() {
|
||||
super();
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
viewModel: TrajectoryViewModel = TrajectoryViewModel.empty();
|
||||
cameraDeviceHttpRepository: TrajectoryHttpRepository = new TrajectoryHttpRepository();
|
||||
errorHandingStrategy = (error: CoreError) => { }
|
||||
init = async (navigate?: NavigateFunction | undefined) => {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { Result } from "../../../../../core/helper/result";
|
||||
|
||||
|
||||
export class TrajectoryViewModel {
|
||||
constructor() {}
|
||||
isValid(): Result<string, TrajectoryViewModel> {
|
||||
return Result.ok();
|
||||
}
|
||||
static empty() {
|
||||
return new TrajectoryViewModel();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import React from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { ZoneStore } from "./zone_store";
|
||||
import { IDefaultSceneManagerFormProps } from "../scene_manager_forms";
|
||||
|
||||
|
||||
|
||||
export const ZoneForm = observer((props: IDefaultSceneManagerFormProps) => {
|
||||
const [store] = React.useState(() => new ZoneStore());
|
||||
React.useEffect(() => {
|
||||
store.init();
|
||||
}, [store]);
|
||||
|
||||
return <>zone</>;
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
import { HttpRepository } from "../../../../../core/repository/http_repository";
|
||||
|
||||
export class ZoneHttpRepository extends HttpRepository {}
|
|
@ -0,0 +1,19 @@
|
|||
import makeAutoObservable from "mobx-store-inheritance";
|
||||
import { NavigateFunction } from "react-router-dom";
|
||||
import { ZoneViewModel } from "./zone_view_model";
|
||||
import { ZoneHttpRepository } from "./zone_http_repository";
|
||||
import { FormState, CoreError } from "../../../../../core/store/base_store";
|
||||
|
||||
export class ZoneStore extends FormState<ZoneViewModel, CoreError> {
|
||||
constructor() {
|
||||
super();
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
viewModel: ZoneViewModel = ZoneViewModel.empty();
|
||||
cameraDeviceHttpRepository: ZoneHttpRepository = new ZoneHttpRepository();
|
||||
errorHandingStrategy = (error: CoreError) => { }
|
||||
init = async (navigate?: NavigateFunction | undefined) => {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { Result } from "../../../../../core/helper/result";
|
||||
|
||||
export class ZoneViewModel {
|
||||
name: string;
|
||||
constructor(name: string) {
|
||||
this.name = name;
|
||||
}
|
||||
isValid(): Result<string, ZoneViewModel> {
|
||||
return Result.ok();
|
||||
}
|
||||
static empty() {
|
||||
return new ZoneViewModel("");
|
||||
}
|
||||
}
|
|
@ -1,14 +1,13 @@
|
|||
import * as React from "react";
|
||||
import { DrawersSceneManager, SceneMangerStore, StoreMode } from "./scene_manager_store";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Drawer, Popover } from "antd";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { MainPage } from "../../../core/ui/pages/main_page";
|
||||
import { CoreText, CoreTextType } from "../../../core/ui/text/text";
|
||||
import { Drawer } from "antd";
|
||||
import { CoreButton } from "../../../core/ui/button/button";
|
||||
import { CoreInput } from "../../../core/ui/input/input";
|
||||
import { DrawersDataset } from "../../dataset/dataset_store";
|
||||
import { Popover } from "antd";
|
||||
import { Icon } from "../../../core/ui/icons/icons";
|
||||
import { sceneManagerForms } from "./forms/scene_manager_forms";
|
||||
|
||||
|
@ -34,6 +33,7 @@ export const SceneManger = observer(() => {
|
|||
return (
|
||||
<MainPage
|
||||
page={"Сцена"}
|
||||
panelStyle={{ display: store.storeMode.isEqual(StoreMode.sceneInstance) ? "" : "none" }}
|
||||
panelChildren={
|
||||
<div style={{ width: "100%", height: "100%" }}>
|
||||
<div style={{ height: 260, width: "100%", padding: 10 }}>
|
||||
|
@ -45,8 +45,8 @@ export const SceneManger = observer(() => {
|
|||
content={
|
||||
<div>
|
||||
{store.popoverItems.map((el, i) => (
|
||||
<div onClick={() => el.fn()}>
|
||||
<CoreText key={i} text={el.name} type={CoreTextType.medium} color="white" />
|
||||
<div key={i} onClick={() => el.fn()}>
|
||||
<CoreText text={el.name} type={CoreTextType.medium} color="white" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
@ -56,11 +56,33 @@ export const SceneManger = observer(() => {
|
|||
<CoreButton text="Добавить" filled={true} />
|
||||
</span>
|
||||
</Popover>
|
||||
<div style={{ position: "relative" }}>
|
||||
<div style={{ position: "absolute" }}>
|
||||
<div style={{ position: "relative", left: 20 }}>
|
||||
{store.sceneHelperInstruments.map((el, i) => (
|
||||
<div
|
||||
key={i}
|
||||
onClick={() => el.onClick()}
|
||||
style={{
|
||||
marginTop: 4,
|
||||
width: 50,
|
||||
height: 50,
|
||||
backgroundColor: el.isSelected ? "rgba(160, 132, 255, 1)" : "rgba(99, 81, 159, 1)",
|
||||
border: "1px solid",
|
||||
borderRadius: 5,
|
||||
}}
|
||||
>
|
||||
<Icon type={el.icon} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ height: 10 }} />
|
||||
<div
|
||||
style={{
|
||||
borderRadius: 22,
|
||||
borderRadius: 7,
|
||||
height: 200,
|
||||
width: "-webkit-fill-available",
|
||||
backgroundColor: "white",
|
||||
|
@ -71,15 +93,29 @@ export const SceneManger = observer(() => {
|
|||
<div
|
||||
key={index}
|
||||
style={{
|
||||
paddingLeft: 20,
|
||||
display: "flex",
|
||||
backgroundColor: index.isEven() ? "rgba(217, 217, 217, 0.27)" : "",
|
||||
backgroundColor: el.isSelected
|
||||
? "rgba(104, 80, 164, 0.47)"
|
||||
: index.isEven()
|
||||
? "rgba(217, 217, 217, 0.27)"
|
||||
: "",
|
||||
alignItems: "center",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
width: "100%",
|
||||
}}
|
||||
onClick={() => store.selectSceneItems(el.name, index, !el.isSelected)}
|
||||
>
|
||||
<Icon type={el.icon} />
|
||||
<Icon width={13} height={13} type={el.icon} style={{ marginLeft: 10 }} />
|
||||
<div style={{ width: 10 }} />
|
||||
<CoreText text={el.name} type={CoreTextType.small} />
|
||||
<Icon
|
||||
type="DeleteCircle"
|
||||
width={13}
|
||||
height={13}
|
||||
onClick={() => store.deleteSceneItem(el)}
|
||||
style={{ marginRight: 10 }}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
@ -92,12 +128,12 @@ export const SceneManger = observer(() => {
|
|||
borderRadius: 7,
|
||||
backgroundColor: "white",
|
||||
margin: 10,
|
||||
|
||||
overflow: "auto",
|
||||
}}
|
||||
>
|
||||
{sceneManagerForms(store.activeFormDependency ?? {}, store).map((el) => {
|
||||
{sceneManagerForms(store.activeFormDependency ?? {}, store).map((el, i) => {
|
||||
if (el.name.isEqual(store.activeFormType ?? "")) {
|
||||
return <>{el.component}</>;
|
||||
return <span key={i}>{el.component}</span>;
|
||||
}
|
||||
return <></>;
|
||||
})}
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
import makeAutoObservable from "mobx-store-inheritance";
|
||||
import { Object3D, Object3DEventMap, Vector2 } from "three";
|
||||
import { message } from "antd";
|
||||
import { CoreThreeRepository } from "../../../core/repository/core_three_repository";
|
||||
import { Object3D, Vector2 } from "three";
|
||||
import { HttpError } from "../../../core/repository/http_repository";
|
||||
import { UiDrawerFormState } from "../../../core/store/base_store";
|
||||
import { UiBaseError } from "../../../core/model/ui_base_error";
|
||||
import { SceneMenu, SceneMode } from "../model/scene_view";
|
||||
import { BaseSceneItemModel, CameraViewModel, RobossemblerFiles, StaticAssetItemModel } from "../model/scene_assets";
|
||||
import { SceneHttpRepository } from "../data/scene_http_repository";
|
||||
import { message } from "antd";
|
||||
import { RobossemblerAssets } from "../../../core/model/robossembler_assets";
|
||||
import { SceneViewModel } from "../model/scene_view_model";
|
||||
import { SceneModel } from "../model/scene_model";
|
||||
import { SceneManagerForms } from "./forms/scene_manager_forms";
|
||||
import { SolidBodyViewModel } from "./forms/solid_body/solid_body_view_model";
|
||||
import { SolidBodyModel } from "../model/solid_body_model";
|
||||
|
||||
export enum DrawersSceneManager {
|
||||
NewScene = "Новая сцена",
|
||||
|
@ -20,6 +22,13 @@ export enum StoreMode {
|
|||
sceneInstance = "sceneInstance",
|
||||
allScenes = "allScenes",
|
||||
}
|
||||
export interface ISolidSpawnHelper {
|
||||
url: string;
|
||||
solidType: string;
|
||||
name: string;
|
||||
isFinished: boolean;
|
||||
type: string;
|
||||
}
|
||||
interface IPopoverItem {
|
||||
name: string;
|
||||
fn: Function;
|
||||
|
@ -27,18 +36,12 @@ interface IPopoverItem {
|
|||
interface SceneItems {
|
||||
fn: Function;
|
||||
name: string;
|
||||
isSelected: boolean;
|
||||
icon: string;
|
||||
}
|
||||
export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpError> {
|
||||
popoverItems: IPopoverItem[] = [
|
||||
{ name: "Камера", fn: () => this.createNewForm(SceneManagerForms.camera, { store: this }) },
|
||||
{ name: "Твердое тело", fn: () => this.createNewForm(SceneManagerForms.solidBody, { store: this }) },
|
||||
{ name: "Робот", fn: () => this.createNewForm(SceneManagerForms.robot, { store: this }) },
|
||||
{ name: "Точка", fn: () => {} },
|
||||
{ name: "Траектория", fn: () => {} },
|
||||
{ name: "Зона", fn: () => {} },
|
||||
];
|
||||
activeFormType?: string;
|
||||
selectedItemName?: string;
|
||||
activeFormDependency?: Object;
|
||||
viewModel: SceneViewModel = SceneViewModel.empty();
|
||||
sceneMode: SceneMode;
|
||||
|
@ -55,19 +58,79 @@ export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpErro
|
|||
scenes: SceneModel[] = [];
|
||||
storeMode: StoreMode;
|
||||
canvasRef?: HTMLCanvasElement;
|
||||
mousePositionAwait: boolean = false;
|
||||
mousePosition?: Vector2;
|
||||
solidSpawnHelper?: ISolidSpawnHelper;
|
||||
selectSceneObject?: Object;
|
||||
isLoadingForm: boolean = false;
|
||||
scene: SolidBodyModel[] = [];
|
||||
|
||||
sceneHelperInstruments: { icon: string; onClick: Function; isSelected: boolean }[] = [
|
||||
{ icon: SceneMode.Select, onClick: () => this.setMode(SceneMode.Select), isSelected: false },
|
||||
{ icon: SceneMode.Move, onClick: () => this.setMode(SceneMode.Move), isSelected: false },
|
||||
{ icon: SceneMode.Rotate, onClick: () => this.setMode(SceneMode.Rotate), isSelected: false },
|
||||
{
|
||||
icon: SceneMode.Save,
|
||||
onClick: () => {
|
||||
this.setMode(SceneMode.Rotate);
|
||||
this.sceneSave();
|
||||
},
|
||||
isSelected: false,
|
||||
},
|
||||
];
|
||||
popoverItems: IPopoverItem[] = [
|
||||
{ name: "Камера", fn: () => this.createNewForm(SceneManagerForms.camera) },
|
||||
{ name: "Твердое тело", fn: () => this.createNewForm(SceneManagerForms.solidBody) },
|
||||
{ name: "Источник света", fn: () => this.createNewForm(SceneManagerForms.light) },
|
||||
{ name: "Робот", fn: () => this.createNewForm(SceneManagerForms.robot) },
|
||||
{ name: "Точка", fn: () => this.createNewForm(SceneManagerForms.point) },
|
||||
{ name: "Траектория", fn: () => this.createNewForm(SceneManagerForms.trajectory) },
|
||||
{ name: "Зона", fn: () => this.createNewForm(SceneManagerForms.zone) },
|
||||
];
|
||||
constructor() {
|
||||
super(DrawersSceneManager);
|
||||
makeAutoObservable(this);
|
||||
this.sceneItems = [];
|
||||
this.sceneHttpRepository = new SceneHttpRepository();
|
||||
this.sceneMode = SceneMode.EMPTY;
|
||||
this.sceneMode = SceneMode.Select;
|
||||
this.sceneMenu = SceneMenu.empty();
|
||||
}
|
||||
createNewForm = (formType: SceneManagerForms, dependency: Object) => {
|
||||
this.activeFormDependency = dependency;
|
||||
sceneSave = () => {};
|
||||
selectSceneItems = (name: string, index: number, selected: boolean) => {
|
||||
this.sceneItems.map((el, i) => i.isEqualR(index).map(() => (el.isSelected = selected)));
|
||||
if (selected) {
|
||||
this.createNewForm(SceneManagerForms.solidBody);
|
||||
this.selectedItemName = name;
|
||||
}
|
||||
|
||||
if (!selected) {
|
||||
this.createNewForm(undefined);
|
||||
this.selectedItemName = undefined;
|
||||
}
|
||||
|
||||
this.activeFormDependency = {
|
||||
type: "Preview",
|
||||
name: name,
|
||||
};
|
||||
};
|
||||
|
||||
setMode = (mode: SceneMode) => {
|
||||
this.sceneHelperInstruments.map((el) => {
|
||||
el.isSelected = false;
|
||||
if (el.icon.isEqual(mode)) {
|
||||
el.isSelected = true;
|
||||
}
|
||||
});
|
||||
this.sceneMode = mode;
|
||||
this.coreThreeRepository?.setTransformMode(this.sceneMode);
|
||||
this.sceneModeWatcher();
|
||||
};
|
||||
createNewForm = (formType: SceneManagerForms | undefined) => {
|
||||
this.activeFormDependency = {
|
||||
store: this,
|
||||
};
|
||||
this.activeFormType = formType;
|
||||
};
|
||||
makeSolid = () => {};
|
||||
createNewScene = () =>
|
||||
this.viewModel.valid().fold(
|
||||
async (s) => {
|
||||
|
@ -78,12 +141,11 @@ export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpErro
|
|||
async (e) => message.error(e)
|
||||
);
|
||||
|
||||
deleteSceneItem(item: BaseSceneItemModel) {
|
||||
const itm = this.sceneModels.filter((el) => el.id === item.id);
|
||||
this.coreThreeRepository!.deleteSceneItem(itm[0]);
|
||||
this.sceneModels = this.sceneModels.filter((el) => el.name !== item.name);
|
||||
deleteSceneItem = (item: SceneItems) => {
|
||||
this.sceneItems = this.sceneItems.filter((el) => !el.name.isEqual(item.name));
|
||||
this.coreThreeRepository?.deleteSceneItem(item.name);
|
||||
this.visibleSaveButton();
|
||||
}
|
||||
};
|
||||
|
||||
visibleSaveButton = () => {
|
||||
this.isVisibleSaveButton = true;
|
||||
|
@ -92,7 +154,8 @@ export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpErro
|
|||
addNewCamera = (model: CameraViewModel) => {
|
||||
model.position = this.coreThreeRepository!.camera.position;
|
||||
model.quaternion = this.coreThreeRepository!.camera.quaternion;
|
||||
this.sceneItems.push({ name: model.cameraLink, icon: "Camera", fn: () => {} });
|
||||
this.sceneItems.push({ name: model.cameraLink, icon: "Camera", fn: () => {}, isSelected: false });
|
||||
|
||||
this.coreThreeRepository?.addSceneCamera(model);
|
||||
this.visibleSaveButton();
|
||||
};
|
||||
|
@ -117,7 +180,7 @@ export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpErro
|
|||
} catch (error) {
|
||||
message.error(String(error));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
isRenderedAsset(name: string): boolean {
|
||||
return this.sceneModels
|
||||
|
@ -130,19 +193,7 @@ export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpErro
|
|||
.isNotEmpty();
|
||||
}
|
||||
|
||||
hiddenMenu() {
|
||||
this.isSceneMenuShow = false;
|
||||
}
|
||||
|
||||
setSceneMode = (mode: SceneMode) => {
|
||||
if (this.sceneMode === undefined || this.sceneMode !== mode) {
|
||||
this.sceneMode = mode;
|
||||
} else if (this.sceneMode === mode) {
|
||||
this.sceneMode = SceneMode.EMPTY;
|
||||
}
|
||||
this.coreThreeRepository?.setTransformMode(this.sceneMode);
|
||||
this.sceneModeWatcher();
|
||||
};
|
||||
hiddenMenu = () => (this.isSceneMenuShow = false);
|
||||
|
||||
sceneModeWatcher() {}
|
||||
|
||||
|
@ -155,20 +206,19 @@ export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpErro
|
|||
this.mapOk("scenes", this.sceneHttpRepository.getAllScenes());
|
||||
}
|
||||
};
|
||||
errorHandingStrategy = (error: HttpError) => {
|
||||
if (error.status === 404) {
|
||||
this.errors.push(new UiBaseError(`${RobossemblerFiles.robossemblerAssets} not found to project`));
|
||||
}
|
||||
};
|
||||
errorHandingStrategy = (error: HttpError) =>
|
||||
error.status
|
||||
.isEqualR(404)
|
||||
.map(() => this.errors.push(new UiBaseError(`${RobossemblerFiles.robossemblerAssets} not found to project`)));
|
||||
|
||||
async loadScene(canvasRef: HTMLCanvasElement) {
|
||||
loadScene = (canvasRef: HTMLCanvasElement) => {
|
||||
this.canvasRef = canvasRef;
|
||||
if (this.storeMode.isEqual(StoreMode.sceneInstance)) this.loadWebGl(canvasRef);
|
||||
this.storeMode.isEqualR(StoreMode.sceneInstance).map(() => this.loadWebGl(canvasRef));
|
||||
// await this.mapOk<RobossemblerAssets>("robossemblerAssets", this.sceneHttpRepository.getRobossemblerAssets());
|
||||
// if (this.robossemblerAssets) {
|
||||
// this.coreThreeRepository?.loadInstances(this.robossemblerAssets);
|
||||
// }
|
||||
}
|
||||
};
|
||||
|
||||
loadWebGl(canvasRef: HTMLCanvasElement): void {
|
||||
this.coreThreeRepository = new CoreThreeRepository(canvasRef as HTMLCanvasElement, this.watcherSceneEditorObject);
|
||||
|
@ -176,56 +226,80 @@ export class SceneMangerStore extends UiDrawerFormState<SceneViewModel, HttpErro
|
|||
this.coreThreeRepository.render();
|
||||
this.sceneModels = this.coreThreeRepository.getAllSceneModels();
|
||||
|
||||
window.addEventListener("click", (event) => this.clickLister(event));
|
||||
window.addEventListener("mousedown", (e) => this.sceneContextMenu(e));
|
||||
canvasRef.addEventListener("click", (event) => this.clickLister(event, canvasRef.getBoundingClientRect().x));
|
||||
|
||||
canvasRef.addEventListener("mousedown", (e) => this.sceneContextMenu(e));
|
||||
}
|
||||
|
||||
clickLister(event: MouseEvent) {
|
||||
clickLister = (event: MouseEvent, offset: number = 0) => {
|
||||
const vector = new Vector2();
|
||||
vector.x = (event.clientX / window.innerWidth) * 2 - 1;
|
||||
vector.y = -(event.clientY / window.innerHeight) * 2 + 1;
|
||||
if (this.sceneMode === SceneMode.EMPTY) {
|
||||
const boundingRect = this.canvasRef!.getBoundingClientRect();
|
||||
|
||||
vector.x = ((event.clientX - offset) / boundingRect.width) * 2 - 1;
|
||||
vector.y = -(event.clientY / boundingRect.height) * 2 + 1;
|
||||
if (this.mousePositionAwait && this.solidSpawnHelper) {
|
||||
this.mousePositionAwait = false;
|
||||
this.mousePosition = vector;
|
||||
this.coreThreeRepository?.setRayCastAndGetFirstObjectAndPointToObject(vector).map((v3) => {
|
||||
this.coreThreeRepository?.solidSpawn(
|
||||
this.solidSpawnHelper as ISolidSpawnHelper,
|
||||
(obj: Object3D<Object3DEventMap> | undefined) => {
|
||||
const { solidType, name, url } = this.solidSpawnHelper as ISolidSpawnHelper;
|
||||
this.scene.push(new SolidBodyModel(obj!.quaternion, obj!.position, name, solidType, url, url));
|
||||
this.sceneItems.push({
|
||||
name: String(this.solidSpawnHelper?.name),
|
||||
icon: "Solid",
|
||||
isSelected: false,
|
||||
fn: () => this.createNewForm(SceneManagerForms.solidBody),
|
||||
});
|
||||
},
|
||||
v3
|
||||
);
|
||||
});
|
||||
}
|
||||
if (this.sceneMode.isEqual(SceneMode.Select)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.sceneMode === SceneMode.MOVING || this.sceneMode === SceneMode.ROTATE) {
|
||||
if (this.sceneMode === SceneMode.Move || this.sceneMode === SceneMode.Rotate) {
|
||||
this.transformContollsCall(vector);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
sceneContextMenu(e: MouseEvent): void {
|
||||
if (e.button === 2) {
|
||||
sceneContextMenu = (e: MouseEvent) =>
|
||||
e.button.isEqualR(2).map(() => {
|
||||
this.isSceneMenuShow = true;
|
||||
this.sceneMenu.x = e.clientX;
|
||||
this.sceneMenu.y = e.clientY;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
watcherThereObjects = (sceneItemModel: BaseSceneItemModel): void => {
|
||||
this.sceneModels.push(sceneItemModel);
|
||||
watcherThereObjects = (sceneItemModel: BaseSceneItemModel) => {
|
||||
// this.sceneModels.push(sceneItemModel);
|
||||
console.log(sceneItemModel);
|
||||
};
|
||||
|
||||
watcherSceneEditorObject = (mesh: Object3D) => {
|
||||
this.sceneModels = this.sceneModels.map((el) => {
|
||||
if (el.name === mesh.name) {
|
||||
el.position = mesh.position;
|
||||
el.quaternion = mesh.quaternion;
|
||||
return el;
|
||||
}
|
||||
return el;
|
||||
});
|
||||
this.scene = this.scene.map((el) =>
|
||||
el.name.isEqualR(mesh.name).fold(
|
||||
() => {
|
||||
el.vector3 = mesh.position;
|
||||
el.quaternion = mesh.quaternion;
|
||||
return el;
|
||||
},
|
||||
() => el
|
||||
)
|
||||
);
|
||||
this.visibleSaveButton();
|
||||
};
|
||||
|
||||
transformContollsCall = (vector: Vector2) => {
|
||||
transformContollsCall = (vector: Vector2) =>
|
||||
this.coreThreeRepository?.setRayCastAndGetFirstObject(vector).fold(
|
||||
(success) => this.coreThreeRepository?.setTransformControlsAttach(success),
|
||||
(_error) => this.coreThreeRepository?.disposeTransformControlsMode()
|
||||
(object) => this.coreThreeRepository?.setTransformControlsAttach(object),
|
||||
(_) => this.coreThreeRepository?.disposeTransformControlsMode()
|
||||
);
|
||||
};
|
||||
|
||||
dispose() {
|
||||
dispose = () => {
|
||||
window.removeEventListener("click", this.clickLister);
|
||||
window.removeEventListener("mousedown", (e) => this.sceneContextMenu(e));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
"useDefineForClassFields": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"strictPropertyInitialization": false
|
||||
"strictPropertyInitialization": false,
|
||||
"sourceMap": true
|
||||
},
|
||||
"types": ["babylonjs", "babylonjs-loaders"],
|
||||
"include": ["src"]
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
{
|
||||
"eslintConfig": {
|
||||
"extends": ["react-app", "shared-config"],
|
||||
"extends": [
|
||||
"react-app",
|
||||
"shared-config"
|
||||
],
|
||||
"rules": {
|
||||
"additional-rule": "warn",
|
||||
"no-extend-native":"off",
|
||||
"react-hooks/exhaustive-deps":"off"
|
||||
"no-extend-native": "off",
|
||||
"react-hooks/exhaustive-deps": "off",
|
||||
"array-callback-return": "off"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/*.ts?(x)"],
|
||||
"files": [
|
||||
"**/*.ts?(x)"
|
||||
],
|
||||
"rules": {
|
||||
"additional-typescript-only-rule": "warn",
|
||||
"array-callback-return": "off",
|
||||
"react-hooks/exhaustive-deps": "off",
|
||||
"no-extend-native":"off"
|
||||
"no-extend-native": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
BIN
web_p/blender/.DS_Store
vendored
Normal file
BIN
web_p/blender/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
web_p/blender/assets/.DS_Store
vendored
Normal file
BIN
web_p/blender/assets/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
web_p/blender/libs/.DS_Store
vendored
Normal file
BIN
web_p/blender/libs/.DS_Store
vendored
Normal file
Binary file not shown.
2881
web_p/blender/libs/objects/body_down.obj
Normal file
2881
web_p/blender/libs/objects/body_down.obj
Normal file
File diff suppressed because it is too large
Load diff
2913
web_p/blender/libs/objects/body_up.obj
Normal file
2913
web_p/blender/libs/objects/body_up.obj
Normal file
File diff suppressed because it is too large
Load diff
|
@ -6,6 +6,7 @@ import blenderproc as bproc
|
|||
Используется модуль blenderproc
|
||||
|
||||
02.05.2024 @shalenikol release 0.1
|
||||
02.07.2024 @shalenikol release 0.2
|
||||
"""
|
||||
import numpy as np
|
||||
import argparse
|
||||
|
@ -13,25 +14,37 @@ import random
|
|||
import os
|
||||
import shutil
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import bpy
|
||||
|
||||
VHACD_PATH = "blenderproc_resources/vhacd"
|
||||
DIR_MODELS = "models"
|
||||
DIR_MESH = "assets/libs/objects/" #"assets/mesh/"
|
||||
FILE_LOG_SCENE = "res.txt"
|
||||
FILE_RBS_INFO = "rbs_info.json"
|
||||
FILE_GT_COCO = "scene_gt_coco.json"
|
||||
EXT_MODELS = ".fbx"
|
||||
TEXTURE_TMPL = "*.jpg"
|
||||
|
||||
Not_Categories_Name = True # наименование категории в COCO-аннотации отсутствует
|
||||
|
||||
def _get_list_texture(rel_path: str) -> list:
|
||||
# local_path/texture/
|
||||
loc = os.path.dirname(os.path.dirname(rnd_par.output_dir))
|
||||
path = os.path.join(loc, rel_path)
|
||||
return list(Path(path).absolute().rglob(TEXTURE_TMPL))
|
||||
|
||||
def _get_path_model(name_model: str) -> str:
|
||||
# TODO on name_model find path for mesh (model.fbx)
|
||||
# local_path/assets/mesh/
|
||||
# local_path/assets/libs/objects # assets/mesh/
|
||||
loc = os.path.dirname(os.path.dirname(rnd_par.output_dir))
|
||||
return os.path.join(loc, "assets/mesh/"+name_model+".fbx")
|
||||
return os.path.join(loc, DIR_MESH + name_model + EXT_MODELS)
|
||||
|
||||
def _get_path_object(name_obj: str) -> str:
|
||||
# TODO on name_obj find path for scene object (object.fbx)
|
||||
loc = os.path.dirname(os.path.dirname(rnd_par.output_dir))
|
||||
return os.path.join(loc, "assets/mesh/"+name_obj+".fbx")
|
||||
return os.path.join(loc, DIR_MESH + name_obj + EXT_MODELS)
|
||||
|
||||
def convert2relative(height, width, bbox):
|
||||
"""
|
||||
|
@ -43,11 +56,14 @@ def convert2relative(height, width, bbox):
|
|||
return x/width, y/height, w/width, h/height
|
||||
|
||||
def render() -> int:
|
||||
i = 0
|
||||
for obj in all_meshs:
|
||||
# Make the object actively participate in the physics simulation
|
||||
obj.enable_rigidbody(active=True, collision_shape="COMPOUND")
|
||||
# Also use convex decomposition as collision shapes
|
||||
obj.build_convex_decomposition_collision_shape(VHACD_PATH)
|
||||
i += 1
|
||||
# print(f"{i} : {obj.get_name()}")
|
||||
|
||||
objs = all_meshs + rnd_par.scene.objs
|
||||
|
||||
|
@ -85,13 +101,26 @@ def render() -> int:
|
|||
# Цикл рендеринга
|
||||
# Do multiple times: Position the shapenet objects using the physics simulator and render X images with random camera poses
|
||||
for r in range(rnd_par.n_series):
|
||||
print(f"********** Series : {r+1}")
|
||||
is_texture = True if "texture_path" in rnd_par.models_randomization else False
|
||||
if is_texture:
|
||||
val = rnd_par.models_randomization["texture_path"]
|
||||
l_texture = _get_list_texture(val)
|
||||
image = bpy.data.images.load(filepath=str(l_texture[r % len(l_texture)]))
|
||||
# один случайный объект в кадре / все заданные объекты
|
||||
random_obj = random.choice(range(rnd_par.scene.n_obj))
|
||||
random_obj = random.choice(range(rnd_par.models.n_item))
|
||||
meshs = []
|
||||
for i,o in enumerate(all_meshs): #objs
|
||||
for i,o in enumerate(all_meshs): # активные модели
|
||||
if rnd_par.single_object and i != random_obj:
|
||||
continue
|
||||
meshs += [o]
|
||||
if is_texture:
|
||||
mats = o.get_materials()
|
||||
for mat in mats:
|
||||
# image = bpy.data.images.load(filepath=str(random.choice(l_texture)))
|
||||
mat.set_principled_shader_value("Base Color", image)
|
||||
|
||||
for i,o in enumerate(rnd_par.scene.objs): # объекты сцены
|
||||
rnd_mat = rnd_par.scene.obj_data[i]["material_randomization"]
|
||||
mats = o.get_materials() #[0]
|
||||
for mat in mats:
|
||||
|
@ -99,10 +128,17 @@ def render() -> int:
|
|||
mat.set_principled_shader_value("Specular", random.uniform(val[0], val[1]))
|
||||
val = rnd_mat["roughness"]
|
||||
mat.set_principled_shader_value("Roughness", random.uniform(val[0], val[1]))
|
||||
val = rnd_mat["base_color"]
|
||||
mat.set_principled_shader_value("Base Color", np.random.uniform(val[0], val[1]))
|
||||
val = rnd_mat["metallic"]
|
||||
mat.set_principled_shader_value("Metallic", random.uniform(val[0], val[1]))
|
||||
if "texture_path" in rnd_mat: # путь к текстурам (*.jpg)
|
||||
val = rnd_mat["texture_path"]
|
||||
val = _get_list_texture(val)
|
||||
image = bpy.data.images.load(filepath=str(random.choice(val)))
|
||||
mat.set_principled_shader_value("Base Color", image)
|
||||
else:
|
||||
val = rnd_mat["base_color"]
|
||||
mat.set_principled_shader_value("Base Color", np.random.uniform(val[0], val[1]))
|
||||
# mat.set_principled_shader_value("Base Color", image)
|
||||
|
||||
# Randomly set the color and energy
|
||||
for i,l in enumerate(ls):
|
||||
|
@ -225,7 +261,7 @@ def render() -> int:
|
|||
cat["name"] = rnd_par.models.names[i] #obj_names[i]
|
||||
|
||||
with open(coco_file, "w") as fh:
|
||||
json.dump(data, fh, indent=0)
|
||||
json.dump(data, fh, indent=1)
|
||||
|
||||
def explore(path: str):
|
||||
if not os.path.isdir(path):
|
||||
|
@ -331,7 +367,7 @@ if __name__ == "__main__":
|
|||
models_randomization = ds_cfg["models_randomization"]
|
||||
|
||||
rnd_par = lambda: None
|
||||
rnd_par.single_object = True
|
||||
rnd_par.single_object = False # True
|
||||
rnd_par.ds_name = cfg["name"]
|
||||
rnd_par.output_dir = cfg["local_path"]
|
||||
rnd_par.dataset_objs = cfg["dataSetObjects"]
|
||||
|
@ -343,6 +379,7 @@ if __name__ == "__main__":
|
|||
rnd_par.center_shell = cam_pos["center_shell"]
|
||||
rnd_par.radius_range = cam_pos["radius_range"]
|
||||
rnd_par.elevation_range = cam_pos["elevation_range"]
|
||||
rnd_par.models_randomization = models_randomization
|
||||
rnd_par.loc_range_low = models_randomization["loc_range_low"]
|
||||
rnd_par.loc_range_high = models_randomization["loc_range_high"]
|
||||
|
||||
|
@ -353,8 +390,7 @@ if __name__ == "__main__":
|
|||
bproc.init()
|
||||
|
||||
all_meshs = []
|
||||
ret = _get_models(rnd_par, rnd_par.dataset_objs)
|
||||
if ret <= 0:
|
||||
if _get_models(rnd_par, rnd_par.dataset_objs) <= 0:
|
||||
print("Error: no models in config")
|
||||
exit(-4)
|
||||
if _get_scene(rnd_par, ds_cfg["scene"]) == 0:
|
||||
|
|
1
web_p/robot_builder/base.dae
Symbolic link
1
web_p/robot_builder/base.dae
Symbolic link
|
@ -0,0 +1 @@
|
|||
/home/idontsudo/robossembler_ws/src/rbs_gripper/meshes/visual/base.dae
|
1
web_p/robot_builder/ee_link.dae
Symbolic link
1
web_p/robot_builder/ee_link.dae
Symbolic link
|
@ -0,0 +1 @@
|
|||
/home/idontsudo/robossembler_ws/src/rbs_arm/meshes/visual/ee_link.dae
|
1
web_p/robot_builder/finger.dae
Symbolic link
1
web_p/robot_builder/finger.dae
Symbolic link
|
@ -0,0 +1 @@
|
|||
/home/idontsudo/robossembler_ws/src/rbs_gripper/meshes/visual/finger.dae
|
1
web_p/robot_builder/fork_link.dae
Symbolic link
1
web_p/robot_builder/fork_link.dae
Symbolic link
|
@ -0,0 +1 @@
|
|||
/home/idontsudo/robossembler_ws/src/rbs_arm/meshes/visual/fork_link.dae
|
1
web_p/robot_builder/main_link.dae
Symbolic link
1
web_p/robot_builder/main_link.dae
Symbolic link
|
@ -0,0 +1 @@
|
|||
/home/idontsudo/robossembler_ws/src/rbs_arm/meshes/visual/main_link.dae
|
346
web_p/robot_builder/robot.xml
Normal file
346
web_p/robot_builder/robot.xml
Normal file
|
@ -0,0 +1,346 @@
|
|||
<robot name="rbs_arm">n <link name="world" />n <joint name="base_link_joint" type="fixed">n <origin
|
||||
rpy="0.0 0.0 0.0" xyz="0.0 0.0 0.0" />n <parent
|
||||
link="world" />n <child link="base_link" />n </joint>n <link name="base_link">n <collision
|
||||
name="base_link_collision">n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.00000 0.00000 0.00000" />n <geometry>n <mesh
|
||||
filename="start_link.stl"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </collision> n <inertial>n <inertia
|
||||
ixx="0.00503302470272442" ixy="0.000343817346410954" ixz="-4.74990755448368E-06"
|
||||
iyy="0.00337962410057753" iyz="-2.3099255620051E-05" izz="0.00405858207282473" />n <origin
|
||||
rpy="0.00000 0.00000 0.00000"
|
||||
xyz="-0.000297002857922682 0.0964721185617698 -0.000361033370053684" /> n <mass
|
||||
value="1.88031044620482" />n </inertial>n <visual name="base_link_visual">n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.00000 0.00000 0.00000" />n <geometry> n <mesh
|
||||
filename="start_link.dae"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </visual>n </link>n <gazebo
|
||||
reference="base_link">n <visual>n <material>n <diffuse>0.8 0.8 0.8 1</diffuse>n <specular>0.6
|
||||
0.6
|
||||
0.6 1</specular>n <ambient>1.0 1.0 1.0</ambient>n <lighting>true</lighting>n <emissive>0
|
||||
0 0
|
||||
1</emissive>n <pbr>n <metal>n <albedo_map>
|
||||
/base_link_d.png</albedo_map> n <normal_map>
|
||||
/base_link_n.png</normal_map>
|
||||
n <ambient_occlusion_map>
|
||||
/base_link_ao.png</ambient_occlusion_map>
|
||||
n <roughness_map>
|
||||
/base_link_r.png</roughness_map>
|
||||
n </metal>n </pbr>n </material>n </visual>n </gazebo>n <joint name="fork0_link_joint"
|
||||
type="revolute">n <limit
|
||||
effort="78" lower="-6.14159" upper="6.14159" velocity="0.52" />n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.00000 0.00000 0.17833" />n <parent link="base_link" />
|
||||
n <child link="fork0_link" />n <axis xyz="0 0 1" />n </joint>n <link name="fork0_link">n <collision
|
||||
name="fork0_link_collision">n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.00000 -0.00000 0.00000" />n <geometry>n <mesh
|
||||
filename="fork_link.stl"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </collision> n <inertial>n <inertia
|
||||
ixx="0.00367804533572758" ixy="1.04277925521833E-05" ixz="-0.00149971410403071"
|
||||
iyy="0.00415208849477534" iyz="-0.00122" izz="0.00329" />n <origin
|
||||
rpy="0.00000 0.00000 0.00000"
|
||||
xyz="0.0472051139085306 0.00208890925682996 0.0557265410642575" /> n <mass
|
||||
value="1.12472202892859" />n </inertial>n <visual name="fork0_link_visual">n <origin
|
||||
rpy="0.00000 -0.00000 -0.00000" xyz="0.00000 -0.00000 0.00000" />n <geometry> n <mesh
|
||||
filename="fork_link.dae"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </visual>n </link>n <ros2_control
|
||||
name="fork0_link_joint_hardware_interface" type="actuator">n <hardware>n <plugin>
|
||||
ign_ros2_control/IgnitionSystem</plugin>n </hardware> n <joint name="fork0_link_joint">n <command_interface
|
||||
name="position">n <!-- <param name="min">-1</param> -->n <!-- <param name="max">1</param> -->n </command_interface>n <command_interface
|
||||
name="velocity">n <!-- <param name="min">-1</param> -->n <!-- <param name="max">1</param> -->n </command_interface>n <!-- WARN When this active a robot falls
|
||||
down -->n <!-- <command_interface
|
||||
name="effort"/> -->n <!-- <param name="p">${p}</param> -->n <!-- <param name="d">${d}</param> -->n <!-- <command_interface
|
||||
name="effort"/> -->n <state_interface
|
||||
name="position" />n <state_interface
|
||||
name="velocity" />n <state_interface name="effort" />n </joint>n </ros2_control>n <gazebo
|
||||
reference="fork0_link">n <visual>n <material>n <diffuse>0.8 0.8 0.8 1</diffuse>n <specular>0.6
|
||||
0.6
|
||||
0.6 1</specular>n <ambient>1.0 1.0 1.0</ambient>n <lighting>true</lighting>n <emissive>0
|
||||
0 0
|
||||
1</emissive>n <pbr>n <metal>n <albedo_map>
|
||||
/fork_d.png</albedo_map>
|
||||
n <normal_map>
|
||||
/fork_n.png</normal_map>
|
||||
n <ambient_occlusion_map>
|
||||
/fork_ao.png</ambient_occlusion_map>
|
||||
n <roughness_map>
|
||||
/fork_r.png</roughness_map>
|
||||
n </metal>n </pbr>n </material>n </visual>n </gazebo>n <joint name="main0_link_joint"
|
||||
type="revolute">n <limit
|
||||
effort="78" lower="-1.5708" upper="3.14159" velocity="0.52" />n <origin
|
||||
rpy="-0.00000 0.00000 0.00000" xyz="0.10000 0.00000 0.09400" />n <parent
|
||||
link="fork0_link" /> n <child link="main0_link" />n <axis xyz="0 1 0" />n </joint>n <link
|
||||
name="main0_link">n <collision name="main0_link_collision">n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.00000 0.00000 0.00000" />n <geometry>n <mesh
|
||||
filename="main_link.stl"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </collision> n <inertial>n <inertia
|
||||
ixx="0.00315699373090845" ixy="2.84713820858537E-05" ixz="-7.01601261191721E-05"
|
||||
iyy="0.00343729241263707" iyz="-0.000101485203138902" izz="0.00125534890134052" />n <origin
|
||||
rpy="0.00000 0.00000 0.00000"
|
||||
xyz="0.00186712264682627 -0.000412152188777604 0.0516389446895805" /> n <mass
|
||||
value="1.58688811563124" />n </inertial>n <visual name="main0_link_visual">n <origin
|
||||
rpy="0.00000 -0.00000 -0.00000" xyz="0.00000 0.00000 0.00000" />n <geometry> n <mesh
|
||||
filename="main_link.dae"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </visual>n </link>n <ros2_control
|
||||
name="main0_link_joint_hardware_interface" type="actuator">n <hardware>n <plugin>
|
||||
ign_ros2_control/IgnitionSystem</plugin>n </hardware> n <joint name="main0_link_joint">n <command_interface
|
||||
name="position">n <!-- <param name="min">-1</param> -->n <!-- <param name="max">1</param> -->n </command_interface>n <command_interface
|
||||
name="velocity">n <!-- <param name="min">-1</param> -->n <!-- <param name="max">1</param> -->n </command_interface>n <!-- WARN When this active a robot falls
|
||||
down -->n <!-- <command_interface
|
||||
name="effort"/> -->n <!-- <param name="p">${p}</param> -->n <!-- <param name="d">${d}</param> -->n <!-- <command_interface
|
||||
name="effort"/> -->n <state_interface
|
||||
name="position" />n <state_interface
|
||||
name="velocity" />n <state_interface name="effort" />n </joint>n </ros2_control>n <gazebo
|
||||
reference="main0_link">n <visual>n <material>n <diffuse>0.8 0.8 0.8 1</diffuse>n <specular>0.6
|
||||
0.6
|
||||
0.6 1</specular>n <ambient>1.0 1.0 1.0</ambient>n <lighting>true</lighting>n <emissive>0
|
||||
0 0
|
||||
1</emissive>n <pbr>n <metal>n <albedo_map>
|
||||
/main_link_d.png</albedo_map>
|
||||
n <normal_map>
|
||||
/main_link_n.png</normal_map>
|
||||
n <ambient_occlusion_map>
|
||||
/main_link_ao.png</ambient_occlusion_map>
|
||||
n <roughness_map>
|
||||
/main_link_r.png</roughness_map>
|
||||
n </metal>n </pbr>n </material>n </visual>n </gazebo>n <joint name="fork1_link_joint"
|
||||
type="revolute">n <limit
|
||||
effort="78" lower="-6.14159" upper="6.14159" velocity="0.52" />n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.00000 0.00000 0.13300" />n <parent
|
||||
link="main0_link" /> n <child link="fork1_link" />n <axis xyz="0 0 1" />n </joint>n <link
|
||||
name="fork1_link">n <collision name="fork1_link_collision">n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.00000 -0.00000 0.00000" />n <geometry>n <mesh
|
||||
filename="fork_link.stl"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </collision> n <inertial>n <inertia
|
||||
ixx="0.00367804533572758" ixy="1.04277925521833E-05" ixz="-0.00149971410403071"
|
||||
iyy="0.00415208849477534" iyz="-0.00122" izz="0.00329" />n <origin
|
||||
rpy="0.00000 0.00000 0.00000"
|
||||
xyz="0.0472051139085306 0.00208890925682996 0.0557265410642575" /> n <mass
|
||||
value="1.12472202892859" />n </inertial>n <visual name="fork1_link_visual">n <origin
|
||||
rpy="0.00000 -0.00000 -0.00000" xyz="0.00000 -0.00000 0.00000" />n <geometry> n <mesh
|
||||
filename="fork_link.dae"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </visual>n </link>n <ros2_control
|
||||
name="fork1_link_joint_hardware_interface" type="actuator">n <hardware>n <plugin>
|
||||
ign_ros2_control/IgnitionSystem</plugin>n </hardware> n <joint name="fork1_link_joint">n <command_interface
|
||||
name="position">n <!-- <param name="min">-1</param> -->n <!-- <param name="max">1</param> -->n </command_interface>n <command_interface
|
||||
name="velocity">n <!-- <param name="min">-1</param> -->n <!-- <param name="max">1</param> -->n </command_interface>n <!-- WARN When this active a robot falls
|
||||
down -->n <!-- <command_interface
|
||||
name="effort"/> -->n <!-- <param name="p">${p}</param> -->n <!-- <param name="d">${d}</param> -->n <!-- <command_interface
|
||||
name="effort"/> -->n <state_interface
|
||||
name="position" />n <state_interface
|
||||
name="velocity" />n <state_interface name="effort" />n </joint>n </ros2_control>n <gazebo
|
||||
reference="fork1_link">n <visual>n <material>n <diffuse>0.8 0.8 0.8 1</diffuse>n <specular>0.6
|
||||
0.6
|
||||
0.6 1</specular>n <ambient>1.0 1.0 1.0</ambient>n <lighting>true</lighting>n <emissive>0
|
||||
0 0
|
||||
1</emissive>n <pbr>n <metal>n <albedo_map>
|
||||
/fork_d.png</albedo_map>
|
||||
n <normal_map>
|
||||
/fork_n.png</normal_map>
|
||||
n <ambient_occlusion_map>
|
||||
/fork_ao.png</ambient_occlusion_map>
|
||||
n <roughness_map>
|
||||
/fork_r.png</roughness_map>
|
||||
n </metal>n </pbr>n </material>n </visual>n </gazebo>n <joint name="main1_link_joint"
|
||||
type="revolute">n <limit
|
||||
effort="78" lower="-1.5708" upper="3.14159" velocity="0.52" />n <origin
|
||||
rpy="-0.00000 0.00000 0.00000" xyz="0.10000 0.00000 0.09400" />n <parent
|
||||
link="fork1_link" /> n <child link="main1_link" />n <axis xyz="0 1 0" />n </joint>n <link
|
||||
name="main1_link">n <collision name="main1_link_collision">n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.00000 0.00000 0.00000" />n <geometry>n <mesh
|
||||
filename="main_link.stl"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </collision> n <inertial>n <inertia
|
||||
ixx="0.00315699373090845" ixy="2.84713820858537E-05" ixz="-7.01601261191721E-05"
|
||||
iyy="0.00343729241263707" iyz="-0.000101485203138902" izz="0.00125534890134052" />n <origin
|
||||
rpy="0.00000 0.00000 0.00000"
|
||||
xyz="0.00186712264682627 -0.000412152188777604 0.0516389446895805" /> n <mass
|
||||
value="1.58688811563124" />n </inertial>n <visual name="main1_link_visual">n <origin
|
||||
rpy="0.00000 -0.00000 -0.00000" xyz="0.00000 0.00000 0.00000" />n <geometry> n <mesh
|
||||
filename="main_link.dae"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </visual>n </link>n <ros2_control
|
||||
name="main1_link_joint_hardware_interface" type="actuator">n <hardware>n <plugin>
|
||||
ign_ros2_control/IgnitionSystem</plugin>n </hardware> n <joint name="main1_link_joint">n <command_interface
|
||||
name="position">n <!-- <param name="min">-1</param> -->n <!-- <param name="max">1</param> -->n </command_interface>n <command_interface
|
||||
name="velocity">n <!-- <param name="min">-1</param> -->n <!-- <param name="max">1</param> -->n </command_interface>n <!-- WARN When this active a robot falls
|
||||
down -->n <!-- <command_interface
|
||||
name="effort"/> -->n <!-- <param name="p">${p}</param> -->n <!-- <param name="d">${d}</param> -->n <!-- <command_interface
|
||||
name="effort"/> -->n <state_interface
|
||||
name="position" />n <state_interface
|
||||
name="velocity" />n <state_interface name="effort" />n </joint>n </ros2_control>n <gazebo
|
||||
reference="main1_link">n <visual>n <material>n <diffuse>0.8 0.8 0.8 1</diffuse>n <specular>0.6
|
||||
0.6
|
||||
0.6 1</specular>n <ambient>1.0 1.0 1.0</ambient>n <lighting>true</lighting>n <emissive>0
|
||||
0 0
|
||||
1</emissive>n <pbr>n <metal>n <albedo_map>
|
||||
/main_link_d.png</albedo_map>
|
||||
n <normal_map>
|
||||
/main_link_n.png</normal_map>
|
||||
n <ambient_occlusion_map>
|
||||
/main_link_ao.png</ambient_occlusion_map>
|
||||
n <roughness_map>
|
||||
/main_link_r.png</roughness_map>
|
||||
n </metal>n </pbr>n </material>n </visual>n </gazebo>n <joint name="fork2_link_joint"
|
||||
type="revolute">n <limit
|
||||
effort="78" lower="-6.14159" upper="6.14159" velocity="0.52" />n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.00000 0.00000 0.13300" />n <parent
|
||||
link="main1_link" /> n <child link="fork2_link" />n <axis xyz="0 0 1" />n </joint>n <link
|
||||
name="fork2_link">n <collision name="fork2_link_collision">n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.00000 -0.00000 0.00000" />n <geometry>n <mesh
|
||||
filename="fork_link.stl"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </collision> n <inertial>n <inertia
|
||||
ixx="0.00367804533572758" ixy="1.04277925521833E-05" ixz="-0.00149971410403071"
|
||||
iyy="0.00415208849477534" iyz="-0.00122" izz="0.00329" />n <origin
|
||||
rpy="0.00000 0.00000 0.00000"
|
||||
xyz="0.0472051139085306 0.00208890925682996 0.0557265410642575" /> n <mass
|
||||
value="1.12472202892859" />n </inertial>n <visual name="fork2_link_visual">n <origin
|
||||
rpy="0.00000 -0.00000 -0.00000" xyz="0.00000 -0.00000 0.00000" />n <geometry> n <mesh
|
||||
filename="fork_link.dae"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </visual>n </link>n <ros2_control
|
||||
name="fork2_link_joint_hardware_interface" type="actuator">n <hardware>n <plugin>
|
||||
ign_ros2_control/IgnitionSystem</plugin>n </hardware> n <joint name="fork2_link_joint">n <command_interface
|
||||
name="position">n <!-- <param name="min">-1</param> -->n <!-- <param name="max">1</param> -->n </command_interface>n <command_interface
|
||||
name="velocity">n <!-- <param name="min">-1</param> -->n <!-- <param name="max">1</param> -->n </command_interface>n <!-- WARN When this active a robot falls
|
||||
down -->n <!-- <command_interface
|
||||
name="effort"/> -->n <!-- <param name="p">${p}</param> -->n <!-- <param name="d">${d}</param> -->n <!-- <command_interface
|
||||
name="effort"/> -->n <state_interface
|
||||
name="position" />n <state_interface
|
||||
name="velocity" />n <state_interface name="effort" />n </joint>n </ros2_control>n <gazebo
|
||||
reference="fork2_link">n <visual>n <material>n <diffuse>0.8 0.8 0.8 1</diffuse>n <specular>0.6
|
||||
0.6
|
||||
0.6 1</specular>n <ambient>1.0 1.0 1.0</ambient>n <lighting>true</lighting>n <emissive>0
|
||||
0 0
|
||||
1</emissive>n <pbr>n <metal>n <albedo_map>
|
||||
/fork_d.png</albedo_map>
|
||||
n <normal_map>
|
||||
/fork_n.png</normal_map>
|
||||
n <ambient_occlusion_map>
|
||||
/fork_ao.png</ambient_occlusion_map>
|
||||
n <roughness_map>
|
||||
/fork_r.png</roughness_map>
|
||||
n </metal>n </pbr>n </material>n </visual>n </gazebo>n <joint name="ee_link_joint"
|
||||
type="revolute">n <limit
|
||||
effort="78" lower="-1.5708" upper="3.14159" velocity="0.52" />n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.10000 0.00000 0.09473" />n <parent
|
||||
link="fork2_link" /> n <child link="ee_link" />n <axis xyz="0 1 0" />n </joint>n <joint
|
||||
name="tool0_joint" type="fixed">n <origin rpy="0.00000 0.00000 0.00000"
|
||||
xyz="0.00000 0.00000 0.11000" />n <parent link="ee_link" />n <child link="tool0" />n </joint>
|
||||
n <link name="tool0" />n <link
|
||||
name="ee_link">n <collision name="ee_link_collision">n <origin
|
||||
rpy="-0.00000 0.00000 -0.00000" xyz="0.00000 -0.00000 0.00000" />n <geometry>n <mesh
|
||||
filename="ee_link.stl"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry>n </collision>n <inertial>n <inertia
|
||||
ixx="0.00147695259043549" ixy="-2.66894744420299E-05"
|
||||
ixz="-4.40871314563273E-05" iyy="0.00135500487881796" iyz="-3.19001462979333E-05"
|
||||
izz="0.00087582892706912" />n <origin rpy="0.00000 0.00000 0.00000"
|
||||
xyz="-9.7531539777207E-06 -0.000888494418875867 0.0342332199538358" />n <mass
|
||||
value="1.88031044620482" />n </inertial> n <visual name="ee_link_visual">n <origin
|
||||
rpy="0.00000 0.00000 0.00000" xyz="0.00000 -0.00000 0.00000" />n <geometry>n <mesh
|
||||
filename="ee_link.dae"
|
||||
scale="1.00000 1.00000 1.00000" />n </geometry> n </visual>n </link>n <ros2_control
|
||||
name="ee_link_joint_hardware_interface" type="actuator">n <hardware>n <plugin>
|
||||
ign_ros2_control/IgnitionSystem</plugin>n </hardware>n <joint name="ee_link_joint">n <command_interface
|
||||
name="position">n <!-- <param name="min">-1</param> -->n <!-- <param name="max">1</param> -->n </command_interface>n <command_interface name="velocity">n <!--
|
||||
<param
|
||||
name="min">-1</param> -->n <!--
|
||||
<param
|
||||
name="max">1</param> -->n </command_interface>
|
||||
n <!-- WARN When this active a robot falls down -->n <!-- <command_interface name="effort"/> -->n <!-- <param name="p">${p}</param> -->n <!-- <param name="d">${d}</param> -->n <!-- <command_interface name="effort"/> -->n <state_interface name="position" />n <state_interface name="velocity" />n <state_interface
|
||||
name="effort" />n </joint>n </ros2_control>n <gazebo reference="ee_link">n <visual>n <material>
|
||||
n <diffuse>0.8 0.8 0.8 1</diffuse>n <specular>0.6 0.6 0.6 1</specular>n <ambient>1.0
|
||||
1.0 1.0</ambient>n <lighting>true</lighting>n <emissive>0 0 0 1</emissive>n <pbr>
|
||||
n <metal>n <albedo_map>
|
||||
/ee_link_d.png</albedo_map>
|
||||
n <normal_map>
|
||||
/ee_link_n.png</normal_map>
|
||||
n <ambient_occlusion_map>
|
||||
/ee_link_ao.png</ambient_occlusion_map>
|
||||
n <roughness_map>
|
||||
/ee_link_r.png</roughness_map>
|
||||
n </metal>n </pbr>n </material>n </visual>n </gazebo>n <!-- END robot description -->n <ros2_control name="rbs_gripper_gazebo"
|
||||
type="system">n <!-- Plugins -->n <hardware>n <plugin>ign_ros2_control/IgnitionSystem</plugin>n </hardware>n <!--
|
||||
Joint interfaces -->
|
||||
n <joint name="rbs_gripper_rot_base_joint">n <state_interface name="position">n <param
|
||||
name="initial_value">0.000</param>n </state_interface> n <command_interface
|
||||
name="position" />n <command_interface name="velocity" />n <command_interface
|
||||
name="effort" />n <state_interface name="velocity" />n <state_interface
|
||||
name="effort" />n </joint>n <joint
|
||||
name="rbs_gripper_r_finger_joint">n <state_interface name="position">n <param
|
||||
name="initial_value">0.000</param>n </state_interface> n <command_interface
|
||||
name="position" />n <command_interface name="velocity" />n <command_interface
|
||||
name="effort" />n <state_interface name="velocity" />n <state_interface
|
||||
name="effort" />n </joint>n <joint
|
||||
name="rbs_gripper_l_finger_joint">n <param name="mimic">rbs_gripper_r_finger_joint</param>
|
||||
n <param name="multiplier">1</param> n </joint>n </ros2_control>n <joint
|
||||
name="rbs_gripper_gripper_base_joint" type="fixed">n <origin rpy="0 0 0" xyz="0 0 0" />n <parent
|
||||
link="tool0" />n <child link="rbs_gripper_gripper_base_link" />n </joint>n <link
|
||||
name="rbs_gripper_gripper_base_link">n <inertial>n <origin rpy="0 0 0"
|
||||
xyz="0.000364704367134063 0.0336387482840125 0.0593891203954369" />n <mass
|
||||
value="1.13983632906086" />n <inertia ixx="0.00107738806534129"
|
||||
ixy="-1.09841172461737E-05" ixz="2.62750043451545E-06" iyy="0.000717388573992299"
|
||||
iyz="-2.95426438182787E-05" izz="0.00115777179755934" /> n </inertial>n <visual>n <origin
|
||||
rpy="0 0 0" xyz="0 0 0" />n <geometry>n <mesh
|
||||
filename="base.dae" /> n </geometry> n <material name="rbs_gripper_material">n <color
|
||||
rgba="0.752941176470588 0.752941176470588 0.752941176470588 1" />n </material>n </visual>
|
||||
n <collision>n <origin
|
||||
rpy="0 0 0" xyz="0 0 0" />n <geometry>n <mesh
|
||||
filename="base.stl" /> n </geometry>n </collision>n </link> n <link
|
||||
name="rbs_gripper_rot_base_link">n <inertial>n <origin
|
||||
rpy="0 0 0" xyz="6.79110135283868E-11 -3.80956832067611E-10 0.00775394473595793" />n <mass
|
||||
value="0.161003401535982" />n <inertia ixx="0.00011089089949771"
|
||||
ixy="5.01335040610636E-06" ixz="1.74608448389267E-14" iyy="0.000105515893695012"
|
||||
iyz="-2.03282362854432E-14" izz="0.000206912001661452" />n </inertial>n <visual>n <origin
|
||||
rpy="0 0 0"
|
||||
xyz="0 0 0" />n <geometry>n <mesh
|
||||
filename="rotor.dae" /> n </geometry>n <material name="rbs_gripper_material">n <color
|
||||
rgba="0.250980392156863 0.250980392156863 0.250980392156863 1" />n </material>n </visual>
|
||||
n <collision>n <origin rpy="0 0 0" xyz="0 0 0" />n <geometry> n <mesh
|
||||
filename="rotor.stl" /> n </geometry>n </collision>n </link>n <joint
|
||||
name="rbs_gripper_rot_base_joint" type="revolute"> n <origin
|
||||
rpy="0 0 0" xyz="0 0 0.10861" />n <parent link="rbs_gripper_gripper_base_link" />n <child
|
||||
link="rbs_gripper_rot_base_link" />n <axis xyz="0 0 1" />n <limit
|
||||
effort="78" lower="-3.14159" upper="3.14159" velocity="0.52" />n </joint>n <link
|
||||
name="rbs_gripper_l_finger_link">n <inertial>n <origin
|
||||
rpy="0 0 0" xyz="0.00399878118534129 0.0187296413885176 -0.0777776233934166" />n <mass
|
||||
value="0.0601996441483964" />n <inertia ixx="4.18533281165612E-05"
|
||||
ixy="-7.11657995951147E-06" ixz="1.81029223490065E-05" iyy="7.89886367868258E-05"
|
||||
iyz="1.20542845942065E-05"
|
||||
izz="5.16740841307935E-05" />n </inertial>n <visual>n <origin rpy="0 0 0"
|
||||
xyz="0 0 0" />n <geometry>n <mesh
|
||||
filename="finger.dae" /> n </geometry>n <material name="rbs_gripper_material">n <color
|
||||
rgba="0.752941176470588 0 0 1" />n </material> n </visual>n <collision>n <origin
|
||||
rpy="0 0 0" xyz="0 0 0" />n <geometry>n <mesh
|
||||
filename="finger.stl" /> n </geometry> n </collision>n </link>n <joint
|
||||
name="rbs_gripper_l_finger_joint" type="prismatic"> n <origin rpy="0 0 1.5708"
|
||||
xyz="0 0 0.1071" />n <parent
|
||||
link="rbs_gripper_rot_base_link" />n <child link="rbs_gripper_l_finger_link" />n <axis
|
||||
xyz="-1 0 0" />n <limit effort="10" lower="0" upper="0.064"
|
||||
velocity="0.53" />n <mimic joint="rbs_gripper_r_finger_joint" multiplier="1" />n </joint>
|
||||
n <link name="rbs_gripper_r_finger_link">n <inertial> n <origin rpy="0 0 0"
|
||||
xyz="0.0039988 -0.077778 -0.01873" />n <mass value="0.0602" />n <inertia
|
||||
ixx="4.1853E-05" ixy="1.8103E-05" ixz="7.1166E-06" iyy="5.1674E-05"
|
||||
iyz="-1.2054E-05" izz="7.8989E-05" />n </inertial>n <visual>n <origin rpy="0 0 0"
|
||||
xyz="0 0 0" />n <geometry>n <mesh
|
||||
filename="finger.dae" /> n </geometry>n <material name="rbs_gripper_material">n <color
|
||||
rgba="0.75294 0 0 1" />n </material> n </visual>n <collision>n <origin
|
||||
rpy="0 0 0" xyz="0 0 0" />n <geometry>n <mesh
|
||||
filename="finger.stl" /> n </geometry> n </collision>n </link>n <joint
|
||||
name="rbs_gripper_r_finger_joint" type="prismatic"> n <origin rpy="0 0 -1.5708"
|
||||
xyz="0 0 0.1071" />n <parent
|
||||
link="rbs_gripper_rot_base_link" />n <child link="rbs_gripper_r_finger_link" />n <axis
|
||||
xyz="-1 0 0" />n <limit effort="10" lower="0" upper="0.064"
|
||||
velocity="0.53" />n </joint>n <link name="gripper_grasp_point" />n <joint
|
||||
name="rbs_gripper_gripper_tool0_joint" type="fixed">n <origin rpy="0 0 0"
|
||||
xyz="0 0 0.09139" />n <parent link="rbs_gripper_rot_base_link" />n <child
|
||||
link="gripper_grasp_point" />n </joint>n <ros2_control name="fts_sensor"
|
||||
type="sensor">n <hardware>n <plugin>ign_ros2_control/IgnitionFts</plugin>n </hardware>n <sensor
|
||||
name="fts_sensor">n <state_interface name="force.x" />n <state_interface name="force.y" />
|
||||
n <state_interface
|
||||
name="force.z" />n <state_interface name="torque.x" />n <state_interface
|
||||
name="torque.y" />n <state_interface
|
||||
name="torque.z" />n </sensor>n </ros2_control>n <gazebo reference="tool0_joint">n <preserveFixedJoint>
|
||||
true</preserveFixedJoint>n <sensor name="fts_sensor" type="force_torque">n <always_on>true</always_on>
|
||||
n <update_rate>
|
||||
50</update_rate>n <visualize>true</visualize>n <topic>ft_data</topic>n <force_torque>
|
||||
n <frame>
|
||||
sensor</frame>n <measure_direction>child_to_parent</measure_direction>n </force_torque>
|
||||
n </sensor> n </gazebo>n <gazebo>n <plugin filename="libign_ros2_control-system.so"
|
||||
name="ign_ros2_control::IgnitionROS2ControlPlugin">n <parameters>
|
||||
/home/idontsudo/robossembler_ws/install/rbs_arm/share/rbs_arm/config/rbs_arm0_controllers.yaml</parameters>
|
||||
n <ros>n <namespace></namespace>n </ros>n </plugin>n </gazebo>n</robot>
|
1
web_p/robot_builder/rotor.dae
Symbolic link
1
web_p/robot_builder/rotor.dae
Symbolic link
|
@ -0,0 +1 @@
|
|||
/home/idontsudo/robossembler_ws/src/rbs_gripper/meshes/visual/rotor.dae
|
1
web_p/robot_builder/start_link.dae
Symbolic link
1
web_p/robot_builder/start_link.dae
Symbolic link
|
@ -0,0 +1 @@
|
|||
/home/idontsudo/robossembler_ws/src/rbs_arm/meshes/visual/start_link.dae
|
|
@ -1,20 +1,531 @@
|
|||
"""
|
||||
train_Dope
|
||||
train_Dope
|
||||
Общая задача: оценка позиции объекта (Pose estimation)
|
||||
Реализуемая функция: обучение нейросетевой модели DOPE по заданному BOP-датасету
|
||||
|
||||
python3 $PYTHON_EDUCATION --path /Users/idontsudo/webservice/server/build/public/7065d6b6-c8a3-48c5-9679-bb8f3a690296 \
|
||||
python3 $PYTHON_EDUCATION --path /Users/user/webservice/server/build/public/7065d6b6-c8a3-48c5-9679-bb8f3a690296 \
|
||||
--name test1234 --datasetName 32123213
|
||||
|
||||
25.04.2024 @shalenikol release 0.1
|
||||
08.05.2024 @shalenikol release 0.1
|
||||
"""
|
||||
import os
|
||||
import json
|
||||
import shutil
|
||||
import numpy as np
|
||||
import transforms3d as t3d
|
||||
|
||||
def train_Dope_i(path:str, wname:str, dname:str, outpath:str, epochs:int):
|
||||
results = f"torchrun --nproc_per_node=1 train.py --local_rank 0 --data {os.path.join(path,dname)} --object fork" \
|
||||
+ f" -e {epochs} --batchsize 16 --exts jpg --imagesize 640 --pretrained" \
|
||||
+ " --net_path /home/shalenikol/fork_work/dope_training/output/weights_2996/net_epoch_47.pth"
|
||||
print(results)
|
||||
FILE_RBS_INFO = "rbs_info.json"
|
||||
FILE_CAMERA = "camera.json"
|
||||
FILE_GT = "scene_gt.json"
|
||||
FILE_GT_COCO = "scene_gt_coco.json"
|
||||
FILE_GT_INFO = "scene_gt_info.json"
|
||||
|
||||
FILE_MODEL = "epoch"
|
||||
EXT_MODEL = ".pth"
|
||||
EXT_RGB = "jpg"
|
||||
DIR_ROOT_DS = "dataset_dope"
|
||||
DIR_TRAIN_OUT = "out_weights"
|
||||
|
||||
MODEL_SCALE = 1000 # исходная модель в метрах, преобразуем в мм (для DOPE)
|
||||
|
||||
# Own_Numbering_Files = True # наименование image-файлов: собственная нумерация
|
||||
nn_image = 0
|
||||
K_intrinsic = []
|
||||
model_info = []
|
||||
camera_data = {}
|
||||
im_width = 0
|
||||
|
||||
nb_update_network = 0
|
||||
# [
|
||||
# [min(x), min(y), min(z)],
|
||||
# [min(x), max(y), min(z)],
|
||||
# [min(x), max(y), max(z)],
|
||||
# [min(x), min(y), max(z)],
|
||||
# [max(x), min(y), max(z)],
|
||||
# [max(x), max(y), min(z)],
|
||||
# [max(x), max(y), max(z)],
|
||||
# [max(x), min(y), max(z)],
|
||||
# [xc, yc, zc] # min + (max - min) / 2
|
||||
# ]
|
||||
|
||||
def trans_3Dto2D_point_in_camera(xyz, K_m, R_m2c, t_m2c):
|
||||
"""
|
||||
xyz : 3D-координаты точки
|
||||
K_m : внутренняя матрица камеры 3х3
|
||||
R_m2c : матрица поворота 3х3
|
||||
t_m2c : вектор перемещения 3х1
|
||||
return [u,v]
|
||||
"""
|
||||
K = np.array(K_m)
|
||||
r = np.array(R_m2c)
|
||||
r.shape = (3, 3)
|
||||
t = np.array(t_m2c)
|
||||
t.shape = (3, 1)
|
||||
T = np.concatenate((r, t), axis=1)
|
||||
|
||||
P_m = np.array(xyz)
|
||||
P_m.resize(4)
|
||||
P_m[-1] = 1.0
|
||||
P_m.shape = (4, 1)
|
||||
|
||||
# Project (X, Y, Z, 1) into cameras coordinate system
|
||||
P_c = T @ P_m # 4x1
|
||||
# Apply camera intrinsics to map (Xc, Yc, Zc) to p=(x, y, z)
|
||||
p = K @ P_c
|
||||
# Normalize by z to get (u,v,1)
|
||||
uv = (p / p[2][0])[:-1]
|
||||
return uv.flatten().tolist()
|
||||
|
||||
def gt_parse(path: str, out_dir: str):
|
||||
global nn_image
|
||||
with open(os.path.join(path, FILE_GT_COCO), "r") as fh:
|
||||
coco_data = json.load(fh)
|
||||
with open(os.path.join(path, FILE_GT), "r") as fh:
|
||||
gt_data = json.load(fh)
|
||||
with open(os.path.join(path, FILE_GT_INFO), "r") as fh:
|
||||
gt_info = json.load(fh)
|
||||
|
||||
for img in coco_data["images"]:
|
||||
rgb_file = os.path.join(path, img["file_name"])
|
||||
if os.path.isfile(rgb_file):
|
||||
# if Own_Numbering_Files:
|
||||
ext = os.path.splitext(rgb_file)[1] # only ext
|
||||
f = f"{nn_image:06}"
|
||||
out_img = os.path.join(out_dir, f + ext)
|
||||
# else:
|
||||
# f = os.path.split(rgb_file)[1] # filename with extension
|
||||
# f = os.path.splitext(f)[0] # only filename
|
||||
# out_img = out_dir
|
||||
shutil.copy2(rgb_file, out_img)
|
||||
out_file = os.path.join(out_dir,f+".json")
|
||||
nn_image += 1
|
||||
|
||||
# full annotation of the one image
|
||||
all_data = camera_data.copy()
|
||||
cat_names = {obj["id"]: obj["name"] for obj in coco_data["categories"]}
|
||||
id_img = img["id"] # 0, 1, 2 ...
|
||||
sid_img = str(id_img) # "0", "1", "2" ...
|
||||
img_info = gt_info[sid_img]
|
||||
img_gt = gt_data[sid_img]
|
||||
img_idx = 0 # object index on the image
|
||||
objs = []
|
||||
for ann in coco_data["annotations"]:
|
||||
if ann["image_id"] == id_img:
|
||||
item = ann["category_id"]
|
||||
obj_data = {}
|
||||
obj_data["class"] = cat_names[item]
|
||||
x, y, width, height = ann["bbox"]
|
||||
obj_data["bounding_box"] = {"top_left":[x,y], "bottom_right":[x+width,y+height]}
|
||||
|
||||
# visibility from FILE_GT_INFO
|
||||
item_info = img_info[img_idx]
|
||||
obj_data["visibility"] = item_info["visib_fract"]
|
||||
|
||||
# location from FILE_GT
|
||||
item_gt = img_gt[img_idx]
|
||||
obj_id = item_gt["obj_id"] - 1 # index with 0
|
||||
cam_R_m2c = item_gt["cam_R_m2c"]
|
||||
cam_t_m2c = item_gt["cam_t_m2c"]
|
||||
obj_data["location"] = cam_t_m2c
|
||||
q = t3d.quaternions.mat2quat(np.array(cam_R_m2c))
|
||||
obj_data["quaternion_xyzw"] = [q[1], q[2], q[3], q[0]]
|
||||
|
||||
cuboid_xyz = model_info[obj_id]
|
||||
obj_data["projected_cuboid"] = [
|
||||
trans_3Dto2D_point_in_camera(cub, K_intrinsic, cam_R_m2c, cam_t_m2c)
|
||||
for cub in cuboid_xyz
|
||||
]
|
||||
|
||||
objs.append(obj_data)
|
||||
img_idx += 1
|
||||
|
||||
all_data["objects"] = objs
|
||||
with open(out_file, "w") as fh:
|
||||
json.dump(all_data, fh, indent=2)
|
||||
|
||||
def explore(path: str, res_dir: str):
|
||||
if not os.path.isdir(path):
|
||||
return
|
||||
folders = [
|
||||
os.path.join(path, o)
|
||||
for o in os.listdir(path)
|
||||
if os.path.isdir(os.path.join(path, o))
|
||||
]
|
||||
for path_entry in folders:
|
||||
if os.path.isfile(os.path.join(path_entry,FILE_GT_COCO)) and \
|
||||
os.path.isfile(os.path.join(path_entry,FILE_GT_INFO)) and \
|
||||
os.path.isfile(os.path.join(path_entry,FILE_GT)):
|
||||
gt_parse(path_entry, res_dir)
|
||||
else:
|
||||
explore(path_entry, res_dir)
|
||||
|
||||
def BOP2DOPE_dataset(dpath: str, out_dir: str) -> str:
|
||||
""" Convert BOP-dataset to YOLO format for train """
|
||||
res_dir = os.path.join(out_dir, DIR_ROOT_DS)
|
||||
if os.path.isdir(res_dir):
|
||||
shutil.rmtree(res_dir)
|
||||
os.mkdir(res_dir)
|
||||
|
||||
explore(dpath, res_dir)
|
||||
|
||||
return out_dir
|
||||
|
||||
def train(dopepath:str, wname:str, epochs:int, pretrain: bool, lname: list):
|
||||
import random
|
||||
# try:
|
||||
import configparser as configparser
|
||||
# except ImportError:
|
||||
# import ConfigParser as configparser
|
||||
import torch
|
||||
# import torch.nn.parallel
|
||||
import torch.optim as optim
|
||||
import torch.utils.data
|
||||
import torchvision.transforms as transforms
|
||||
from torch.autograd import Variable
|
||||
import datetime
|
||||
from tensorboardX import SummaryWriter
|
||||
|
||||
from models_dope import DopeNetwork
|
||||
from utils_dope import CleanVisiiDopeLoader #, VisualizeBeliefMap, save_image
|
||||
|
||||
import warnings
|
||||
warnings.filterwarnings("ignore")
|
||||
|
||||
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1,2,3,4,5,6,7"
|
||||
|
||||
torch.autograd.set_detect_anomaly(False)
|
||||
torch.autograd.profiler.profile(False)
|
||||
torch.autograd.gradcheck = False
|
||||
torch.backends.cudnn.benchmark = True
|
||||
|
||||
start_time = datetime.datetime.now()
|
||||
print("start:", start_time.strftime("%m/%d/%Y, %H:%M:%S"))
|
||||
|
||||
res_model = os.path.join(dopepath, wname + EXT_MODEL)
|
||||
|
||||
local_rank = 0
|
||||
opt = lambda: None
|
||||
opt.use_s3 = False
|
||||
opt.train_buckets = []
|
||||
opt.endpoint = None
|
||||
opt.lr=0.0001
|
||||
opt.loginterval=100
|
||||
opt.sigma=0.5 # 4
|
||||
opt.nbupdates=None
|
||||
# opt.save=False
|
||||
# opt.option="default"
|
||||
# opt.gpuids=[0]
|
||||
|
||||
opt.namefile=FILE_MODEL
|
||||
opt.workers=8
|
||||
opt.batchsize=16
|
||||
|
||||
opt.data = [os.path.join(dopepath, DIR_ROOT_DS)]
|
||||
opt.outf = os.path.join(dopepath, DIR_TRAIN_OUT)
|
||||
opt.object = lname #["fork"]
|
||||
opt.exts = [EXT_RGB]
|
||||
# opt.imagesize = im_width
|
||||
opt.epochs = epochs
|
||||
opt.pretrained = pretrain
|
||||
opt.net_path = res_model if pretrain else None
|
||||
opt.manualseed = random.randint(1, 10000)
|
||||
|
||||
# # Validate Arguments
|
||||
# if opt.use_s3 and (opt.train_buckets is None or opt.endpoint is None):
|
||||
# raise ValueError(
|
||||
# "--train_buckets and --endpoint must be specified if training with data from s3 bucket."
|
||||
# )
|
||||
# if not opt.use_s3 and opt.data is None:
|
||||
# raise ValueError("--data field must be specified.")
|
||||
|
||||
os.makedirs(opt.outf, exist_ok=True)
|
||||
|
||||
# if local_rank == 0:
|
||||
# writer = SummaryWriter(opt.outf + "/runs/")
|
||||
random.seed(opt.manualseed)
|
||||
torch.cuda.set_device(local_rank)
|
||||
# torch.distributed.init_process_group(backend="nccl", init_method="env://")
|
||||
torch.manual_seed(opt.manualseed)
|
||||
torch.cuda.manual_seed_all(opt.manualseed)
|
||||
|
||||
# # Data Augmentation
|
||||
# if not opt.save:
|
||||
# contrast = 0.2
|
||||
# brightness = 0.2
|
||||
# noise = 0.1
|
||||
# normal_imgs = [0.59, 0.25]
|
||||
# transform = transforms.Compose(
|
||||
# [
|
||||
# AddRandomContrast(0.2),
|
||||
# AddRandomBrightness(0.2),
|
||||
# transforms.Resize(opt.imagesize),
|
||||
# ]
|
||||
# )
|
||||
# else:
|
||||
# contrast = 0.00001
|
||||
# brightness = 0.00001
|
||||
# noise = 0.00001
|
||||
# normal_imgs = None
|
||||
# transform = transforms.Compose(
|
||||
# [transforms.Resize(opt.imagesize), transforms.ToTensor()]
|
||||
# )
|
||||
|
||||
# Load Model
|
||||
net = DopeNetwork()
|
||||
output_size = 50
|
||||
# opt.sigma = 0.5
|
||||
|
||||
train_dataset = CleanVisiiDopeLoader(
|
||||
opt.data,
|
||||
sigma=opt.sigma,
|
||||
output_size=output_size,
|
||||
extensions=opt.exts,
|
||||
objects=opt.object,
|
||||
use_s3=opt.use_s3,
|
||||
buckets=opt.train_buckets,
|
||||
endpoint_url=opt.endpoint,
|
||||
)
|
||||
trainingdata = torch.utils.data.DataLoader(
|
||||
train_dataset,
|
||||
batch_size=opt.batchsize,
|
||||
shuffle=True,
|
||||
num_workers=opt.workers,
|
||||
pin_memory=True,
|
||||
)
|
||||
if not trainingdata is None:
|
||||
print(f"training data: {len(trainingdata)} batches")
|
||||
|
||||
print("Loading Model...")
|
||||
net = net.cuda()
|
||||
# net = torch.nn.parallel.DistributedDataParallel(
|
||||
# net.cuda(), device_ids=[local_rank], output_device=local_rank
|
||||
# )
|
||||
if opt.pretrained:
|
||||
if opt.net_path is not None:
|
||||
net.load_state_dict(torch.load(opt.net_path))
|
||||
else:
|
||||
print("Error: Did not specify path to pretrained weights.")
|
||||
quit()
|
||||
|
||||
parameters = filter(lambda p: p.requires_grad, net.parameters())
|
||||
optimizer = optim.Adam(parameters, lr=opt.lr)
|
||||
|
||||
print("ready to train!")
|
||||
|
||||
global nb_update_network
|
||||
nb_update_network = 0
|
||||
# best_results = {"epoch": None, "passed": None, "add_mean": None, "add_std": None}
|
||||
|
||||
scaler = torch.cuda.amp.GradScaler()
|
||||
|
||||
def _runnetwork(epoch, train_loader): #, syn=False
|
||||
global nb_update_network
|
||||
# net
|
||||
net.train()
|
||||
|
||||
loss_avg_to_log = {}
|
||||
loss_avg_to_log["loss"] = []
|
||||
loss_avg_to_log["loss_affinities"] = []
|
||||
loss_avg_to_log["loss_belief"] = []
|
||||
loss_avg_to_log["loss_class"] = []
|
||||
for batch_idx, targets in enumerate(train_loader):
|
||||
optimizer.zero_grad()
|
||||
|
||||
data = Variable(targets["img"].cuda())
|
||||
target_belief = Variable(targets["beliefs"].cuda())
|
||||
target_affinities = Variable(targets["affinities"].cuda())
|
||||
|
||||
output_belief, output_aff = net(data)
|
||||
|
||||
loss = None
|
||||
|
||||
loss_belief = torch.tensor(0).float().cuda()
|
||||
loss_affinities = torch.tensor(0).float().cuda()
|
||||
loss_class = torch.tensor(0).float().cuda()
|
||||
|
||||
for stage in range(len(output_aff)): # output, each belief map layers.
|
||||
loss_affinities += (
|
||||
(output_aff[stage] - target_affinities)
|
||||
* (output_aff[stage] - target_affinities)
|
||||
).mean()
|
||||
|
||||
loss_belief += (
|
||||
(output_belief[stage] - target_belief)
|
||||
* (output_belief[stage] - target_belief)
|
||||
).mean()
|
||||
|
||||
loss = loss_affinities + loss_belief
|
||||
|
||||
# if batch_idx == 0:
|
||||
# post = "train"
|
||||
# if local_rank == 0:
|
||||
# for i_output in range(1):
|
||||
# # input images
|
||||
# writer.add_image(
|
||||
# f"{post}_input_{i_output}",
|
||||
# targets["img_original"][i_output],
|
||||
# epoch,
|
||||
# dataformats="CWH",
|
||||
# )
|
||||
# # belief maps gt
|
||||
# imgs = VisualizeBeliefMap(target_belief[i_output])
|
||||
# img, grid = save_image(
|
||||
# imgs, "some_img.png", mean=0, std=1, nrow=3, save=False
|
||||
# )
|
||||
# writer.add_image(
|
||||
# f"{post}_belief_ground_truth_{i_output}",
|
||||
# grid,
|
||||
# epoch,
|
||||
# dataformats="CWH",
|
||||
# )
|
||||
# # belief maps guess
|
||||
# imgs = VisualizeBeliefMap(output_belief[-1][i_output])
|
||||
# img, grid = save_image(
|
||||
# imgs, "some_img.png", mean=0, std=1, nrow=3, save=False
|
||||
# )
|
||||
# writer.add_image(
|
||||
# f"{post}_belief_guess_{i_output}",
|
||||
# grid,
|
||||
# epoch,
|
||||
# dataformats="CWH",
|
||||
# )
|
||||
|
||||
loss.backward()
|
||||
|
||||
optimizer.step()
|
||||
|
||||
nb_update_network += 1
|
||||
|
||||
# log the loss
|
||||
loss_avg_to_log["loss"].append(loss.item())
|
||||
loss_avg_to_log["loss_class"].append(loss_class.item())
|
||||
loss_avg_to_log["loss_affinities"].append(loss_affinities.item())
|
||||
loss_avg_to_log["loss_belief"].append(loss_belief.item())
|
||||
|
||||
if batch_idx % opt.loginterval == 0:
|
||||
print(
|
||||
"Train Epoch: {} [{}/{} ({:.0f}%)] \tLoss: {:.15f} \tLocal Rank: {}".format(
|
||||
epoch,
|
||||
batch_idx * len(data),
|
||||
len(train_loader.dataset),
|
||||
100.0 * batch_idx / len(train_loader),
|
||||
loss.item(),
|
||||
local_rank,
|
||||
)
|
||||
)
|
||||
# # log the loss values
|
||||
# if local_rank == 0:
|
||||
# writer.add_scalar("loss/train_loss", np.mean(loss_avg_to_log["loss"]), epoch)
|
||||
# writer.add_scalar("loss/train_cls", np.mean(loss_avg_to_log["loss_class"]), epoch)
|
||||
# writer.add_scalar("loss/train_aff", np.mean(loss_avg_to_log["loss_affinities"]), epoch)
|
||||
# writer.add_scalar("loss/train_bel", np.mean(loss_avg_to_log["loss_belief"]), epoch)
|
||||
|
||||
for epoch in range(1, opt.epochs + 1):
|
||||
|
||||
_runnetwork(epoch, trainingdata)
|
||||
|
||||
try:
|
||||
if local_rank == 0:
|
||||
torch.save(
|
||||
net.state_dict(),
|
||||
f"{opt.outf}/{opt.namefile}_{str(epoch).zfill(3)}.pth",
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Encountered Exception: {e}")
|
||||
|
||||
if not opt.nbupdates is None and nb_update_network > int(opt.nbupdates):
|
||||
break
|
||||
|
||||
# if local_rank == 0:
|
||||
# save result model
|
||||
torch.save(net.state_dict(), res_model) #os.path.join(dopepath, wname + EXT_MODEL))
|
||||
# else:
|
||||
# torch.save(
|
||||
# net.state_dict(),
|
||||
# f"{opt.outf}/{opt.namefile}_{str(epoch).zfill(3)}_rank_{local_rank}.pth",
|
||||
# )
|
||||
|
||||
print("end:", datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S"))
|
||||
print("Total time taken: ", str(datetime.datetime.now() - start_time).split(".")[0])
|
||||
|
||||
def train_Dope_i(path:str, wname:str, dname:str, outpath:str, epochs:int, pretrain: bool):
|
||||
""" Main procedure for train DOPE model """
|
||||
global K_intrinsic, model_info, camera_data, im_width
|
||||
|
||||
if not os.path.isdir(outpath):
|
||||
print(f"Invalid output path '{outpath}'")
|
||||
exit(-1)
|
||||
out_dir = os.path.join(outpath, wname)
|
||||
ds_path = os.path.join(path, dname)
|
||||
|
||||
if not os.path.isdir(ds_path):
|
||||
print(f"{ds_path} : no BOP directory")
|
||||
return ""
|
||||
|
||||
camera_json = os.path.join(ds_path, FILE_CAMERA)
|
||||
if not os.path.isfile(camera_json):
|
||||
print(f"{camera_json} : no intrinsic camera file")
|
||||
return ""
|
||||
|
||||
rbs_info = os.path.join(ds_path, FILE_RBS_INFO)
|
||||
if not os.path.isfile(rbs_info):
|
||||
print(f"{rbs_info} : no dataset info file")
|
||||
return ""
|
||||
|
||||
camera_data = {}
|
||||
with open(camera_json, "r") as fh:
|
||||
data = json.load(fh)
|
||||
keys = ["cx","cy","fx","fy"]
|
||||
intrinsic = {k: data[k] for k in keys}
|
||||
im_height = data["height"]
|
||||
im_width = data["width"]
|
||||
camera_data["camera_data"] = dict(intrinsic=intrinsic, height=im_height, width=im_width)
|
||||
K_intrinsic = [
|
||||
[data["fx"], 0.0, data["cx"]],
|
||||
[0.0, data["fy"], data["cy"]],
|
||||
[0.0, 0.0, 1.0]
|
||||
]
|
||||
# calc cuboid + center
|
||||
with open(rbs_info, "r") as fh:
|
||||
info = json.load(fh)
|
||||
# список имён объектов
|
||||
list_name = list(map(lambda x: x["name"], info))
|
||||
# in FILE_RBS_INFO model numbering from smallest to largest
|
||||
model_info = []
|
||||
for m_info in info:
|
||||
cub = np.array(m_info["cuboid"]) * MODEL_SCALE
|
||||
xyz_min = cub.min(axis=0)
|
||||
xyz_max = cub.max(axis=0)
|
||||
# [xc, yc, zc] # min + (max - min) / 2
|
||||
center = []
|
||||
for i in range(3):
|
||||
center.append(xyz_min[i] + (xyz_max[i]- xyz_min[i]) / 2)
|
||||
c = np.array(center, ndmin=2)
|
||||
model_info.append(np.append(cub, c, axis=0))
|
||||
|
||||
if pretrain:
|
||||
# продолжить обучение
|
||||
if not os.path.isdir(out_dir):
|
||||
print(f"No dir '{out_dir}'")
|
||||
exit(-2)
|
||||
dpath = out_dir
|
||||
# model_path = os.path.join(dpath, wname + ".pt")
|
||||
else:
|
||||
# обучение сначала
|
||||
if not os.path.isdir(out_dir):
|
||||
os.mkdir(out_dir)
|
||||
|
||||
dpath = BOP2DOPE_dataset(ds_path, out_dir)
|
||||
if len(dpath) == 0:
|
||||
print(f"Error in convert dataset '{ds_path}' to '{outpath}'")
|
||||
exit(-4)
|
||||
# model_path = os.path.join(dpath, FILE_BASEMODEL)
|
||||
|
||||
# results = f"python train.py --local_rank 0 --data {dpath} --object fork" \
|
||||
# + f" -e {epochs} --batchsize 16 --exts jpg --imagesize 640 --pretrained" \
|
||||
# + " --net_path /home/shalenikol/fork_work/dope_training/output/weights_2996/net_epoch_47.pth"
|
||||
# print(results)
|
||||
train(dpath, wname, epochs, pretrain, list_name)
|
||||
|
||||
import argparse
|
||||
|
||||
|
@ -25,6 +536,7 @@ if __name__ == "__main__":
|
|||
parser.add_argument("--datasetName", required=True, help="String with dataset name")
|
||||
parser.add_argument("--outpath", default="weights", help="Output path for weights")
|
||||
parser.add_argument("--epoch", default=3, help="How many training epochs")
|
||||
parser.add_argument('--pretrain', action="store_true", help="Use pretraining")
|
||||
args = parser.parse_args()
|
||||
|
||||
train_Dope_i(args.path, args.name, args.datasetName, args.outpath, args.epoch)
|
||||
train_Dope_i(args.path, args.name, args.datasetName, args.outpath, args.epoch, args.pretrain)
|
||||
|
|
|
@ -28,7 +28,7 @@ DIR_COCO_DS = "rbs_coco"
|
|||
DIR_RGB_DS = "images"
|
||||
DIR_LABELS_DS = "labels"
|
||||
|
||||
SZ_SERIES = 5 # number of train images per validation images
|
||||
SZ_SERIES = 15 # number of train images per validation images
|
||||
|
||||
nn_image = 0
|
||||
f1 = f2 = None
|
||||
|
@ -166,7 +166,6 @@ def train_YoloV8(path:str, wname:str, dname:str, outpath:str, epochs:int, pretra
|
|||
|
||||
shutil.copy2(wf, os.path.join(dpath, wname + ".pt"))
|
||||
shutil.rmtree(results.save_dir)
|
||||
# print(f"\n ********\n{wf}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue