How do i get skeleton data - kinect

Sorry for my poor English.
I am a student want to finish my project.
I am trying to use kinect 360 with WPF to get skeleton Joint's data frame by frame ,but I don't know how, please help me.
I've tryed this:
long setTime = currentTimeStamp;
int i = 0;
while (currentTimeStamp <= setTime + 150) {
foreach (Skeleton skeleton in skeletons) {
this.DataSave(skeleton, JointType.Head, i);
}
i++;
}
I k now that in pykinect I can do it with
frame = kinect.skeleton_engine.get_next_frame()
but how do i do the same thing in wpf?

Related

Best way to do object collision?

I'm trying to do wall collision for objects and I've followed a tutorial that offers one method of doing collision.
This is the tutorial: https://www.youtube.com/watch?v=yZU1QJJdxgs
Currently, if the object detects a wall, instead of moving it's full distance, it moves pixel by pixel until it's against the wall. This worked well until I started trying to rotate the object with image_rotate, because it caused objects to get stuck in walls by either sliding against them or if they rotated into them.
I fixed this by using draw_sprite_ext instead and changing the rotation of the sprite itself and not the mask, which worked for about 20 minutes until it started causing more problems.
///obj_player Step
//Initialise Variables
hor_speed = 0;
ver_speed = 0;
accelerationspeed = 0.2;
decelerationspeed = 0.2;
maxspeed = 3;
pointdirection = 0;
//Get player's input
key_right = keyboard_check(ord("D"))
key_left = -keyboard_check(ord("A"))
key_up = -keyboard_check(ord("W"))
key_down = keyboard_check(ord("S"))
pointdirection = point_direction(x,y,mouse_x,mouse_y) + 270
hor_movement = key_left + key_right;
ver_movement = key_up + key_down;
//horizontal acceleration
if !(abs(hor_speed) >= maxspeed) {
hor_speed += hor_movement * accelerationspeed;
}
//horizontal deceleration
if (hor_movement = 0) {
if !(hor_speed = 0) {
hor_speed -= (sign(hor_speed) * decelerationspeed)
}
}
//vertical acceleration
if !(abs(ver_speed) >= maxspeed) {
ver_speed += ver_movement * accelerationspeed;
}
//vertical deceleration
if (ver_movement = 0) {
if !(ver_speed = 0) {
ver_speed -= (sign(ver_speed) * decelerationspeed)
}
}
//horizontal collision
if (place_meeting(x+hor_speed,y,obj_wall)) {
while(!place_meeting(x+sign(hor_speed),y,obj_wall)) {
x += sign(hor_speed);
}
hor_speed = 0;
}
//vertical collision
if (place_meeting(x,y+ver_speed,obj_wall)) {
while(!place_meeting(x,y+sign(ver_speed),obj_wall)) {
y += sign(ver_speed);
}
ver_speed = 0;
}
//move the player
x += hor_speed;
y += ver_speed;
///obj_player Draw
//rotate to look at cursor
draw_sprite_ext(spr_player, 0, x,y,image_xscale,image_yscale, pointdirection, image_blend, image_alpha);
I think the best way to rotate objects is through image_rotate, and I'd like to do it without getting stuff stuck in walls. Can my current method of collision be adapted to do this, or should I attempt to do it in a different way?
Your code looks fine, but if you're going to be rotating objects then you would also need to consider having a "knock back mechanic." Reason being is the player could be sitting next to this wall and if you rotate the object over them so they cant move, its not a fun time being stuck.
So you 'could' have the object that's rotating do a check before rotating and if objects are in the way then either stop it or push them back so they cant be within range.

game maker GML twin stick shooter analogue controller

