首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何模拟一组物体的直线运动

如何模拟一组物体的直线运动
EN

Stack Overflow用户
提问于 2022-09-25 18:46:18
回答 1查看 233关注 0票数 0

我的目标是动画一个线性抓取运动(挑选/位置),这里是一个码箱来重现我的问题:

  1. 夹持器被创建,它开始向下移动,直到它到达乐高砖,然后它停止。
代码语言:javascript
复制
const grip_pos = new Vector3(
    pick_pos.x,
    pick_pos.y,
    pick_pos.z + 5
);
createGripper(grip_pos, this.scene);
console.log(this.scene.getObjectByName("gripper", true));
const gripper = this.scene.getObjectByName("gripper", true);
// Down
while (gripper.position.y > (pick_pos.z / 0.48)) {
    gripper.position.y -= 0.1;
};
  1. 夹持器连接到乐高,它拿起它,并移动到上方的位置。
代码语言:javascript
复制
gripper.add(lego);
    
    // if Down then Up
    if (!gripper.position.y > pick_pos.z / 0.48) {
      while (gripper.position.y < grip_pos) {
        gripper.position.y += step;
      }
      
      if (pick_rot) {
        gripper.rotateY(Math.PI / 2);
      }
    }

    // Move to Place Position
    while (gripper.position.x > place_pos.y / 0.8 + 9.2) {
      gripper.position.x -= step;
    }
    while (gripper.position.x < place_pos.y / 0.8 + 9.2) {
      gripper.position.x += step;
    }

    while (gripper.position.z > place_pos.x / 0.8 + 2.8) {
      gripper.position.z -= step;
    }
    while (gripper.position.z < place_pos.x / 0.8 + 2.8) {
      gripper.position.z += step;
    }
  1. 夹持器移动到位置位置,到达位置位置,然后分离乐高,向上移动,然后消失。
代码语言:javascript
复制
// Place Down
if (
  gripper.position.x === place_pos.y &&
  gripper.position.z === place_pos.x
) {
  while (gripper.position.y > pick_pos.z / 0.48) {
    gripper.position.y -= step;
  }
}
if (place_rot) {
  gripper.rotateY(Math.PI / 2);
}

this.scene.add(lego);
this.scene.remove(gripper);
this.renderer.render(this.scene, this.camera);
cancelAnimationFrame(id);

要做到这一点,我有创造了我的夹子,并试图移动它之前解释。但是我看不到任何运动,而且,我的浏览器被卡住了,没有任何错误!你能指导我如何实现直线运动吗?提前谢谢。

请注意,位置上有一个转换,因为我使用两个坐标框架xyz,具有平移和缩放的zyx

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-02 07:37:33

解决方案是避免将参数传递给动画函数,因为每个requestAnimationFrame都将调用它,

代码语言:javascript
复制
export class PickPlace {
    /***********************************************************
     * 
     * @param {*} renderer 
     * @param {*} scene 
     * @param {*} camera 
     * @param {*} lego 
     * @param {*} place_position 
     * @param {*} place_rotation 
     ***********************************************************/
    constructor(renderer, scene, camera, lego,
        place_position, place_rotation = false) {
        //
        this.renderer = renderer;
        this.scene = scene;
        this.camera = camera;
        //
        this.lego = this.scene.getObjectByName(lego);
        //
        this.pick_position = new Vector3(
            Number((Math.round( ((this.lego.position.z + 2.8) / 0.8) * 100) / 100).toFixed(1)),
            Number((Math.round( ((this.lego.position.x + 9.2) / 0.8) * 100) / 100).toFixed(1)),
            Number((Math.round( (this.lego.position.y/0.48 - 0.01)   * 100) / 100).toFixed(1))
        );
        this.place_position = place_position
        this.place_rotation = place_rotation;
        this.step = 0.05;
        this.motion_down = true;
        this.planar_motion = false;
        this.x_lock = 0;
        this.z_lock = 0;
        this.pick();
    };

    pick = () => {
        /* grip_pos in units, 
        * createGripper() function does the conversion unit => mm
        */
        this.grip_pos = new Vector3(
            this.pick_position.x,
            this.pick_position.y,
            this.pick_position.z + 5);

        /* Create the gripper,
        * (scene.add(gripper)) is done internally.
        */
        createGripper(this.scene, this.grip_pos);
        this.gripper = this.scene.getObjectByName("gripper");

        if (!this.lego.userData.rotation) {
            this.gripper.rotateY(-Math.PI / 2);
        };
    };

    place = () => {
        if (this.place_rotation) {
            this.gripper.rotateY(-Math.PI / 2);
            if (this.lego.userData.size == 6 && this.lego.userData.rotation) {
                this.lego.translateX(-1.6);
            }
        };
    };

