为什么我的伺服电机按以下代码不动?

问题描述 投票:0回答:1

我正在尝试使用unity和arduino之间的串行连接来控制两个伺服电机。

但是,我注意到,虽然arduino代码可以工作,并且当我尝试发送时,我可以根据“逆时针”,“顺时针”,“逆时针关节2”和“顺时针关节2”命令独立为伺服电机供电在一个更新循环中向串行监视器发出两个命令,我的伺服器都没有移动。

以下是arduino代码:


`#include <Servo.h> // servo library

String input;
int count;
int countSecond;
int rotationAngleStep;

Servo servo1; // servo control object
Servo servo2;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  servo1.attach(13);
  servo1.write(0);
  servo2.attach(10);
  servo2.write(0);
  count = 0;
  countSecond = 0;
  rotationAngleStep = 10;
}

void loop() 
{
  input = Serial.readString();
  Serial.print(input);
      
  if(input == "anticlockwise")
  {
    Serial.println("turn motor");
    count = count + 1;
    servo1.write(count*rotationAngleStep);  
   }

  if(input == "clockwise")
  {
    Serial.println("turn motor");
    if(count > 0)
    {
    count = count - 1;
    servo1.write(count*rotationAngleStep);
    }   
  }


    if(input == "anticlockwise joint 2")
  {
    Serial.println("turn motor");
    countSecond = countSecond + 1;
    servo2.write(countSecond*rotationAngleStep);
   }

    if(input == "clockwise joint 2")
  {
    Serial.println("turn motor");
    if(countSecond > 0)
    {
    countSecond = countSecond - 1;
    servo2.write(countSecond*rotationAngleStep);
    }   
  }

  delay(1000);


}
    
    //}if(data == 'servo1'){
      //servo1.write(10);
    //}if(data == 'servo2'){
      //servo2.write(10);
    
 `

以下是统一代码:

``using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using Unity.VisualScripting;
using UnityEngine;
using System.IO.Ports;

public class IKManager : MonoBehaviour
{


    public SerialPort serial = new SerialPort("COM4",9600);
    //basically want to evaluate how close we are to target by assessing end effector value in the y dimension, against target value in the y dimension.
    //by evaluating distance between two iterative frames (and attaining a slope value) can tell if moving further or closer to end effector. Gradient descent.

    //root of the armature
    public Joint m_root;

    //End effector
    public Joint m_end;

    public GameObject m_target;

    public float m_threshold = 20f;

    public float m_rate = 1.0f;

    private int counter = 2;

    private float timer;

    private float slope1;
    private float slope2;

    private float intermediary;

    void Start(){
        if(serial.IsOpen == false){
            serial.Open();
        }

        serial.Write("hey");
    }

    // Calculate slope - i.e distance between points divided by step (delta theta)
    float CalculateSlope(Joint _joint)
    {
        float deltaTheta = 10f;
        float distance1 = GetDistance(m_end.transform.position, m_target.transform.position);

        _joint.transform.Rotate(0f,0f,deltaTheta,Space.World);

        float distance2 = GetDistance(m_end.transform.position, m_target.transform.position);

        _joint.transform.Rotate(0f,0f,-deltaTheta,Space.World);

        return (distance2 - distance1) / deltaTheta;

    }

    async void Update()
    {
        timer = Time.realtimeSinceStartup;
        //Debug.Log(timer);
        //Debug.Log("counter " + counter);
        if (timer > 4*counter)
        {
            Debug.Log("can move now");
            counter = counter + 1;
            Debug.Log(counter);
            if (GetDistance(m_end.transform.position, m_target.transform.position) > m_threshold)
            {
                Joint current = m_root;
                float slope1 = CalculateSlope(current);
                if (slope1 > 0){
                    current.transform.Rotate(0f,0f,-10f,Space.World);
                    serial.Write("clockwise");
                    Debug.Log("clockwise");
                }if(slope1 < 0){
                    current.transform.Rotate(0f,0f,10f,Space.World);
                    serial.Write("anticlockwise");
                    Debug.Log("anticlockwise");                             
                }
                //Debug.Log("Slope " + slope);
                
                //Debug.Log("Move Servo");

                current = current.GetChild();
                slope2 = CalculateSlope(current);
                if (slope2 > 0){
                    current.transform.Rotate(0f,0f,-10f,Space.World);
                    //serial.Write("clockwise joint 2");
                    Debug.Log("clockwise joint 2");
                }if(slope2 < 0){
                    current.transform.Rotate(0f,0f,10f,Space.World);
                    //serial.Write("anticlockwise joint 2");
                    Debug.Log("anticlockwise joint 2");                               
                }
                //Debug.Log("Slope " + slope);




                
                // if(slope != 0){
                //     serial.Write("servo2");
                // }else{
                //     serial.Write("no change");
                // } 
                // serial.Close() ;
            
            }
        }
        
    }
    float GetDistance(Vector3 _point1, Vector3 _point2)
    {
        return Vector3.Distance(_point1, _point2);
    }

}`

我认为这是因为信号可能在同一行上注册,但后来我在arduino中的serial.read()函数之后引入了延迟,并且遇到了同样的问题。任何帮助将不胜感激。

c# unity-game-engine arduino robotics servo
1个回答
0
投票

您需要更新您的 Arduino 循环

来自文档

Serial.readString() 将字符从串行缓冲区读取到字符串中。如果超时,函数将终止(请参阅 setTimeout())。

void loop() {
  while (Serial.available() == 0) {}   // wait for data available
  input = Serial.readString();         // read until timeout
  input.trim();                        // remove any \r \n whitespace at the end of the String
  Serial.print(input);

  if (input == "anticlockwise") {
    Serial.println("turn motor");
    count = count + 1;
    servo1.write(count * rotationAngleStep);
  }

  if (input == "clockwise") {
    Serial.println("turn motor");
    if (count > 0) {
      count = count - 1;
      servo1.write(count * rotationAngleStep);
    }
  }
  if (input == "anticlockwise joint 2") {
    Serial.println("turn motor");
    countSecond = countSecond + 1;
    servo2.write(countSecond * rotationAngleStep);
  }

  if (input == "clockwise joint 2") {
    Serial.println("turn motor");
    if (countSecond > 0) {
      countSecond = countSecond - 1;
      servo2.write(countSecond * rotationAngleStep);
    }
  }
  delay(1000);
}
© www.soinside.com 2019 - 2024. All rights reserved.