研究DiffCloth源代码

本文介绍了一种名为DiffCloth的项目,它是一种基于干摩擦接触的可微分布料模拟系统,通过git克隆和编译过程在Ubuntu上实现。文章详细描述了如何设置环境变量、编译代码,并介绍了可视化和优化功能,包括使用LBFGS优化器进行布料动画的训练过程。
摘要由CSDN通过智能技术生成

论文的标题是DiffCloth: Differentiable Cloth Simulation with Dry Frictional Contact。

在ubuntu操作系统上输入命令:

git clone --recursive https://github.com/omegaiota/DiffCloth.git

即可下载代码到当前目录。

然后输入以下命令:

cd DiffCloth
mkdir build
cd build
cmake ..
make

即可编译代码到DiffCloth/build中。

然后就可以去玩了,怎么玩呢?

运行程序之前需要设置一个临时的环境变量,输入命令:

export OMP_NUM_THREADS=1

也可以将其设置为其他数字,输入命令

echo $OMP_NUM_THREADS

即可显示该环境变量的值,该环境变量应该设置的是线程数。

设置好环境变量之后,切换到build目录下,输入命令

./DiffCloth -demo tshirt -mode visualize -exp tshirt-exampleopt/iter0/

可以看到一个t恤衫的动画。

还有hat, sock等,但是没有训练出来。如果要训练hat,可以输入命令:

./DiffCloth -demo hat -mode optimize -seed 1

-seed后面可以是任意值,训练其他的东西也同理。

在main函数中,会先查找在环境变量中设置的线程数,并赋值给局部变量n_threads。然后创建几个线程,OPENMP_ENABLED在程序中默认为true。接着跟据输入过的命令执行visualization或optimization。

先说visualization。如果执行的是这条命令:

./DiffCloth -demo tshirt -mode visualize -exp tshirt-exampleopt/iter0/

则会在DiffCloth/output/tshirt-exampleopt/iter0/中找到每一帧对应的obj模型文件,并播放成动画。

然后,第二大块是optimize部分,这一部分很复杂。这一部分主要在runBackwardTask(demo, true, std::atoi(randSeedStr));函数中,这个函数的定义是:

void runBackwardTask(int demoIdx, bool isRandom, int srandSeed)

参数demoIdx指的是这几个宏:

Demos::DEMO_WIND_TSHIRT
Demos::DEMO_WEAR_SOCK
Demos::DEMO_WEAR_HAT
Demos::DEMO_SPHERE_ROTATE
Demos::DEMO_DRESS_TWIRL

这是五个选项,分别表示运行t恤衫被风吹、穿袜子、戴帽子、旋转球,卷曲裙子这几个demo中的哪一个。

isRandom:是否使用随机数

srandSeed:随机数种子

这个函数中,首先设置场景初始化的一些参数,这些参数在initSceneProfile对象中。代码里用hatScene作为场景的初始化参数。initSceneProfile的类型是Simulation::SceneConfiguration结构体,该结构体的定义如下:

struct SceneConfiguration {
        FabricConfiguration fabric; // in SimulationConstant::fabricArrs
        Orientation orientation;
        Vec3d upVector;
        AttachmentConfigs attachmentPoints;
        std::vector<std::pair<double, std::vector<int>>> customAttachmentVertexIdx; // outside loop: different sets; each element: startFrame x vIdx
        TrajectoryConfigs trajectory;
        PrimitiveConfiguration primitiveConfig;
        WindConfig windConfig;
        Vec3d camPos;
        Vec3d camFocusPos;
        Vec3d sockLegOrientation;
        CameraFocusPointType camFocusPointType;
        AABB sceneBbox;
        double timeStep;
        int stepNum;
        double forwardConvergenceThresh;
        double backwardConvergenceThresh;
        std::string name;
    };

其中包括织物的材质信息、相机位置、朝向、风的属性、AABB包围盒的信息、时间步的间隔和步数等等信息。代码中对这些信息的设定如下:

