Asked — Edited
Resolved Resolved by ptp!

How To Use Jd Head Follow Position For Face Detection In C#

Hello @ptp

I want to use head follow position in ur project as ARC in anther words when jd detect face his head follow that face I've tried to use tutorial 4 in sdk# but I couldn't reach my needs would u help me plz ?


ARC Pro

Upgrade to ARC Pro

Stay at the forefront of robot programming innovation with ARC Pro, ensuring your robot is always equipped with the latest advancements.

PRO
USA
#1  

The project code does not seem right.

I'll take better look later.

#2  

@ptp Hello , sorry for disturbance dear eng but is there any answer for my ques ?

PRO
USA
#3  

Sorry, long weekend due to public holiday.

main code logic:


private void HeadTracking()
{
	if (!this.headTrackingActive)
	{
		return;
	}

	var faceLocations = this.camera.CameraFaceDetection.GetFaceDetection();
	if (faceLocations.Length == 0)
	{
		return;
	}

	//Grab the first face location (ONLY ONE)
	var faceLocation = faceLocations.First();

	var servoVerticalPosition = this.ezb.Servo.GetServoPosition(HeadServoVerticalPort);
	var servoHorizontalPosition = this.ezb.Servo.GetServoPosition(HeadServoHorizontalPort);

	var yDiff = faceLocation.CenterY - CameraHeight / 2;
	if (Math.Abs(yDiff) > YDiffMargin)
	{
		if (yDiff < 0)
		{
			if (servoVerticalPosition - ServoStepValue >= this.mapPortToServoLimits[HeadServoVerticalPort].MinPosition)
			{
				servoVerticalPosition -= ServoStepValue;
			}
		}
		else
		{
			if (servoVerticalPosition + ServoStepValue <= this.mapPortToServoLimits[HeadServoVerticalPort].MaxPosition)
			{
				servoVerticalPosition += ServoStepValue;
			}
		}
	}

	var xDiff = faceLocation.CenterX - CameraWidth / 2;
	if (Math.Abs(xDiff) > XDiffMargin)
	{
		if (xDiff > 0)
		{
			if (servoHorizontalPosition - ServoStepValue >= this.mapPortToServoLimits[HeadServoHorizontalPort].MinPosition)
			{
				servoHorizontalPosition -= ServoStepValue;
			}
		}
		else
		{
			if (servoHorizontalPosition + ServoStepValue <= this.mapPortToServoLimits[HeadServoHorizontalPort].MaxPosition)
			{
				servoHorizontalPosition += ServoStepValue;
			}
		}
	}

	this.ezb.Servo.SetServoPosition(HeadServoVerticalPort, servoVerticalPosition);
	this.ezb.Servo.SetServoPosition(HeadServoHorizontalPort, servoHorizontalPosition);
}

full example: https://github.com/ppedro74/ez-robot-form-application

PRO
USA
#4  

*** Very important ***

while developing or playing with JD please pay attention to the JD's servos.

Check if they are not being pushed more than their physical limits.

ignoring this can lead to serious servo damages.

the following code defines the limits per servo:


public partial class Form1 : Form
{
	private struct ServoLimits
	{
		public readonly int MaxPosition;
		public readonly int CenterPosition;
		public readonly int MinPosition;

		public ServoLimits(int min, int max)
		{
			this.MinPosition = min;
			this.MaxPosition = max;
			this.CenterPosition = (max - min)/2 + min;
		}
	}

	private const Servo.ServoPortEnum HeadServoHorizontalPort = Servo.ServoPortEnum.D0;
	private const Servo.ServoPortEnum HeadServoVerticalPort = Servo.ServoPortEnum.D1;
	private const int CameraWidth = 320;
	private const int CameraHeight = 240;
	private const int ServoStepValue = 1;
	private const int YDiffMargin = CameraWidth/80;
	private const int XDiffMargin = CameraHeight/80;

	private readonly Dictionary<Servo.ServoPortEnum, ServoLimits> mapPortToServoLimits = new Dictionary<Servo.ServoPortEnum, ServoLimits>()
	{
		{Servo.ServoPortEnum.D0, new ServoLimits(5, 176)}, //Head Horizontal
		{Servo.ServoPortEnum.D1, new ServoLimits(70, 176)} //Head Vertical 
	};
..

is important to preset the head servos values before start tracking, otherwise their default positions are 0,0 below the allowed limits.


private void HeadTrackingButton_Click(object sender, EventArgs e)
{
	var button = (Button) sender;
	var labels = button.Tag.ToString().Split(new[] {'|'});

	if (this.headTrackingActive)
	{
		this.headTrackingActive = false;
		this.WriteDebug("Stopping Head Tracking." );
		button.Text = labels[0];
	}
	else
	{
		if (!this.camera.IsActive)
		{
			this.WriteDebug("Error: Please start the camera." );
		}
		else if (!this.ezb.IsConnected)
		{
			this.WriteDebug("Error: Please connect the EZB." );
		}
		else
		{
			//Note: assign servo values before start tracking
			this.ezb.Servo.SetServoPosition(HeadServoHorizontalPort, this.mapPortToServoLimits[HeadServoHorizontalPort].CenterPosition);
			this.ezb.Servo.SetServoPosition(HeadServoVerticalPort, this.mapPortToServoLimits[HeadServoVerticalPort].CenterPosition);

			this.headTrackingActive = true;
			this.WriteDebug("Starting Head Tracking." );
			button.Text = labels[1];
		}
	}
}