I am trying to make a twin stick shooter but I cannot get right analogue stick to shoot in the correct direction. Here is the code I have the weapon sits on top of the player and rotates. It all works fine just need to know how to get the correct angle of the right stick and fire a bullet in that direction.
//set depth
depth = -y + obj_player.y_off_set - 1;
//analog left stick face direction
var h_point = gamepad_axis_value(0, gp_axisrh);
var v_point = gamepad_axis_value(0, gp_axisrv);
if ((h_point != 0) || (v_point != 0))
{
var pdir = point_direction(0, 0, h_point, v_point);
var dif = angle_difference(pdir, image_angle);
image_angle += median(-20, dif, 20);
}
//flips gun when turning
if(gamepad_axis_value(0, gp_axisrh) < -0.5)
{
image_yscale = -1;
}else if (gamepad_axis_value(0, gp_axisrh) > 0.5)
{
image_yscale = 1;
}
//fireing
fire = gamepad_button_check_pressed(0, gp_shoulderr) && alarm[0] <= 0;
if(fire)
{
var face = point_direction(0, 0, gp_axisrh, gp_axisrv);
var p = instance_create(x, y, obj_projectile);
var xforce = lengthdir_x(20, face*90);
var yforce = lengthdir_x(20, face*90);
p.creator = id;
with (p){
physics_apply_impulse(x, y, xforce, yforce);
}
as this question is a couple months old, I imagine you found the solution to your problem, but hopefully this answer can help anyone else stuck on the issue.
Based on the code snippet you provided, it looks like if you remove the *90 from the lengthdir_ functions, your code should work.
Here is the code I wrote in my game to get 360 degree shooting working with the right analog stick (this code lives in the step event of the Player object):
if (shooting) {
bullet = instance_create(x, y, Bullet);
with (bullet) {
haxis = gamepad_axis_value(0, gp_axisrh);
vaxis = gamepad_axis_value(0, gp_axisrv);
dir = point_direction(0, 0, haxis, vaxis);
physics_apply_impulse(x, y, lengthdir_x(50, gp_axisrh), lengthdir_y(50, dir));
}
}
This particular thread on the GameMaker community forums was quite helpful as I researched how to solve this issue in my game.

Windows Store App: set an image as a background for an UI element

Sorry for asking a really basic question, but it's probably the first time for a number of years I feel really confused.
Windows provides two set of controls: Windows.UI.Xaml namespace (I thinks this is referred as Metro), used for Windows Store Apps, and System.Windows (WPF) for Desktop.
Since I am going to develop Windows Store Apps mainly for Windows 8.1 and Windows 10 phones, I will have to stick to Windows.UI.Xaml, and this has not only a separate set of UI elements, but also separate set of bitmaps, brushes, etc. (Windows.UI.Xaml.Media vs System.Windows.Media).
I found that Windows.UI.Xaml provides a very limited support for graphics, much less than provided by WPF, Android or (even!) iOS platform. To start with, I got stuck with a simple task: tiling a background!
Since Windows.UI.Xaml.Media.ImageBrush do not support tiling, I wanted to to do that "manually". Some sites suggest making numerous number of children, each holding a tile. Honestly, it looks as a rather awkward approach to me, so I decided to do it in what appears a more natural way: create an off-screen tiled image, assign it to a brush and assign the brush as the background for a panel.
The tiling code is rather straightforward (it probably has mistakes, possibly won't even not run on a phone, because of some unavailable classes used).
int panelWidth = (int) contentPanel.Width;
int panelHeight = (int) contentPanel.Height;
Bitmap bmpOffscreen = new Bitmap(panelWidth, panelHeight);
Graphics gOffscreen = Graphics.FromImage(bmpOffscreen);
string bmpPath = Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, "Assets/just_a_tile.png");
System.Drawing.Image tile = System.Drawing.Image.FromFile(bmpPath, true);
int tileWidth = tile.Width;
int tileHeight = tile.Height;
for (int y = 0; y < panelHeight; y += tileHeight)
for (int x = 0; x < panelWidth; x += tileWidth)
gOffscreen.DrawImage(tile, x, y);
Now I presumably have the tiled image in bmpOffscreen. But how assign it to a brush? To do that I need to convert Bitmap to BitmapSource, while I couldn't find something similar to System.Windows.Imaging.CreateBitmapSourceFromHBitmap available for WPF structure!
Well, first of all System.Drawing namespace is not available in Windows Universal Platform, so you won't be able to use Bitmap class
But, all hope is not lost - you can use
Windows.UI.Xaml.Media.Imaging.WriteableBitmap
If you look at example included on this page, you will see that at one point image data is extracted to a byte array - all you need to do is copy it according to your needs
Please let me know if you want me to include a complete code sample.
Edit:
StorageFile file = await StorageFile.GetFileFromPathAsync(filePath);
Scenario4WriteableBitmap = new WriteableBitmap(2000, 2000);
// Ensure a file was selected
if (file != null)
{
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
int columns = 4;
int rows = 4;
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
// Scale image to appropriate size
BitmapTransform transform = new BitmapTransform()
{
ScaledHeight = Convert.ToUInt32(Scenario4ImageContainer.Height),
ScaledWidth = Convert.ToUInt32(Scenario4ImageContainer.Width)
};
PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format
BitmapAlphaMode.Straight,
transform,
ExifOrientationMode.IgnoreExifOrientation, // This sample ignores Exif orientation
ColorManagementMode.DoNotColorManage);
// An array containing the decoded image data, which could be modified before being displayed
byte[] sourcePixels = pixelData.DetachPixelData();
// Open a stream to copy the image contents to the WriteableBitmap's pixel buffer
using (Stream stream = Scenario4WriteableBitmap.PixelBuffer.AsStream())
{
for (int i = 0; i < columns * rows; i++)
{
await stream.WriteAsync(sourcePixels, 0, sourcePixels.Length);
}
}
}
// Redraw the WriteableBitmap
Scenario4WriteableBitmap.Invalidate();
Scenario4Image.Source = Scenario4WriteableBitmap;
Scenario4Image.Stretch = Stretch.None;
}
Thank you, Arkadiusz. Since Australian time goes slightly ahead of Europe,
I had an advantage and seen the code before you posted it. I downloaded
MSDN XAML images sample and it helped me a lot. I gave a +1 to you but someone apparently put -1, so it compensated each other. Don't be upset I get -1 so often, that I stopped paying attention on that :)
So I've managed to do tiling with Windows Universal Platform! On my Lumia 532 phone it works magnifique. I felt like re-inventing a wheel, because all this stuff must be handled by SDK, not by a third-party developer.
public static async Task<bool> setupTiledBackground(Panel panel, string tilePath)
{
Brush backgroundBrush = await createTiledBackground((int)panel.Width, (int)panel.Height, TilePath);
if (backgroundBrush == null) return false;
panel.Background = backgroundBrush;
return true;
}
private static async Task<Brush> createTiledBackground(int width, int height, string tilePath)
{
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///" + tilePath));
byte[] sourcePixels;
int tileWidth, tileHeight;
using (IRandomAccessStream inputStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
if (inputStream == null) return null;
BitmapDecoder tileDecoder = await BitmapDecoder.CreateAsync(inputStream);
if (tileDecoder == null) return null;
tileWidth = (int)tileDecoder.PixelWidth;
tileHeight = (int) tileDecoder.PixelHeight;
PixelDataProvider pixelData = await tileDecoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format
BitmapAlphaMode.Straight,
new BitmapTransform(),
ExifOrientationMode.IgnoreExifOrientation,
ColorManagementMode.DoNotColorManage);
sourcePixels = pixelData.DetachPixelData();
// fileStream.Dispose();
}
WriteableBitmap backgroundBitmap = new WriteableBitmap(width, height);
int tileBmpWidth = tileWidth << 2;
int screenBmpWidth = width << 2;
int tileSize = tileBmpWidth * tileHeight;
int sourceOffset = 0;
using (Stream outputStream = backgroundBitmap.PixelBuffer.AsStream())
{
for (int bmpY=0; bmpY < height; bmpY++) {
for (int bmpX = 0; bmpX < screenBmpWidth; bmpX += tileBmpWidth)
await outputStream.WriteAsync(sourcePixels, sourceOffset, Math.Min(screenBmpWidth - bmpX, tileBmpWidth));
if ((sourceOffset += tileBmpWidth) >= tileSize)
sourceOffset -= tileSize;
}
}
ImageBrush backgroundBrush = new ImageBrush();
backgroundBrush.ImageSource = backgroundBitmap; // It's very easy now!
return backgroundBrush; // Finita la comédia!
}
Just one remark: if you do it on form start, you should not wait for it.
This doesn't work:
public MainPage()
{
this.InitializeComponent();
bool result = setupTiledBackground(contextPanel, TilePath).Result;
}
This works:
private Task<bool> backgroundImageTask;
public MainPage()
{
this.InitializeComponent();
backgroundImageTask = setupTiledBackground(contextPanel, TilePath);
}

