bt builder

This commit is contained in:
IDONTSUDO 2024-05-29 15:38:36 +03:00
parent 5162612a77
commit c5ae89d18a
52 changed files with 1013 additions and 441 deletions

View file

@ -6,7 +6,6 @@ import { Server } from "socket.io";
import { createServer } from "http";
import { SocketSubscriber } from "./socket_controller";
import { dirname } from "path";
import { SetLastActivePipelineToRealTimeServiceScenario } from "../scenarios/set_active_pipeline_to_realtime_service_scenario";
import { CheckAndCreateStaticFilesFolderUseCase } from "../usecases/check_and_create_static_files_folder_usecase";
import { DataBaseConnectUseCase } from "../usecases/database_connect_usecase";
import { TypedEvent } from "../helpers/typed_event";
@ -58,8 +57,6 @@ export class App extends TypedEvent<ServerStatus> {
io.on("connection", (socket) => {
this.socketSubscribers.map((el) => {
el.emitter.on((e) => {
console.log(el.event)
console.log(e)
socket.emit(el.event, e);
});
});
@ -125,3 +122,4 @@ export class App extends TypedEvent<ServerStatus> {
};
}

View file

@ -3,6 +3,7 @@ import { Result } from "../helpers/result";
import { Router, Request, Response } from "express";
import { IRouteModel, Routes } from "../interfaces/router";
import { CoreValidation } from "../validations/core_validation";
import { plainToInstance } from "class-transformer";
export type HttpMethodType = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "PATCH" | "HEAD";
@ -78,11 +79,11 @@ export class CoreHttpController<V> implements ICoreHttpController {
}
call(): Routes {
if (this.subRoutes.isNotEmpty()) {
this.subRoutes.map((el) => {
this.subRoutes.map(async (el) => {
this.router[el.method.toLowerCase()](this.mainURL + "/" + el.subUrl, async (req, res) => {
if (el.fn instanceof CallbackStrategyWithValidationModel) {
// TODO(IDONTSUDO):
throw Error("needs to be implimed");
this.responseHelper(res, el.fn.call(req.body));
return;
}
if (el.fn instanceof CallbackStrategyWithIdQuery) {
if (req.query.id === undefined) {

View file

@ -10,11 +10,13 @@ export const validationModelMiddleware = (
forbidNonWhitelisted = true
): RequestHandler => {
return (req, res, next) => {
if (type === null && type == undefined) {
next();
return;
}
const model = plainToInstance(type, req[value]);
validate(model, { skipMissingProperties, whitelist, forbidNonWhitelisted }).then((errors: ValidationError[]) => {
if (errors.length > 0) {
const message = errors.map((error: ValidationError) => Object.values(error.constraints)).join(", ");

View file

@ -1,8 +1,11 @@
import { CrudController } from "../../core/controllers/crud_controller";
import { GetBehaviorTreeSkillsTemplatesUseCase } from "./get_bt_skills_templates_usecase";
import { GetBehaviorTreeSkillsTemplatesUseCase } from "./domain/get_bt_skills_templates_usecase";
import { BehaviorTreeValidationModel } from "./models/behavior_tree_validation_model";
import { BehaviorTreeDBModel } from "./models/behavior_tree_database_model";
import { ReadByIdDataBaseModelScenario } from "../../core/scenarios/read_by_id_database_model_scenario";
import { GetBehaviorTreeActiveProjectScenario } from "./domain/get_behavior_tree_active_project_scenario";
import { SaveBtScenario as FillBtScenario } from "./domain/save_bt_scenario";
export class BehaviorTreesPresentation extends CrudController<BehaviorTreeValidationModel, typeof BehaviorTreeDBModel> {
constructor() {
super({
@ -10,6 +13,12 @@ export class BehaviorTreesPresentation extends CrudController<BehaviorTreeValida
validationModel: BehaviorTreeValidationModel,
databaseModel: BehaviorTreeDBModel,
});
super.get(new GetBehaviorTreeActiveProjectScenario().call);
this.subRoutes.push({
method: "POST",
subUrl: "fill/tree",
fn: new FillBtScenario(),
});
this.subRoutes.push({ method: "GET", subUrl: "templates", fn: new GetBehaviorTreeSkillsTemplatesUseCase() });
this.subRoutes.push({
method: "GET",

View file

@ -0,0 +1,15 @@
import { CallbackStrategyWithEmpty, ResponseBase } from "../../../core/controllers/http_controller";
import { Result } from "../../../core/helpers/result";
import { SearchOneDataBaseModelUseCase } from "../../../core/usecases/search_database_model_usecase";
import { IProjectModel, ProjectDBModel } from "../../_projects/models/project_database_model";
import { BehaviorTreeDBModel } from "../models/behavior_tree_database_model";
export class GetBehaviorTreeActiveProjectScenario extends CallbackStrategyWithEmpty {
call = async (): ResponseBase =>
(
await new SearchOneDataBaseModelUseCase<IProjectModel>(ProjectDBModel).call(
{ isActive: true },
"no active projects"
)
).map(async (project) => Result.ok(await BehaviorTreeDBModel.find({ project: project._id })));
}

View file

@ -0,0 +1,44 @@
import { CallbackStrategyWithEmpty, ResponseBase } from "../../../core/controllers/http_controller";
import { Result } from "../../../core/helpers/result";
export class GetBehaviorTreeSkillsTemplatesUseCase extends CallbackStrategyWithEmpty {
call = async (): ResponseBase => {
return Result.ok({
skills: [
{
SkillPackage: { name: "Robossembler", version: "1.0", format: "1" },
Module: { name: "PoseEstimation", description: "Pose Estimation skill with DOPE" },
Launch: { package: "rbs_perception", executable: "pe_dope_lc.py", name: "lc_dope" },
BTAction: [
{
name: "peConfigure",
type: "run",
param: [
{
type: "weights",
dependency: {},
},
],
result: ["POSE"],
},
{ name: "peStop", type: "stop", param: [], result: [] },
],
Interface: {
Input: [
{ name: "cameraLink", type: "CAMERA" },
{ name: "object_name", type: "MODEL" },
],
Output: [{ name: "pose_estimation_topic", type: "POSE" }],
},
Settings: [
{ name: "cameraLink", value: "inner_rgbd_camera" },
{ name: "pose", value: "" },
{ name: "publishDelay", value: 0.5 },
{ name: "tf2_send_pose", value: 1 },
{ name: "mesh_scale", value: 0.001 },
],
},
],
});
};
}

View file

@ -0,0 +1,32 @@
import { CallbackStrategyWithValidationModel, ResponseBase } from "../../../core/controllers/http_controller";
import { CreateFileUseCase } from "../../../core/usecases/create_file_usecase";
import { CreateFolderUseCase } from "../../../core/usecases/create_folder_usecase";
import { SearchOneDataBaseModelUseCase } from "../../../core/usecases/search_database_model_usecase";
import { IProjectModel, ProjectDBModel } from "../../_projects/models/project_database_model";
import { FolderStructure } from "../../projects/domain/upload_file_to_to_project_scenario";
import { BehaviorTreeValidationModel } from "../models/behavior_tree_validation_model";
export class SaveBtScenario extends CallbackStrategyWithValidationModel<BehaviorTreeValidationModel> {
validationModel: BehaviorTreeValidationModel = new BehaviorTreeValidationModel();
call = async (model: BehaviorTreeValidationModel): ResponseBase =>
(
await new SearchOneDataBaseModelUseCase<IProjectModel>(ProjectDBModel).call(
{ isActive: true },
"no active projects"
)
).map(async (project) => {
const folder = `${project.rootDir}/${FolderStructure.behaviorTrees}/`;
(await new CreateFolderUseCase().call(folder)).map(async () =>
(await new CreateFolderUseCase().call(`${folder}${model.name}/`)).map(async () =>
(await new CreateFileUseCase().call(`${folder}${model.name}/bt.xml`, Buffer.from(model.xml))).map(
async () =>
await new CreateFileUseCase().call(
`${folder}${model.name}/skills.json`,
Buffer.from(JSON.stringify(model.skills))
)
)
)
);
});
}

View file

@ -1,98 +0,0 @@
import { CallbackStrategyWithEmpty, ResponseBase } from "../../core/controllers/http_controller";
import { Result } from "../../core/helpers/result";
export class GetBehaviorTreeSkillsTemplatesUseCase extends CallbackStrategyWithEmpty {
call = async (): ResponseBase => {
return Result.ok({
skills: [
{
SkillPackage: {
name: "Robossembler",
version: "1.0",
format: "1",
},
Module: {
name: "PoseEstimation",
description: "Pose Estimation skill with DOPE",
},
Launch: {
executable: "pe_dope_lc.py",
},
ROS2: {
node_name: "lc_dope",
},
BTAction: [
{
name: "peConfigure",
format: "yaml",
type: "run",
param: [
{
type: "weights",
dependency: {},
},
{
type: "form",
dependency: {},
},
],
result: ["POSE"],
},
{
name: "peStop",
format: "yaml",
type: "stop",
param: [],
result: [],
},
],
Interface: {
Input: [
{
name: "cameraLink",
type: "CAMERA",
},
{
name: "object_name",
type: "MODEL",
},
],
Output: [
{
name: "pose_estimation_topic",
type: "POSE",
},
],
},
Settings: [
{
name: "cameraLink",
value: "inner_rgbd_camera",
},
{
name: "pose",
value: "",
},
{
name: "publishDelay",
value: 0.5,
},
{
name: "tf2_send_pose",
value: 1,
},
{
name: "mesh_scale",
value: 0.001,
},
],
xxx: {
cameraLink: "inner_rgbd_camera",
topicImage: "/inner_rgbd_camera/image",
topicCameraInfo: "/inner_rgbd_camera/camera_info",
},
},
],
});
};
}

View file

@ -3,7 +3,7 @@ import { IProjectModel, projectSchema } from "../../_projects/models/project_dat
export interface IBehaviorTreeModel {
name: string;
project?: IProjectModel;
project?: IProjectModel | string;
unixTime?: number;
local_path?: string;
}
@ -26,6 +26,13 @@ export const BehaviorTreeSchema = new Schema({
dependency: {
type: Schema.Types.Mixed,
},
skills: {
type: Schema.Types.Mixed,
},
scene: {
type: Array,
default: null,
},
project: {
type: Schema.Types.ObjectId,
ref: projectSchema,

View file

@ -1,7 +1,11 @@
import { IsString } from "class-validator";
import { IsMongoId, IsString } from "class-validator";
import { IBehaviorTreeModel } from "./behavior_tree_database_model";
export class BehaviorTreeValidationModel implements IBehaviorTreeModel {
@IsString()
public name: string;
@IsMongoId()
public project:string;
public skills:any;
public xml:string;
}

View file

@ -16,7 +16,6 @@ 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}/`;
console.log(`blenderproc run $PYTHON_BLENDER_PROC --cfg '${JSON.stringify(model)}'`);
return new ExecProcessUseCase().call(
`${model.project.rootDir}/`,
`blenderproc run $PYTHON_BLENDER_PROC --cfg '${JSON.stringify(model)}'`,

View file

@ -13,6 +13,7 @@ export enum FolderStructure {
assets = "assets",
weights = "weights",
datasets = "datasets",
behaviorTrees = "behavior_trees",
}
export class UploadCadFileToProjectScenario extends CallbackStrategyWithFileUpload {
@ -30,9 +31,12 @@ export class UploadCadFileToProjectScenario extends CallbackStrategyWithFileUplo
""
)
).map(async () =>
(await new CreateManyFolderScenario().call(databaseModel.rootDir, Object.keys(FolderStructure).map((el) => `/${el}`))).map(() =>
Result.ok("file upload and save")
)
(
await new CreateManyFolderScenario().call(
databaseModel.rootDir,
Object.keys(FolderStructure).map((el) => `/${el}`)
)
).map(() => Result.ok("file upload and save"))
)
)
);

View file

@ -9,5 +9,4 @@ extensions();
const socketSubscribers = [new SocketSubscriber(executorProgramService, "realtime")];
new App(httpRoutes, socketSubscribers).listen();
new App(httpRoutes, socketSubscribers).listen();