Simulation::SceneConfiguration OptimizationTaskConfigurations::hatScene = {
        .fabric = agenthat579,
        .orientation =  Orientation::FRONT,
        .attachmentPoints =  AttachmentConfigs::CUSTOM_ARRAY,
        .customAttachmentVertexIdx = {{0.0, {394, 32}}},  //{{0.0, {501}}},
        .trajectory = TrajectoryConfigs::CORNERS_2_WEARHAT,
        .primitiveConfig = PrimitiveConfiguration::PLANE_BUST_WEARHAT,
        .windConfig = WindConfig::NO_WIND,
        .camPos = Vec3d(-22.14, 9.24, 7.59),
        .camFocusPointType =  CameraFocusPointType::CLOTH_CENTER,
        .sceneBbox =  AABB(Vec3d(-5, -1.5, -14), Vec3d(7, 10, 5)),
        .timeStep = 1.0 / 100.0,
        .stepNum = 400,
        .forwardConvergenceThresh = 1e-8,
        .backwardConvergenceThresh = 5e-4,
        .name = "demo_wearhat"

};

其中agenthat579内容如下:

Simulation::FabricConfiguration OptimizationTaskConfigurations::agenthat579 = {
        .clothDimX = 6,
        .clothDimY = 6,
        .k_stiff_stretching = 1200, // old param: 300 // TODO: WARNING: change back to 1200
        .k_stiff_bending = 120, // old param: 50 // TODO: WARNING: change back to 120
        .gridNumX = 40, //
        .gridNumY = 80, //
        .density = 0.224, // old param: 0.324
        .keepOriginalScalePoint = false,
        .isModel = true,
        .custominitPos = false,
        .fabricIdx = FabricEnumArray::AGENT_HAT579,
        .color = Vec3d(1, 0, 0),
        .name =  "remeshed/agenthat2-579-rotated.obj",
};

大概是布料的劲度系数、颜色、对应的obj文件路径等一些信息。clothDim、gridNum这些不太理解是干嘛的。

接下来是这一行:

Simulation *clothSystem = Simulation::createSystem(
                                                     initSceneProfile,
                                                     Vec3d(0, 0, 0), true);

创建了一个Simulation类的对象,并用一个指针指向该对象。Simulation是一个巨大无比的类,里面的成员声明在Simulation.h中占了约一千多行,看着很头疼,干脆不看了。

那么这一行应该是跟据前面初始化的场景对象initSceneProfile创建了一个Simulation对象,其指针叫做clothSystem,并给该对象设置好中心点坐标为Vec3d(0,0,0),并且确定要使用反向传播算法,也就是最后一个参数为true.

然后就用这个设定好的clothSystem开始训练:

BackwardTaskSolver::solveDemo(clothSystem, [&](const std::string &v) {}, demoIdx, isRandom,
                                srandSeed);

这个函数的形参是这样的:

void BackwardTaskSolver::solveDemo(Simulation *system, const std::function<void(const std::string &)> &setTextBoxCB,
                                   int demoNum, bool isRandom, int srandSeed)

这里面用到一个优化器叫LBFGS,虽然不太懂,但是肯定和SGD差不多。

OptimizeHelper是什么东东?也是一个大类但是没有Simulation大,其声明有100多行。里面似乎是记录梯度信息、误差等一些东西。

设定好helper和优化器后,接下来就是下面这一行:

optimizeLBFGS(system,helper, system->sceneConfig.stepNum, demoNum, isRandom, srandSeed, setTextBoxCB);

如何在vscode上调试这个东西

在vscode左边可以看到项目的目录,其中vscode生成了一个.vscode文件夹,里面有launch.json和tasks.json。tasks.json可以设置如何编译这个项目,launch.json可以设置用什么命令去运行这个项目。编写tasks.json如下:

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: gcc build active file",
            "command": "cd build && cmake .. && make",
            "args": [
            ],
            "options": {
                "cwd": "${workspaceFolder}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "Task generated by Debugger."
        }
    ],
    "version": "2.0.0"
}

其中command命令是创建build目录并且编译的命令。

然后编写launch.json文件如下:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "C/C++: gcc build and debug active file",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/DiffCloth",
            "args": ["-demo", "hat", "-mode", "optimize", "-seed", "1"],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}/build/",
            "environment": [{"name": "OMP_NUM_THREADS", "value": "8"}],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Set Disassembly Flavor to Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "C/C++: gcc build active file",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

这个文件设定了OMP_NUM_THREADS环境变量,和运行程序的命令。

然后在CMakeLists.txt中把MAKE_BUILD_TYPE改成Debug:

最后,打断点,在上方菜单的Run中点击start Debugging即可调试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值