Lego NXT-RobotC ultrasonic sensor

I am newbie in programming so I need help with my Ultrasonic sensor driven NXT robot.
It is attached to motor(A) and I'd like it to scan the room from robot's centerline to 90° left and 90° right in 30° increments (seven measurements total), store the data to an array and based on largest distance point my robot in the direction that measurement was taken to avoid obsticles.
Is this possible at all? Or is there some better solution?
Any advice or suggestion is more than welcome.
This would work somewhat for avoiding obstacles, as for implementing it, it depends what you are programming the robot in. I only know lejos(java), in which a function for getting the angle to go would be something like:
public static int scanArea(RegulatedMotor motorTop, UltrasonicSensor sonar) {
int theAngle = 0;
int largestDist = 0;
int currentDist;
for (int rotateAngle = -90; rotateAngle <= 90; rotateAngle += 30) {
motorTop.rotateTo(rotateAngle);
currentDist = sonar.getDistance();
if (currentDist > largestDist) {
largestDist = currentDist;
theAngle = rotateAngle;
}
Delay.msDelay(25);
}
motorTop.rotateTo(0);
return theAngle;
}
If you're coding the robot in any code based language that should be fairly easy to convert (assuming you have functions such as rotateTo, otherwise you would have to use relative movements). Otherwise I don't know how easy this would be to do in the graphical programming language that you use originally.
I would suggest attaching the ultrasonic sensor to a 180° servo that is vertical. You can take a measurement at a specific degree by assigning that degree to the servo. Using this:
int largestDistance = 0;
int Angle =0;
for (int servovalue = 0; servovalue <= 255; rotateAngle += 30){
Servo[servo1] = servovalue;
if (SensorValue[Sonar] > largestDist) {
largestDist = SensorValue[Sonar];
Angle = servovalue;
}
}
return Angle;
}
It assumes that servo1 is your vertical servo, but this should work if your programming in RobotC.

