Files
HDRobotics/Assets/Scripts/Model/RobotMoveStep.cs
2025-11-13 21:23:28 +09:00

144 lines
4.7 KiB
C#

using System.Text.RegularExpressions;
using UnityEngine;
public class RobotMoveStep
{
public string FullLine { get; private set; }
public RobotPose Pose { get; private set; }
public int StepNumber { get; private set; }
public int Speed { get; private set; }
public int Accu { get; private set; }
public int Tool { get; private set; }
/// <summary>
/// 좌표를 제외한 이동 명령 (예: "move P,spd=50%,accu=3,tool=1")
/// </summary>
public string MoveCommand { get; private set; }
// Regex로 S<번호>와 move <명령> [좌표]를 분리
// 그룹 1: (S([0-9]+)) -> "S1", "1"
// 그룹 3: (move.*?) -> "move P,spd=50%,accu=3,tool=1"
private static readonly Regex StepRegex = new Regex(@"^(S([0-9]+))\s+(move.*?)(\s+\[.*\])", RegexOptions.Compiled);
private static readonly Regex SpeedRegex = new Regex(@"spd=([0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex AccuRegex = new Regex(@"accu=([0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex ToolRegex = new Regex(@"tool=([0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public RobotMoveStep(string line, string coordString)
{
this.FullLine = line;
string[] values = coordString.Split(',');
if (values.Length >= 6)
{
this.Pose = new RobotPose(
float.Parse(values[0]), float.Parse(values[1]), float.Parse(values[2]),
float.Parse(values[3]), float.Parse(values[4]), float.Parse(values[5])
);
}
else
{
Debug.LogError($"좌표 파싱 실패: {coordString}");
this.Pose = new RobotPose(0, 0, 0, 0, 0, 0);
}
Match match = StepRegex.Match(line);
if (match.Success)
{
this.StepNumber = int.Parse(match.Groups[2].Value);
this.MoveCommand = match.Groups[3].Value.Trim();
Match speedMatch = SpeedRegex.Match(this.MoveCommand);
Match accuMatch = AccuRegex.Match(this.MoveCommand);
Match toolMatch = ToolRegex.Match(this.MoveCommand);
if (speedMatch.Success)
this.Speed = int.Parse(speedMatch.Groups[1].Value);
else
Debug.LogWarning($"'spd='를 찾을 수 없음: {this.MoveCommand}");
if (accuMatch.Success)
this.Accu = int.Parse(accuMatch.Groups[1].Value);
else
Debug.LogWarning($"'accu='를 찾을 수 없음: {this.MoveCommand}");
if (toolMatch.Success)
this.Tool = int.Parse(toolMatch.Groups[1].Value);
else
Debug.LogWarning($"'tool='을 찾을 수 없음: {this.MoveCommand}");
}
else
{
Debug.LogError($"스텝 라인 파싱 실패: {line}");
this.StepNumber = -1;
this.MoveCommand = "move P,spd=50%,accu=3,tool=0"; // 기본값
this.Speed = 50; // 기본값
}
}
/// <summary>
/// DeleteStep 시, S<번호>를 업데이트하기 위한 헬퍼 함수
/// </summary>
public void UpdateStepNumber(int newStepNumber, string newMoveCommand = null)
{
this.StepNumber = newStepNumber;
if (newMoveCommand != null)
{
this.MoveCommand = newMoveCommand;
}
// FullLine을 새 번호와 Pose로 다시 조립
this.FullLine = $"S{this.StepNumber} {this.MoveCommand} {this.Pose.ToString()}";
}
/// <summary>
/// UpdateStep 시, Pose를 업데이트하기 위한 헬퍼 함수
/// </summary>
public void UpdatePose(RobotPose newPose)
{
this.Pose = newPose;
// FullLine을 새 Pose로 다시 조립
this.FullLine = $"S{this.StepNumber} {this.MoveCommand} {this.Pose.ToString()}";
}
}
public class RobotPose
{
public float x, y, z, rx, ry, rz;
public RobotPose(float x, float y, float z, float rx, float ry, float rz)
{
this.x = x; this.y = y; this.z = z;
this.rx = rx; this.ry = ry; this.rz = rz;
}
/// <summary>
/// RobotData(Model)를 RobotPose(Program)로 변환
/// </summary>
public RobotPose(RobotData data)
{
this.x = data.x; this.y = data.y; this.z = data.z;
this.rx = data.rx; this.ry = data.ry; this.rz = data.rz;
}
/// <summary>
/// RobotPose(Program)를 RobotData(Model)로 변환
/// </summary>
public RobotData ToRobotData()
{
return new RobotData
{
x = this.x,
y = this.y,
z = this.z,
rx = this.rx,
ry = this.ry,
rz = this.rz
};
}
/// <summary>
/// API에서 요구하는 좌표 문자열 형식으로 변환
/// </summary>
public override string ToString()
{
return $"[{x},{y},{z},{rx},{ry},{rz},\"robot\"]";
}
}