    animatePickPlace = () => {
        const tolerance = 1.1 * this.step;
        let frame_id = requestAnimationFrame(this.animatePickPlace);

        if ((this.gripper.position.y > this.lego.position.y + 0.04)
            && this.motion_down && !this.planar_motion) {

            this.gripper.position.y -= this.step;
        }
        else {
            if (this.motion_down) {
                this.gripper.add(this.lego);
                this.lego.rotateY(Math.PI / 2);
                // 2x2
                if (this.lego.userData.size === 2) {
                    if (this.lego.userData.rotation) {
                        this.lego.position.x += 9.2 - this.pick_position.y * 0.8;
                        this.lego.position.z += 2.8 - this.pick_position.x * 0.8;
                        this.lego.position.y -= this.pick_position.z * 0.48;
                    }
                    else {
                        this.lego.position.z += 2.8 - this.pick_position.y * 0.8;
                        this.lego.position.x += 9.2 - this.pick_position.x * 0.8;
                        this.lego.position.y -= this.pick_position.z * 0.48;
                    }
                }
                // 2x4
                else if (this.lego.userData.size === 4) {
                    if (this.lego.userData.rotation) {
                        this.lego.rotateY(Math.PI / 2);
                        this.lego.position.x += 9.2 - this.pick_position.y * 0.8;
                        this.lego.position.z += 2.0 - this.pick_position.x * 0.8;
                        this.lego.position.y -= this.pick_position.z * 0.48;
                    }
                    else {
                        this.lego.position.x += 9.2 - this.pick_position.y * 0.8;
                        this.lego.position.z += 2.8 - this.pick_position.x * 0.8;
                        this.lego.position.y -= this.pick_position.z * 0.48;
                    }
                }
                // 2x6
                else {
                    if (this.lego.userData.rotation) {
                        this.lego.rotateY(Math.PI / 2);
                        this.lego.position.x += 9.2 - this.pick_position.y * 0.8;
                        this.lego.position.z += 1.2 - this.pick_position.x * 0.8;
                        this.lego.position.y -= this.pick_position.z * 0.48;
                    }
                    else {
                        this.lego.position.z += 2.8 - this.pick_position.y * 0.8;
                        this.lego.position.x += 9.2 - this.pick_position.x * 0.8;
                        this.lego.position.y -= this.pick_position.z * 0.48;
                    }
                }
                this.motion_down = false;
            }
            if (this.gripper.position.y < this.grip_pos.z
                && !this.planar_motion) {
                this.gripper.position.y += this.step;
                if (this.gripper.position.y >= this.grip_pos.z) {
                    this.planar_motion = true;
                };
            }
            //
            if ((this.gripper.position.y >= this.grip_pos.z)
                && !this.motion_down && this.planar_motion) {

                let x_diff = this.gripper.position.x - (this.place_position.y * 0.8 - 9.2);
                let z_diff = this.gripper.position.z - (this.place_position.x * 0.8 - 2.8);

                if ((x_diff > tolerance) && this.x_lock !== 2) {
                    this.x_lock = 1;
                    this.gripper.position.x -= this.step;
                }
                else if ((x_diff < tolerance) && this.x_lock !== 1) {
                    this.x_lock = 2;
                    this.gripper.position.x += this.step;
                }
                else if ((z_diff > tolerance) && this.z_lock !== 2) {
                    this.z_lock = 1;
                    this.gripper.position.z -= this.step;
                }
                else if ((z_diff < tolerance) && this.z_lock !== 1) {
                    this.z_lock = 2;
                    this.gripper.position.z += this.step;
                }
                else {
                    cancelAnimationFrame(frame_id);
                    this.place();
                    this.animatePlace();
                }
            }
        }

        this.renderer.render(this.scene, this.camera);
    };

    animatePlace = () => {
        this.planar_motion = false;
        let frame_id = requestAnimationFrame(this.animatePlace);
        /** TODO: to handle placing rotation */
        if ((this.gripper.position.y > (this.place_position.z * 0.48))
            && !this.motion_down) {

            this.gripper.position.y -= this.step;
        }
        else {
            this.motion_down = true;
            this.scene.add(this.lego);
                /* Position World Unit to mm conversion.*/
                this.lego.position.set(
                    this.place_position.y * 0.8 - 9.2,
                    this.place_position.z * 0.48,
                    this.place_position.x * 0.8 - 2.8
                )
            /** TODO: Move gripper up and make it vanish gradually */
            this.scene.remove(this.gripper);
            cancelAnimationFrame(frame_id);
            /********************************* 
             * Place Translation/Orientation *
             *********************************/
            if (this.lego.userData.size == 4) {
                if (this.place_rotation) { 
                    if (this.lego.userData.rotation) {
                        this.lego.rotateY(Math.PI / 2);
                    }
                    else { 
                        this.lego.translateX(-0.8);
                    }
                }
                else { 
                    if (this.lego.userData.rotation) {
                        // Do Nothing
                    }
                    else { 
                        this.lego.rotateY(Math.PI / 2);
                        this.lego.translateX(-0.8);
                    }
                }
            }
            else if (this.lego.userData.size == 6) { 
                if (this.place_rotation) { 
                    if (this.lego.userData.rotation) {
                        this.lego.rotateY(Math.PI / 2);
                    }
                    else { 
                        this.lego.translateX(-1.6);
                    }
                }
                else { 
                    if (this.lego.userData.rotation) {
                        // Do Nothing
                    }
                    else { 
                        this.lego.rotateY(Math.PI / 2);
                        this.lego.translateX(-1.6);
                    }
                }
            }
        }
    };
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73847040

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档