From 28c36ae7108a53afd424a75eddecad101ebdb767 Mon Sep 17 00:00:00 2001 From: IDONTSUDO Date: Wed, 27 Nov 2024 19:29:49 +0300 Subject: [PATCH] progress --- .vscode/settings.json | 1 + p.json | 1 - server/command.json | 26 +++++++ .../src/core/controllers/http_controller.ts | 29 +++++++- server/src/core/controllers/routes.ts | 2 + .../core/services/executor_program_service.ts | 10 ++- .../src/core/usecases/exec_process_usecase.ts | 42 ++++++++++- ..._calculations_instance_process_scenario.ts | 3 +- .../domain/exec_instance_scenario.ts | 7 +- ...er_assets_absolute_path_mapper_scenario.ts | 15 ++-- ...ssembler_assets_network_mapper_scenario.ts | 4 +- .../runtime/domain/exec_bt_builder_usecase.ts | 7 ++ .../runtime/domain/exec_simulation_usecase.ts | 21 ++++++ .../domain/get_bt_builder_status_usecase.ts | 7 ++ .../runtime/domain/get_command_scenario.ts | 14 ++++ .../domain/get_simulation_state_usecase.ts | 10 +++ server/src/features/runtime/model/command.ts | 14 ++++ .../features/runtime/model/exec_process.ts | 3 + .../runtime/model/run_time_database_model.ts | 23 ++++++ .../model/run_time_validation_model.ts | 21 ++++++ .../features/runtime/runtime_presentation.ts | 25 +++++++ .../runtime/service/process_watcher.ts | 22 ++++++ server/src/p.json | 10 +++ ui/package.json | 4 +- ui/public/index.html | 2 +- .../model/form_builder_validation_model.tsx | 72 ++++++++++++++++-- ui/src/core/ui/input/input_v2.tsx | 1 + .../model/exec_run_time_command.ts | 21 ++++++ .../behavior_tree_builder_screen.tsx | 74 +++++++++++++------ .../behavior_tree_builder_store.tsx | 6 +- ui/src/index.tsx | 63 ++++++++++++++-- 31 files changed, 495 insertions(+), 65 deletions(-) delete mode 100644 p.json create mode 100644 server/command.json create mode 100644 server/src/features/runtime/domain/exec_bt_builder_usecase.ts create mode 100644 server/src/features/runtime/domain/exec_simulation_usecase.ts create mode 100644 server/src/features/runtime/domain/get_bt_builder_status_usecase.ts create mode 100644 server/src/features/runtime/domain/get_command_scenario.ts create mode 100644 server/src/features/runtime/domain/get_simulation_state_usecase.ts create mode 100644 server/src/features/runtime/model/command.ts create mode 100644 server/src/features/runtime/model/exec_process.ts create mode 100644 server/src/features/runtime/model/run_time_database_model.ts create mode 100644 server/src/features/runtime/model/run_time_validation_model.ts create mode 100644 server/src/features/runtime/runtime_presentation.ts create mode 100644 server/src/features/runtime/service/process_watcher.ts create mode 100644 server/src/p.json create mode 100644 ui/src/features/behavior_tree_builder/model/exec_run_time_command.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 1a82dcc..2793cf8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,6 +19,7 @@ "Contolls", "GLTF", "grau", + "idontsudo", "raycaster", "skils", "typedataset", diff --git a/p.json b/p.json deleted file mode 100644 index 8ba6c88..0000000 --- a/p.json +++ /dev/null @@ -1 +0,0 @@ -{"name": "default","collision_shape": "BOX","loc_xyz": [0, 0, 0],"rot_euler": [0,0, 0],"material_randomization": {   "specular": [0, 1],    "roughness": [0, 1],    "metallic": [0, 1],    "base_color": [        [            0,            0,            0,            1        ],        [            1,            1,            1,            1        ]    ]}} diff --git a/server/command.json b/server/command.json new file mode 100644 index 0000000..468f1fe --- /dev/null +++ b/server/command.json @@ -0,0 +1,26 @@ +{ + "tensorBoard": { + "execCommand": "nix run github:nixos/nixpkgs#python312Packages.tensorboard -- --logdir ${dir_path}", + "date": null, + "status": "Fail,Ok", + "delay": 200, + "checkCommand": null, + "filter": null + }, + "simulationProcess": { + "execCommand": "nix run github:nixos/nixpkgs#python312Packages.tensorboard -- --logdir ${dir_path}", + "date": null, + "status": null, + "delay": 0, + "checkCommand": null, + "filter": null + }, + "btBuilderProcess": { + "execCommand": "nix run github:nixos/nixpkgs#python312Packages.tensorboard -- --logdir ${dir_path}", + "date": null, + "status": null, + "delay": 0, + "checkCommand": null, + "filter": null + } +} \ No newline at end of file diff --git a/server/src/core/controllers/http_controller.ts b/server/src/core/controllers/http_controller.ts index cb85282..5b61528 100644 --- a/server/src/core/controllers/http_controller.ts +++ b/server/src/core/controllers/http_controller.ts @@ -34,6 +34,33 @@ export abstract class CallbackStrategyWithFilesUploads { abstract call(files: File[]): ResponseBase; } +export class SubRouter implements ISubSetFeatureRouter { + method: HttpMethodType; + subUrl: string; + fn: + | CallbackStrategyWithValidationModel + | CallbackStrategyWithEmpty + | CallbackStrategyWithIdQuery + | CallBackStrategyWithQueryPage + | CallbackStrategyWithFileUpload + | CallbackStrategyWithFilesUploads; + constructor( + method: HttpMethodType, + subUrl: string, + fn: + | CallbackStrategyWithValidationModel + | CallbackStrategyWithEmpty + | CallbackStrategyWithIdQuery + | CallBackStrategyWithQueryPage + | CallbackStrategyWithFileUpload + | CallbackStrategyWithFilesUploads + ) { + this.fn = fn; + this.subUrl = subUrl; + this.method = method; + } +} + interface ISubSetFeatureRouter { method: HttpMethodType; subUrl: string; @@ -118,7 +145,7 @@ export class CoreHttpController implements ICoreHttpController { await this.responseHelper(res, el.fn.call()); return; } - + if (el.fn instanceof CallbackStrategyWithFileUpload) { if (req["files"] === undefined) { res.status(400).json("need files to form-data request"); diff --git a/server/src/core/controllers/routes.ts b/server/src/core/controllers/routes.ts index 538118a..bd7105b 100644 --- a/server/src/core/controllers/routes.ts +++ b/server/src/core/controllers/routes.ts @@ -10,6 +10,7 @@ import { DigitalTwinsInstancePresentation } from "../../features/digital_twins_i import { DigitalTwinsTemplatePresentation } from "../../features/digital_twins_template/digital_twins_template_presentation"; import { TopicsPresentation } from "../../features/topics/topics_presentation"; import { SkillsPresentation } from "../../features/skills/skill_presentation"; +import { RunTimePresentation } from "../../features/runtime/runtime_presentation"; extensions(); @@ -24,4 +25,5 @@ export const httpRoutes: Routes[] = [ new DigitalTwinsInstancePresentation(), new TopicsPresentation(), new SkillsPresentation(), + new RunTimePresentation(), ].map((el) => el.call()); diff --git a/server/src/core/services/executor_program_service.ts b/server/src/core/services/executor_program_service.ts index bee83c7..2f5dc7b 100644 --- a/server/src/core/services/executor_program_service.ts +++ b/server/src/core/services/executor_program_service.ts @@ -41,7 +41,7 @@ export class ExecutorProgramService await delay(300); this.worker = worker; - + const workerDataExec: WorkerDataExec = { command: command, execPath: this.execPath, @@ -50,6 +50,7 @@ export class ExecutorProgramService }; worker.send(workerDataExec); worker.on("message", (e) => { + console.log(JSON.stringify(e)); const spawnError = SpawnError.isError(e); if (spawnError instanceof SpawnError) { @@ -60,7 +61,7 @@ export class ExecutorProgramService const execError = ExecError.isExecError(e); if (execError instanceof ExecError) { - execError.id = id + execError.id = id; this.emit(Result.error(execError)); this.worker = undefined; return; @@ -68,7 +69,7 @@ export class ExecutorProgramService const executorResult = ExecutorResult.isExecutorResult(e); if (executorResult instanceof ExecutorResult) { - executorResult.id = id + executorResult.id = id; this.emit(Result.ok(executorResult)); this.worker = undefined; return; @@ -103,7 +104,8 @@ export class ExecutorProgramService return; } - this.workerExecuted(command, WorkerType.SPAWN, args, id); + const commands = command.split(" "); + this.workerExecuted(commands.at(0), WorkerType.SPAWN, commands.slice(1, commands.length), id); return; } diff --git a/server/src/core/usecases/exec_process_usecase.ts b/server/src/core/usecases/exec_process_usecase.ts index 12b7d16..379e1e2 100644 --- a/server/src/core/usecases/exec_process_usecase.ts +++ b/server/src/core/usecases/exec_process_usecase.ts @@ -1,7 +1,8 @@ +import * as cp from "child_process"; import { CallbackStrategyWithEmpty } from "../controllers/http_controller"; import { Result } from "../helpers/result"; import { TypedEvent } from "../helpers/typed_event"; -import { EXEC_TYPE, ExecError, SpawnError } from "../models/exec_error_model"; +import { EXEC_EVENT, EXEC_TYPE, ExecError, SpawnError } from "../models/exec_error_model"; import { ExecutorResult } from "../models/executor_result"; import { ExecutorProgramService } from "../services/executor_program_service"; @@ -26,7 +27,7 @@ export class ExecProcessUseCase { call = async ( path: string, command: string, - id:string, + id: string, watcher?: TypedEvent> ): Promise> => { try { @@ -34,7 +35,7 @@ export class ExecProcessUseCase { executorProgramService.on((event) => { if (watcher) watcher.emit(event); }); - executorProgramService.call(EXEC_TYPE.EXEC, command, undefined ,id); + executorProgramService.call(EXEC_TYPE.EXEC, command, undefined, id); return Result.ok("ok"); } catch (error) { @@ -42,3 +43,38 @@ export class ExecProcessUseCase { } }; } + +export class SpawnProcessUseCase { + call = async ( + path: string, + command: string, + id: string, + watcher?: TypedEvent> + ): Promise> => { + try { + const commands = command.split(" "); + + const subprocess = cp.spawn(commands.at(0), commands.slice(1, commands.length), { + cwd: path, + }); + const sendWatcher = (event: Buffer) => { + if (watcher) { + watcher.emit(Result.ok(new ExecutorResult(EXEC_TYPE.SPAWN, EXEC_EVENT.PROGRESS, event.toString()))); + } + }; + subprocess.stdout.on("data", (data) => sendWatcher(data)); + + subprocess.stderr.on("data", (data) => sendWatcher(data)); + + subprocess.on("error", (error) => { + console.error(`Ошибка: ${error.message}`); + }); + + subprocess.on("close", (code) => { + console.log(`Процесс завершился с кодом: ${code}`); + }); + } catch (error) { + return Result.error(error); + } + }; +} diff --git a/server/src/features/calculations_instance/domain/exec_calculations_instance_process_scenario.ts b/server/src/features/calculations_instance/domain/exec_calculations_instance_process_scenario.ts index 44ab62b..bc603d1 100644 --- a/server/src/features/calculations_instance/domain/exec_calculations_instance_process_scenario.ts +++ b/server/src/features/calculations_instance/domain/exec_calculations_instance_process_scenario.ts @@ -15,8 +15,7 @@ export class ExecCalculationInstanceProcessScenario extends CallbackStrategyWith return (await new IsHaveActiveProcessUseCase().call()).map(async () => { const execCommand = `${model.script} --form '${JSON.stringify( model.formBuilder - )}' --path ${model.instancePath.normalize()}`; - console.log(execCommand); + )}' --path ${model.instancePath.pathNormalize()}`; await CalculationInstanceDBModel.findById(id).updateOne({ processStatus: "RUN", lastProcessExecCommand: execCommand, diff --git a/server/src/features/digital_twins_instance/domain/exec_instance_scenario.ts b/server/src/features/digital_twins_instance/domain/exec_instance_scenario.ts index bbc6805..f4ec799 100644 --- a/server/src/features/digital_twins_instance/domain/exec_instance_scenario.ts +++ b/server/src/features/digital_twins_instance/domain/exec_instance_scenario.ts @@ -21,10 +21,13 @@ export class ExecInstanceScenario extends CallbackStrategyWithIdQuery { await new ReadByIdDataBaseModelUseCase(DigitalTwinsInstanceDatabaseModel).call(id) ).map( (document) => ( - console.log(JSON.stringify(document)), + console.log('DOCUMeNT PATH'), + console.log(document.instancePath.pathNormalize()), new ExecProcessUseCase().call( document.instancePath, - `python3 $GET_INTERFACES --path ${document.instancePath.pathNormalize()} --package '${JSON.stringify(document)}'`, + `python3 $GET_INTERFACES --path ${document.instancePath.pathNormalize()} --package '${JSON.stringify( + document + )}'`, "", new ExecInstanceTwinsProcessService(document.instancePath, document) ) diff --git a/server/src/features/projects/domain/robossembler_assets_absolute_path_mapper_scenario.ts b/server/src/features/projects/domain/robossembler_assets_absolute_path_mapper_scenario.ts index 43121bc..d4a9b33 100644 --- a/server/src/features/projects/domain/robossembler_assets_absolute_path_mapper_scenario.ts +++ b/server/src/features/projects/domain/robossembler_assets_absolute_path_mapper_scenario.ts @@ -27,10 +27,11 @@ export class RobossemblerAssetsLocaleMapperScenario extends CallbackStrategyWith ) ).map(async (projectModel) => { const { rootDir } = projectModel[0]; - return (await new ReadFileAndParseJsonUseCase().call(rootDir + StaticFilesProject.parts)).map( - (model) => { + return (await new ReadFileAndParseJsonUseCase().call(rootDir + StaticFilesProject.parts)).map((model) => + Result.ok( model.map((el) => { - const assetLibsAddress = rootDir + "/libs/objects/" + el.name; + const assetLibsAddress = rootDir + "/assets/libs/objects/" + el.name; + console.log(assetLibsAddress); el.fbx = `${assetLibsAddress}.fbx`; el.stlUrl = `${assetLibsAddress}${el.part_path}`; el.glUrl = `${assetLibsAddress}.glb`; @@ -38,11 +39,11 @@ export class RobossemblerAssetsLocaleMapperScenario extends CallbackStrategyWith el.objUrl = `${assetLibsAddress}.obj`; el.image = `${assetLibsAddress}.png`; el.solidType = "active"; + return el; - }); - return Result.ok(model); - } + }) + ) ); - // ); + }); } diff --git a/server/src/features/projects/domain/robossembler_assets_network_mapper_scenario.ts b/server/src/features/projects/domain/robossembler_assets_network_mapper_scenario.ts index c6cdc12..8b24b30 100644 --- a/server/src/features/projects/domain/robossembler_assets_network_mapper_scenario.ts +++ b/server/src/features/projects/domain/robossembler_assets_network_mapper_scenario.ts @@ -34,8 +34,8 @@ export class RobossemblerAssetsNetworkMapperScenario extends CallbackStrategyWit rootDir.match(new RegExp(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gm))[0] + "/assets/"; model.map((el) => { - const assetLibsAddress = assetAddress + "libs/objects/" + el.name; - + const assetLibsAddress = assetAddress + "/libs/objects/" + el.name; + console.log(assetLibsAddress); el.stlUrl = `${assetAddress}${el.part_path}`; el.glUrl = `${assetLibsAddress}.glb`; el.daeUrl = `${assetLibsAddress}.dae`; diff --git a/server/src/features/runtime/domain/exec_bt_builder_usecase.ts b/server/src/features/runtime/domain/exec_bt_builder_usecase.ts new file mode 100644 index 0000000..66ea474 --- /dev/null +++ b/server/src/features/runtime/domain/exec_bt_builder_usecase.ts @@ -0,0 +1,7 @@ +import { CallbackStrategyWithEmpty, ResponseBase } from "../../../core/controllers/http_controller"; + +export class ExecBtBuilderUseCase extends CallbackStrategyWithEmpty { + call(): ResponseBase { + throw new Error("Method not implemented."); + } +} diff --git a/server/src/features/runtime/domain/exec_simulation_usecase.ts b/server/src/features/runtime/domain/exec_simulation_usecase.ts new file mode 100644 index 0000000..a2b9824 --- /dev/null +++ b/server/src/features/runtime/domain/exec_simulation_usecase.ts @@ -0,0 +1,21 @@ +import { App } from "../../../core/controllers/app"; +import { CallbackStrategyWithValidationModel, ResponseBase } from "../../../core/controllers/http_controller"; +import { Result } from "../../../core/helpers/result"; +import { SpawnProcessUseCase } from "../../../core/usecases/exec_process_usecase"; +import { ExecProcesssss } from "../model/exec_process"; +import { ProcessWatcher } from "../service/process_watcher"; +import { GetCommandScenario } from "./get_command_scenario"; + +export class ExecSimulationUseCase extends CallbackStrategyWithValidationModel { + validationModel = new ExecProcesssss(); + call = async (): ResponseBase => + (await new GetCommandScenario().call("btBuilderProcess")).map((el) => { + new SpawnProcessUseCase().call( + App.staticFilesStoreDir(), + el.execCommand.replace("${dir_path}", "/Users/idontsudo/train"), + "btBuilder", + new ProcessWatcher(2000, "localhost") + ); + return Result.ok("200"); + }); +} diff --git a/server/src/features/runtime/domain/get_bt_builder_status_usecase.ts b/server/src/features/runtime/domain/get_bt_builder_status_usecase.ts new file mode 100644 index 0000000..26c76f7 --- /dev/null +++ b/server/src/features/runtime/domain/get_bt_builder_status_usecase.ts @@ -0,0 +1,7 @@ +import { CallbackStrategyWithEmpty, ResponseBase } from "../../../core/controllers/http_controller"; + +export class GetBtBuilderStateUseCase extends CallbackStrategyWithEmpty { + call(): ResponseBase { + throw new Error("Method not implemented."); + } +} diff --git a/server/src/features/runtime/domain/get_command_scenario.ts b/server/src/features/runtime/domain/get_command_scenario.ts new file mode 100644 index 0000000..2212522 --- /dev/null +++ b/server/src/features/runtime/domain/get_command_scenario.ts @@ -0,0 +1,14 @@ +import { ReadFileAndParseJsonUseCase } from "../../../core/usecases/read_file_and_parse_json"; +import { Result } from "../../../core/helpers/result"; +import { Command, ExecProcess } from "../model/command"; + +export class GetCommandScenario { + call = async (command: string): Promise> => + ( + await new ReadFileAndParseJsonUseCase().call( + __filename.slice(0, __filename.lastIndexOf("/")).replace("/build/src/features/runtime/domain", "") + + "/" + + "command.json" + ) + ).map((el) => Result.ok(el[command])); +} diff --git a/server/src/features/runtime/domain/get_simulation_state_usecase.ts b/server/src/features/runtime/domain/get_simulation_state_usecase.ts new file mode 100644 index 0000000..4658739 --- /dev/null +++ b/server/src/features/runtime/domain/get_simulation_state_usecase.ts @@ -0,0 +1,10 @@ +import { CallbackStrategyWithEmpty, ResponseBase } from "../../../core/controllers/http_controller"; +import { Result } from "../../../core/helpers/result"; +import { SpawnProcessUseCase } from "../../../core/usecases/exec_process_usecase"; +import { GetCommandScenario } from "./get_command_scenario"; +import { ProcessWatcher } from "../service/process_watcher"; +import { App } from "../../../core/controllers/app"; + +export class GetSimulationStateScenario extends CallbackStrategyWithEmpty { + call = async (): ResponseBase => Result.ok(""); +} diff --git a/server/src/features/runtime/model/command.ts b/server/src/features/runtime/model/command.ts new file mode 100644 index 0000000..863d14e --- /dev/null +++ b/server/src/features/runtime/model/command.ts @@ -0,0 +1,14 @@ +export interface Command { + tensorBoard: ExecProcess; + simulationProcess: ExecProcess; + btBuilderProcess: ExecProcess; +} + +export interface ExecProcess { + execCommand: string; + date: null; + status: null | string; + delay: number; + checkCommand: null; + filter: null; +} diff --git a/server/src/features/runtime/model/exec_process.ts b/server/src/features/runtime/model/exec_process.ts new file mode 100644 index 0000000..4b2dcb1 --- /dev/null +++ b/server/src/features/runtime/model/exec_process.ts @@ -0,0 +1,3 @@ +export class ExecProcesssss{ + +} \ No newline at end of file diff --git a/server/src/features/runtime/model/run_time_database_model.ts b/server/src/features/runtime/model/run_time_database_model.ts new file mode 100644 index 0000000..6f79226 --- /dev/null +++ b/server/src/features/runtime/model/run_time_database_model.ts @@ -0,0 +1,23 @@ +import { Schema, model } from "mongoose"; +import { ExecRunTimeCommandValidationModel as ExecRunTimeCommandValidationModel } from "./run_time_validation_model"; + +export interface IDigitalTwinsInstanceModel { + instancePath: string; + status?: string; +} + +export const ExecRunTimeDataBaseSchema = new Schema({ + execCommand: String, + date: String, + status: String, + delay: Number, + checkCommand: String, + filter: Array, +}).plugin(require("mongoose-autopopulate")); + +export const ExecRuntimeSchema = "digital_twins_instance"; + +export const ExecRuntimeDatabaseModel = model( + ExecRuntimeSchema, + ExecRunTimeDataBaseSchema +); diff --git a/server/src/features/runtime/model/run_time_validation_model.ts b/server/src/features/runtime/model/run_time_validation_model.ts new file mode 100644 index 0000000..ba2c3fb --- /dev/null +++ b/server/src/features/runtime/model/run_time_validation_model.ts @@ -0,0 +1,21 @@ +import { IsArray, IsEnum, IsNumber, IsString } from "class-validator"; + +export enum Status { + OK = "Ok", + ERROR = "Error", +} + +export class ExecRunTimeCommandValidationModel { + @IsString() + execCommand: string; + @IsString() + date: string = Date(); + @IsEnum(Status) + status: Status; + @IsNumber() + delay: number; + @IsString() + checkCommand: string; + @IsArray() + filter: string[] = []; +} diff --git a/server/src/features/runtime/runtime_presentation.ts b/server/src/features/runtime/runtime_presentation.ts new file mode 100644 index 0000000..03608ce --- /dev/null +++ b/server/src/features/runtime/runtime_presentation.ts @@ -0,0 +1,25 @@ +import { CrudController } from "../../core/controllers/crud_controller"; +import { ExecRunTimeCommandValidationModel } from "./model/run_time_validation_model"; +import { ExecRuntimeDatabaseModel } from "./model/run_time_database_model"; +import { CoreHttpController, SubRouter, HttpMethodType } from "../../core/controllers/http_controller"; +import { ExecBtBuilderUseCase } from "./domain/exec_bt_builder_usecase"; +import { ExecSimulationUseCase } from "./domain/exec_simulation_usecase"; +import { GetBtBuilderStateUseCase } from "./domain/get_bt_builder_status_usecase"; +import { GetSimulationStateScenario } from "./domain/get_simulation_state_usecase"; + +export class RunTimePresentation extends CoreHttpController { + constructor() { + super({ + url: "run_time", + }); + + this.subRoutes.push(new SubRouter("POST", "/exec/bt/builder", new ExecBtBuilderUseCase())); + this.subRoutes.push(new SubRouter("POST", "/get/bt/builder/state", new GetBtBuilderStateUseCase())); + this.subRoutes.push(new SubRouter("POST", "/get/simulator/state", new GetSimulationStateScenario())); + this.subRoutes.push({ + method: "POST", + subUrl: "/exec/simulation/", + fn: new ExecSimulationUseCase(), + }); + } +} diff --git a/server/src/features/runtime/service/process_watcher.ts b/server/src/features/runtime/service/process_watcher.ts new file mode 100644 index 0000000..5263886 --- /dev/null +++ b/server/src/features/runtime/service/process_watcher.ts @@ -0,0 +1,22 @@ +import { Result } from "../../../core/helpers/result"; +import { TypedEvent } from "../../../core/helpers/typed_event"; +import { ExecError, SpawnError } from "../../../core/models/exec_error_model"; +import { ExecutorResult } from "../../../core/models/executor_result"; + +export class ProcessWatcher extends TypedEvent> { + logs = ""; + delay: number; + constructor(delay: number, pattern: string) { + super(); + this.on(this.lister); + setTimeout(() => { + console.log(this.logs); + }, delay); + } + + lister = (event: Result) => { + event.map(async (success) => { + this.logs += success.data; + }); + }; +} diff --git a/server/src/p.json b/server/src/p.json new file mode 100644 index 0000000..7f17eff --- /dev/null +++ b/server/src/p.json @@ -0,0 +1,10 @@ +{ + "execCommand": "string", + "date": "date", + "status": "Fail,Ok", + "delay": 1000, + "checkCommand": "string", + "filter": [ + "/assembly_config" + ] +} \ No newline at end of file diff --git a/ui/package.json b/ui/package.json index d62d998..294e7fa 100644 --- a/ui/package.json +++ b/ui/package.json @@ -21,6 +21,7 @@ "react-dom": "^18.2.0", "react-i18next": "^13.3.1", "react-infinite-scroll-component": "^6.1.0", + "react-resizable-panels": "^2.1.7", "react-router-dom": "^6.18.0", "react-scripts": "5.0.1", "reflect-metadata": "^0.1.13", @@ -39,7 +40,6 @@ "ws": "^8.17.0", "xml-formatter": "^3.6.2" }, - "overrides": { "typescript": "^5.0.2" }, @@ -76,4 +76,4 @@ "@types/three": "^0.158.3", "@types/uuid": "^9.0.2" } -} \ No newline at end of file +} diff --git a/ui/public/index.html b/ui/public/index.html index 750de6c..2cfa6db 100644 --- a/ui/public/index.html +++ b/ui/public/index.html @@ -23,7 +23,7 @@ Robossembler - +
diff --git a/ui/src/core/model/form_builder_validation_model.tsx b/ui/src/core/model/form_builder_validation_model.tsx index 7ae2120..f858f40 100644 --- a/ui/src/core/model/form_builder_validation_model.tsx +++ b/ui/src/core/model/form_builder_validation_model.tsx @@ -54,12 +54,72 @@ export class FormBuilderValidationModel new FormBuilderValidationModel("", simpleFormBuilder, [], ""); static vision = () => new FormBuilderValidationModel( - `ENUM PRETRAIN = "true","false";`, - `{ - "numberOfEpochs": \${numberOfEpochs:number:10}, - "selectDataset": \${:OBJECT:{"dataset": {}}, - "pretrain": \${pretrain:Enum:true} - }`, + ` + ENUM T = "ObjectDetection","PoseEstimation"; + ENUM L = "POINT","SUN"; + ENUM F = "JPEG","PNG"; + ENUM COLLISION_SHAPE = "BOX","COLLISION"; + + type OBJECTS_SCENE = { + "name": \${NAME:string:default}, + "collision_shape": \${collision_shape:Enum:BOX}, + "loc_xyz": [\${LOC_XYZ_1:number:0}, \${LOC_XYZ_2:number:0}, \${LOC_XYZ_3:number:0}], + "rot_euler": [\${ROT_EULER_1:number:0},\${ROT_EULER_2:number:0}, \${ROT_EULER_3:number:0}], + "material_randomization": { + "specular": [\${SPECULAR_1:number:0}, \${SPECULAR_2:number:1}], + "roughness": [\${ROUGHNESS_1:number:0}, \${ROUGHNESS_2:number:1}], + "metallic": [\${METALLIC_1:number:0}, \${METALLIC_2:number:1}], + "base_color": [ + [ + \${BASE_COLOR_1:number:0}, + \${BASE_COLOR_2:number:0}, + \${BASE_COLOR_3:number:0}, + \${BASE_COLOR_4:number:1} + ], + [ + \${BASE_COLOR_5:number:1}, + \${BASE_COLOR_6:number:1}, + \${BASE_COLOR_7:number:1}, + \${BASE_COLOR_8:number:1} + ] + ] + } + }; + type LIGHTS = { + "id": \${ID:number:1}, + "type": \${type:Enum:POINT}, + "loc_xyz": [\${LOC_XYZ_1:number:5}, \${LOC_XYZ_2:number:5}, \${LOC_XYZ_3:number:5}], + "rot_euler": [\${ROT_EULER_1:number:-0.06}, \${ROT_EULER_2:number:0.61}, \${ROT_EULER_3:number:-0.19}], + "color_range_low": [\${COLOR_RANGE_LOW_1:number:0.5}, \${COLOR_RANGE_LOW_2:number:0.5}, \${COLOR_RANGE_LOW_3:number:0.5}], + "color_range_high":[\${COLOR_RANGE_HIGH_1:number:1}, \${COLOR_RANGE_HIGH_2:number:1}, $\{COLOR_RANGE_HIGH_3:number:1}], + "energy_range":[\${ENERGY_RANGE_1:number:400},\${ENERGY_RANGE_2:number:900}] + };`, + ` + { + "datasetObjects":\${:OBJECT:{"details": []}, + "typedataset": \${typedataset:Enum:ObjectDetection}, + "models_randomization":{ + "loc_range_low": [\${LOC_RANGE_LOW_1:number:-1}, \${LOC_RANGE_LOW_2:number:-1},\${LOC_RANGE_LOW_3:number:0}], + "loc_range_high": [\${LOC_RANGE_HIGH_1:number:1}, \${LOC_RANGE_HIGH_2:number:1},\${LOC_RANGE_HIGH_3:number:2}] + }, + "scene":{ + "objects": \${OBJECTS_SCENE:Array:[]}, + "lights": \${LIGHTS:Array:[]} + }, + "camera_position":{ + "center_shell": [\${CENTER_SHELL_1:number:0}, \${CENTER_SHELL_2:number:0}, \${CENTER_SHELL_3:number:0}], + "radius_range": [\${RADIUS_RANGE_1:number:1}, \${RADIUS_RANGE_2:number:1.4}], + "elevation_range": [\${ELEVATION_RANGE_1:number:10}, \${ELEVATION_RANGE_2:number:90}] + }, + "generation":{ + "n_cam_pose": \${N_CAM_POSE:number:5}, + "n_sample_on_pose": \${N_SAMPLE_ON_POSE:number:3}, + "n_series": \${N_SERIES:number:100}, + "image_format": \${image_format:Enum:JPEG}, + "image_size_wh": [\${IMAGE_SIZE_WH_1:number:640}, \${IMAGE_SIZE_WH_2:number:480}] + } + } + `, [], "" ); diff --git a/ui/src/core/ui/input/input_v2.tsx b/ui/src/core/ui/input/input_v2.tsx index 16ab3f5..30bfc20 100644 --- a/ui/src/core/ui/input/input_v2.tsx +++ b/ui/src/core/ui/input/input_v2.tsx @@ -8,6 +8,7 @@ interface InputV2Props { trim?: boolean; height?: number; onChange?: (text: string) => void; + } export const InputV2: React.FC = ({ label, height, value, onChange, trim }) => { return ( diff --git a/ui/src/features/behavior_tree_builder/model/exec_run_time_command.ts b/ui/src/features/behavior_tree_builder/model/exec_run_time_command.ts new file mode 100644 index 0000000..c3ba771 --- /dev/null +++ b/ui/src/features/behavior_tree_builder/model/exec_run_time_command.ts @@ -0,0 +1,21 @@ +import { IsArray, IsEnum, IsNumber, IsString } from "class-validator"; +import { ValidationModel } from "../../../core/model/validation_model"; + +export enum Status { + OK = "Ok", + ERROR = "Error", +} +export class ExecRunTimeCommand extends ValidationModel { + @IsString() + execCommand: string; + @IsString() + date: string = Date(); + @IsEnum(Status) + status: Status; + @IsNumber() + delay: number; + @IsString() + checkCommand: string; + @IsArray() + filter: string[] = []; +} diff --git a/ui/src/features/behavior_tree_builder/presentation/behavior_tree_builder_screen.tsx b/ui/src/features/behavior_tree_builder/presentation/behavior_tree_builder_screen.tsx index 3e0e557..5a890c6 100644 --- a/ui/src/features/behavior_tree_builder/presentation/behavior_tree_builder_screen.tsx +++ b/ui/src/features/behavior_tree_builder/presentation/behavior_tree_builder_screen.tsx @@ -17,8 +17,10 @@ import { InputV2 } from "../../../core/ui/input/input_v2"; import { SelectV2 } from "../../../core/ui/select/select_v2"; import { MainPageV2 } from "../../../core/ui/pages/main_page_v2"; import { DrawerV2 } from "../../../core/ui/drawer/drawer"; +import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"; export const behaviorTreeBuilderScreenPath = "behavior/tree/screen/path"; + export interface DOMReact { x: number; y: number; @@ -31,14 +33,17 @@ export interface DOMReact { } export const behaviorTreeBuilderStore = new BehaviorTreeBuilderStore(); + export const BehaviorTreeBuilderPath = (id?: string) => { if (id) { return `/behavior/tree/${id}`; } return `/behavior/tree/`; }; + export const isBtScreen = () => Boolean(window.location.href.match(new RegExp(BehaviorTreeBuilderPath()))?.at(0)) ?? false; + export const BehaviorTreeBuilderScreen = observer(() => { const navigate = useNavigate(); const { id } = useParams(); @@ -54,9 +59,7 @@ export const BehaviorTreeBuilderScreen = observer(() => { }, [ref.current]); React.useEffect(() => { - store.init(navigate).then(() => { - store.initParam(id); - }); + store.init(navigate).then(() => store.initParam(id)); return () => { store.dispose(); }; @@ -71,10 +74,11 @@ export const BehaviorTreeBuilderScreen = observer(() => { display: "flex", flexDirection: "row", justifyContent: "end", + paddingRight: 30, alignItems: "center", }} > - {}} text="Запуск" textColor={themeStore.theme.black} /> + {/* {}} text="Запуск" textColor={themeStore.theme.black} />
{ type={ButtonV2Type.empty} textColor={themeStore.theme.greenWhite} /> -
-
- {store.isNeedSaveBtn ? ( - store.onClickSaveBehaviorTree()} type="Floppy" /> - ) : undefined} -
+
*/} + {store.isNeedSaveBtn ? ( +
+ {store.isNeedSaveBtn ? ( + store.onClickSaveBehaviorTree()} type="Floppy" /> + ) : undefined} +
+ ) : ( + <> + )}
} @@ -131,15 +139,33 @@ export const BehaviorTreeBuilderScreen = observer(() => { {store.skillTemplates ? : null}
+
+ > + + +
+ + +
+
+ + +
{ - console.log(xml) + console.log(xml); this.behaviorTreeModel.skills = this.filledOutTemplates; this.behaviorTreeModel.scene = NodeBehaviorTree.fromReteScene( this.editor as NodeEditor, @@ -230,7 +230,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState { this.selectedSid = sid; this.selected = label; diff --git a/ui/src/index.tsx b/ui/src/index.tsx index d903f84..bee6c9a 100644 --- a/ui/src/index.tsx +++ b/ui/src/index.tsx @@ -9,6 +9,16 @@ import { configure } from "mobx"; import { ThemeStore } from "./core/store/theme_store"; import { FormBuilderValidationModel } from "./core/model/form_builder_validation_model"; import { FormBuilder } from "./core/ui/form_builder/form_builder"; +import { observer } from "mobx-react-lite"; +import { useStore } from "./core/helper/use_store"; +import { LifeCycleStore, ModalStore } from "./core/store/base_store"; +import { CoreInput } from "./core/ui/input/input"; +import { InputV2 } from "./core/ui/input/input_v2"; +import { useState } from "react"; +import { Button, Modal } from "antd"; +import makeAutoObservable from "mobx-store-inheritance"; +import { CoreButton } from "./core/ui/button/button"; +import { SelectDetail } from "./core/ui/form_builder/forms/select_detail/presentation/select_detail_screen"; configure({ enforceActions: "never", @@ -19,16 +29,55 @@ extensions(); const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement); export const themeStore = new ThemeStore(); +class FormBuilderTextStore extends ModalStore { + viewModel = FormBuilderValidationModel.empty(); + constructor() { + super(); + makeAutoObservable(this); + } + init = undefined; +} +export const FormBuildTest = observer(() => { + const [store] = useState(new FormBuilderTextStore()); + + return ( +
+ (store.viewModel.result = text)} /> + (store.viewModel.context = text)} /> + (store.isModalOpen = true)} /> + { + store.isModalOpen = false; + }} + > + { + console.log(e.output); + // console.log(JSON.stringify(e.output)) + }} + /> + +
+ ); +}); root.render( <> - + {/* */} + {/* - - {/* */} + */} + /> );