Turning Motor on Lego NXT returns error 0002EA Type 2

I a writing a program using RobotC for the Lego NXT to imitate the behaviour of a puppy. This section of code is supposed to rotate the head which is connected to motor port 3 and read the value on the ultra sonic sensor. If while the head is turned, the dog is called, it will turn in the direction it was already facing. The following function is called when the ultrasonic sensor reads a value (meaning the robot has come close to a wall):
visible
void SonarSensor()
{
int sensorValleft;
int sensorValright;
bool alreadyTurned = false;
int i,j;
i = 0;
j = 0;
motor[1] = 0;
motor[2] = 0;
motor[3] = -SPEED/2;
wait10Msec(15);
motor[3] = 0;
sensorValleft = SensorValue[3];
while(i<100)
{
if(SensorValue[4] > 40)//calibrate sound sensor
{
//turn left
motor[1]=SPEED;
motor[2] = -SPEED;
wait10Msec(25);
i = 1000;
j = 1000;
alreadyTurned = true;
}
else
{
i++;
wait1Msec(5);
}
}
motor[3] = SPEED/2;
wait10Msec(30);
motor[3] = 0;
sensorValright = SensorValue[3];
while(j<100)
{
if(SensorValue[3] > 1)//calibrate sound sensor
{
//turn right
motor[1]-=SPEED;
motor[2] = SPEED;
wait10Msec(25);
j = 1000;
alreadyTurned = true;
}
else
{
j++;
wait1Msec(5);
}
}
if(alreadyTurned == false)
{
if(sensorValleft > sensorValright)
{
//turn left
motor[1]=SPEED;
motor[2] = -SPEED;
wait10Msec(25);
}
else
{
//turn right
motor[1]=-SPEED;
motor[2] = SPEED;
wait10Msec(25);
}
}
}visible
When the head (motor[3]) rotates the first time the error 0002EA Type2 appears on the NXT screen. At first we thought it was because we were over-rotating the motor causing it to be obstructed so we tried to play around with the wait times but it made no difference.
Any ideas on what causes this error or how to fix it would be appreciated.
Thanks,
Dominique
The answer as to why only motor[3] causes an error is actually quite simple. The motorA, motorB, and motorC values are defined in an enum, where motorA=0, motorB=1, and motorC=2. So, motor[1] and motor[2] are equivalent to calling motor[motorB] and motor[motorC]. However, motor[3] isn't equivalent to anything. It's trying to set the power of a motor that doesn't exist. motor[0] would be ok, however, and would correspond to motor[motorA].
While debugging, I started putting break points in to see where the error was and it alwas occurred on the line motor[3] = -SPEED/2; it turns out that with the third motor the proper syntax is to use motor[motorA]=-SPEED/2;. I am not sure why only this motor returns this error as I am using two other motors which I set new speeds using
motor[1]=SPEED;
motor[2]=SPEED;
However, this was the way to abolish the error.