progress
This commit is contained in:
parent
3f951d1c09
commit
28c36ae710
31 changed files with 495 additions and 65 deletions
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -19,6 +19,7 @@
|
|||
"Contolls",
|
||||
"GLTF",
|
||||
"grau",
|
||||
"idontsudo",
|
||||
"raycaster",
|
||||
"skils",
|
||||
"typedataset",
|
||||
|
|
1
p.json
1
p.json
|
@ -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 ] ]}}
|
26
server/command.json
Normal file
26
server/command.json
Normal file
|
@ -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
|
||||
}
|
||||
}
|
|
@ -34,6 +34,33 @@ export abstract class CallbackStrategyWithFilesUploads {
|
|||
abstract call(files: File[]): ResponseBase;
|
||||
}
|
||||
|
||||
export class SubRouter<A> implements ISubSetFeatureRouter<A> {
|
||||
method: HttpMethodType;
|
||||
subUrl: string;
|
||||
fn:
|
||||
| CallbackStrategyWithValidationModel<A>
|
||||
| CallbackStrategyWithEmpty
|
||||
| CallbackStrategyWithIdQuery
|
||||
| CallBackStrategyWithQueryPage
|
||||
| CallbackStrategyWithFileUpload
|
||||
| CallbackStrategyWithFilesUploads;
|
||||
constructor(
|
||||
method: HttpMethodType,
|
||||
subUrl: string,
|
||||
fn:
|
||||
| CallbackStrategyWithValidationModel<A>
|
||||
| CallbackStrategyWithEmpty
|
||||
| CallbackStrategyWithIdQuery
|
||||
| CallBackStrategyWithQueryPage
|
||||
| CallbackStrategyWithFileUpload
|
||||
| CallbackStrategyWithFilesUploads
|
||||
) {
|
||||
this.fn = fn;
|
||||
this.subUrl = subUrl;
|
||||
this.method = method;
|
||||
}
|
||||
}
|
||||
|
||||
interface ISubSetFeatureRouter<A> {
|
||||
method: HttpMethodType;
|
||||
subUrl: string;
|
||||
|
@ -118,7 +145,7 @@ export class CoreHttpController<V> 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");
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<Result<ExecError | SpawnError, ExecutorResult>>
|
||||
): Promise<Result<Error, string>> => {
|
||||
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<Result<ExecError | SpawnError, ExecutorResult>>
|
||||
): Promise<Result<Error, string>> => {
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -21,10 +21,13 @@ export class ExecInstanceScenario extends CallbackStrategyWithIdQuery {
|
|||
await new ReadByIdDataBaseModelUseCase<IDigitalTwinsInstanceModel>(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)
|
||||
)
|
||||
|
|
|
@ -27,10 +27,11 @@ export class RobossemblerAssetsLocaleMapperScenario extends CallbackStrategyWith
|
|||
)
|
||||
).map(async (projectModel) => {
|
||||
const { rootDir } = projectModel[0];
|
||||
return (await new ReadFileAndParseJsonUseCase().call<Parts[]>(rootDir + StaticFilesProject.parts)).map(
|
||||
(model) => {
|
||||
return (await new ReadFileAndParseJsonUseCase().call<Parts[]>(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);
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
// );
|
||||
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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`;
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
}
|
|
@ -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<ExecProcesssss> {
|
||||
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");
|
||||
});
|
||||
}
|
|
@ -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.");
|
||||
}
|
||||
}
|
14
server/src/features/runtime/domain/get_command_scenario.ts
Normal file
14
server/src/features/runtime/domain/get_command_scenario.ts
Normal file
|
@ -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<Result<unknown, ExecProcess>> =>
|
||||
(
|
||||
await new ReadFileAndParseJsonUseCase().call<Command>(
|
||||
__filename.slice(0, __filename.lastIndexOf("/")).replace("/build/src/features/runtime/domain", "") +
|
||||
"/" +
|
||||
"command.json"
|
||||
)
|
||||
).map((el) => Result.ok(el[command]));
|
||||
}
|
|
@ -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("");
|
||||
}
|
14
server/src/features/runtime/model/command.ts
Normal file
14
server/src/features/runtime/model/command.ts
Normal file
|
@ -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;
|
||||
}
|
3
server/src/features/runtime/model/exec_process.ts
Normal file
3
server/src/features/runtime/model/exec_process.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export class ExecProcesssss{
|
||||
|
||||
}
|
23
server/src/features/runtime/model/run_time_database_model.ts
Normal file
23
server/src/features/runtime/model/run_time_database_model.ts
Normal file
|
@ -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<ExecRunTimeCommandValidationModel>(
|
||||
ExecRuntimeSchema,
|
||||
ExecRunTimeDataBaseSchema
|
||||
);
|
|
@ -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[] = [];
|
||||
}
|
25
server/src/features/runtime/runtime_presentation.ts
Normal file
25
server/src/features/runtime/runtime_presentation.ts
Normal file
|
@ -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<ExecRunTimeCommandValidationModel> {
|
||||
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(),
|
||||
});
|
||||
}
|
||||
}
|
22
server/src/features/runtime/service/process_watcher.ts
Normal file
22
server/src/features/runtime/service/process_watcher.ts
Normal file
|
@ -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<Result<ExecError | SpawnError, ExecutorResult>> {
|
||||
logs = "";
|
||||
delay: number;
|
||||
constructor(delay: number, pattern: string) {
|
||||
super();
|
||||
this.on(this.lister);
|
||||
setTimeout(() => {
|
||||
console.log(this.logs);
|
||||
}, delay);
|
||||
}
|
||||
|
||||
lister = (event: Result<ExecError | SpawnError, ExecutorResult>) => {
|
||||
event.map(async (success) => {
|
||||
this.logs += success.data;
|
||||
});
|
||||
};
|
||||
}
|
10
server/src/p.json
Normal file
10
server/src/p.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"execCommand": "string",
|
||||
"date": "date",
|
||||
"status": "Fail,Ok",
|
||||
"delay": 1000,
|
||||
"checkCommand": "string",
|
||||
"filter": [
|
||||
"/assembly_config"
|
||||
]
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<title>Robossembler</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body style="overflow: auto;">
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div style="width: 100%; height: 100%" id="root"></div>
|
||||
</body>
|
||||
|
|
|
@ -54,12 +54,72 @@ export class FormBuilderValidationModel
|
|||
new FormBuilderValidationModel("", simpleFormBuilder, [], "");
|
||||
static vision = () =>
|
||||
new FormBuilderValidationModel(
|
||||
`ENUM PRETRAIN = "true","false";`,
|
||||
`{
|
||||
"numberOfEpochs": \${numberOfEpochs:number:10},
|
||||
"selectDataset": \${<SelectDataset/>:OBJECT:{"dataset": {}},
|
||||
"pretrain": \${pretrain:Enum<PRETRAIN>: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<COLLISION_SHAPE>: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<L>: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":\${<SelectDetail/>:OBJECT:{"details": []},
|
||||
"typedataset": \${typedataset:Enum<T>: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<OBJECTS_SCENE>:[]},
|
||||
"lights": \${LIGHTS:Array<LIGHTS>:[]}
|
||||
},
|
||||
"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<F>:JPEG},
|
||||
"image_size_wh": [\${IMAGE_SIZE_WH_1:number:640}, \${IMAGE_SIZE_WH_2:number:480}]
|
||||
}
|
||||
}
|
||||
`,
|
||||
[],
|
||||
""
|
||||
);
|
||||
|
|
|
@ -8,6 +8,7 @@ interface InputV2Props {
|
|||
trim?: boolean;
|
||||
height?: number;
|
||||
onChange?: (text: string) => void;
|
||||
|
||||
}
|
||||
export const InputV2: React.FC<InputV2Props> = ({ label, height, value, onChange, trim }) => {
|
||||
return (
|
||||
|
|
|
@ -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[] = [];
|
||||
}
|
|
@ -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",
|
||||
}}
|
||||
>
|
||||
<ButtonV2 style={{ height: 40 }} onClick={() => {}} text="Запуск" textColor={themeStore.theme.black} />
|
||||
{/* <ButtonV2 style={{ height: 40 }} onClick={() => {}} text="Запуск" textColor={themeStore.theme.black} />
|
||||
<div style={{ width: 10 }} />
|
||||
<ButtonV2
|
||||
style={{ height: 40 }}
|
||||
|
@ -83,21 +87,25 @@ export const BehaviorTreeBuilderScreen = observer(() => {
|
|||
type={ButtonV2Type.empty}
|
||||
textColor={themeStore.theme.greenWhite}
|
||||
/>
|
||||
<div style={{ width: 10 }} />
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: store.isNeedSaveBtn ? themeStore.theme.greenWhite : undefined,
|
||||
height: 40,
|
||||
textAlign: "center",
|
||||
alignContent: "center",
|
||||
width: 40,
|
||||
borderRadius: 100,
|
||||
}}
|
||||
>
|
||||
{store.isNeedSaveBtn ? (
|
||||
<Icon style={{ height: 21 }} onClick={() => store.onClickSaveBehaviorTree()} type="Floppy" />
|
||||
) : undefined}
|
||||
</div>
|
||||
<div style={{ width: 10 }} /> */}
|
||||
{store.isNeedSaveBtn ? (
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: store.isNeedSaveBtn ? themeStore.theme.greenWhite : undefined,
|
||||
height: 40,
|
||||
textAlign: "center",
|
||||
alignContent: "center",
|
||||
width: 40,
|
||||
borderRadius: 100,
|
||||
}}
|
||||
>
|
||||
{store.isNeedSaveBtn ? (
|
||||
<Icon style={{ height: 21 }} onClick={() => store.onClickSaveBehaviorTree()} type="Floppy" />
|
||||
) : undefined}
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
@ -131,15 +139,33 @@ export const BehaviorTreeBuilderScreen = observer(() => {
|
|||
{store.skillTemplates ? <SkillTree skills={store.skillTree} dragEnd={store.dragEnd} /> : null}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
ref={ref}
|
||||
className="dotted"
|
||||
style={{
|
||||
width: "100%",
|
||||
position: "absolute",
|
||||
left: 300,
|
||||
height: "100%",
|
||||
backgroundSize: "20px 20px",
|
||||
width: "calc(100% - 300px)",
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<PanelGroup direction="horizontal" style={{ width: "100%" }}>
|
||||
<Panel>
|
||||
<div
|
||||
ref={ref}
|
||||
className="dotted"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundSize: "20px 20px",
|
||||
}}
|
||||
/>
|
||||
</Panel>
|
||||
<PanelResizeHandle>
|
||||
<div style={{ width: 10, height: "100%", backgroundColor: "beige" }}></div>
|
||||
</PanelResizeHandle>
|
||||
<Panel defaultSize={0}> </Panel>
|
||||
</PanelGroup>
|
||||
</div>
|
||||
</>
|
||||
|
||||
<DrawerV2
|
||||
|
|
|
@ -51,7 +51,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
|
|||
activeProject: string = "";
|
||||
behaviorTreeBuilderHttpRepository = new BehaviorTreeBuilderHttpRepository();
|
||||
canRun = true;
|
||||
isNeedSaveBtn = true;
|
||||
isNeedSaveBtn = false;
|
||||
selected: string = "";
|
||||
selectedSid: string = "";
|
||||
nodeBehaviorTree: NodeBehaviorTree[] = [];
|
||||
|
@ -207,7 +207,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
|
|||
)
|
||||
).fold(
|
||||
(xml) => {
|
||||
console.log(xml)
|
||||
console.log(xml);
|
||||
this.behaviorTreeModel.skills = this.filledOutTemplates;
|
||||
this.behaviorTreeModel.scene = NodeBehaviorTree.fromReteScene(
|
||||
this.editor as NodeEditor<Schemes>,
|
||||
|
@ -230,7 +230,7 @@ export class BehaviorTreeBuilderStore extends UiDrawerFormState<BehaviorTreeView
|
|||
);
|
||||
|
||||
validateBt() {}
|
||||
|
||||
|
||||
setSelected = (label: string, selected: boolean, sid: string) => {
|
||||
this.selectedSid = sid;
|
||||
this.selected = label;
|
||||
|
|
|
@ -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 (
|
||||
<div>
|
||||
<InputV2 label={"result"} onChange={(text) => (store.viewModel.result = text)} />
|
||||
<InputV2 label={"context"} onChange={(text) => (store.viewModel.context = text)} />
|
||||
<CoreButton text="click" onClick={() => (store.isModalOpen = true)} />
|
||||
<Modal
|
||||
destroyOnClose={true}
|
||||
open={store.isModalOpen}
|
||||
footer={null}
|
||||
closable={false}
|
||||
closeIcon={null}
|
||||
onCancel={() => {
|
||||
store.isModalOpen = false;
|
||||
}}
|
||||
>
|
||||
<FormBuilder
|
||||
formBuilder={store.viewModel}
|
||||
onChange={(e) => {
|
||||
console.log(e.output);
|
||||
// console.log(JSON.stringify(e.output))
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
root.render(
|
||||
<>
|
||||
<SocketListener>
|
||||
{/* <FormBuildTest /> */}
|
||||
{/* <SocketListener>
|
||||
<RouterProvider router={router} />
|
||||
</SocketListener>
|
||||
{/* <FormBuilder
|
||||
formBuilder={FormBuilderValidationModel.test()}
|
||||
onChange={function (change: FormBuilderValidationModel): void {
|
||||
console.log(JSON.stringify(change.output));
|
||||
</SocketListener> */}
|
||||
<SelectDetail
|
||||
// @ts-expect-error
|
||||
dependency={{}}
|
||||
onChange={function (obj: any): void {
|
||||
throw new Error("Function not implemented.");
|
||||
}}
|
||||
/> */}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue