I'm building my mini GCS. I had Arm/Disarm are working correctly, but I'm stuck in how to send the waypoints to my drone. I need to send a Spline waypoints. I've tried MAV_CMD_NAV_SPLINE_WAYPOINT and set the parameters as required, but it does not send anything to my drone .
Here is my code:
MAVLink.mavlink_command_long_t alaa = new MAVLink.mavlink_command_long_t();
alaa.target_system = 1;
alaa.target_component = 1;
alaa.command = (ushort)MAV_CMD.MAV_CMD_NAV_SPLINE_WAYPOINT;
alaa.param1 = 0; // hold time
alaa.param4 = 0; // yaw angle
alaa.param5 = latt; // desired latitude
alaa.param6 = longg; // desired longitude
alaa.param7 = altt; // desired altitude
byte[] packet = mavAlaaWrite.GenerateMAVLinkPacket10(MAVLink.MAVLINK_MSG_ID.COMMAND_LONG, alaa);
Serial.Write(packet, 0, packet.Length);
Can someone please make a simple example by sending mission spline waypoints to my drone by clicking on a command button?
I'm programming using C# Windows forms.
Many thanks in advance.
Related
I have 2D game in which I am using around 200 different PlayerPrefs to store all types of data as strings and integers. I keep calling PlayerPrefs back and forth to set or get data. I want to know how good it is? Or I should switch to SQLite or Filing? our targeted devices are of 1GB ram max.
Data Example: Player1Name, Player1Score, Player1Enery, Player1Lives, Player1Hp, Player1Level1TimeTaken, Player1Level1Challenge1TimeTaken. And have we done it for dozens of players and several other preferences as well.
TIA
By reading your comment, there will be no problem with PlayerPrefs by the way you using it. The only problem I see is that you are saving each player's data property individually.
Data Example: Player1Name, Player1Score, Player1Enery, Player1Lives,
Player1Hp, Player1Level1TimeTaken, Player1Level1Challenge1TimeTaken.
And have we done it for dozens of players and several other
preferences as well. TIA
This is not the right way to save your data if you have many properties of a user. Assuming that's one or two variables, then you can, but you have more than 7 variables * number of players(dozens).
By the time you are done saving dozens of all those variables, there will be registry keys everywhere. You can verify this by going to HKCU\Software[company name][product name] key after saving your player dozen information.
Put those player information into a class then convert it Json and save it as one info data.
Player Data:
[System.Serializable]
public class PlayerInfo
{
public string playerName;
public int playerScore;
public int playerEnergy;
public int playerLives;
public int playerHP;
public float playerLevelTimeTaken;
public float playerLevelChallengeTimeTaken;
}
Save Player Info:
void savePlayerInfo()
{
//Create one for player one
PlayerInfo playerInfo1 = new PlayerInfo();
playerInfo1.playerName = "Affan 1";
//Create one for player two
PlayerInfo playerInfo2 = new PlayerInfo();
playerInfo2.playerName = "Affan 2";
//Create one for player three
PlayerInfo playerInfo3 = new PlayerInfo();
playerInfo3.playerName = "Affan 3";
//Convert each of them to Json
string p1Json = JsonUtility.ToJson(playerInfo1);
string p2Json = JsonUtility.ToJson(playerInfo2);
string p3Json = JsonUtility.ToJson(playerInfo3);
//Now Save all 3 player Info
PlayerPrefs.SetString("p1", p1Json);
PlayerPrefs.SetString("p2", p2Json);
PlayerPrefs.SetString("p3", p3Json);
}
Load Player Info:
void loadPlayerInfo()
{
//Load all 3 player Info
string p1Json = PlayerPrefs.GetString("p1");
string p2Json = PlayerPrefs.GetString("p2");
string p3Json = PlayerPrefs.GetString("p3");
//Convert each of them back to class
PlayerInfo playerInfo1 = JsonUtility.FromJson<PlayerInfo>(p1Json);
PlayerInfo playerInfo2 = JsonUtility.FromJson<PlayerInfo>(p2Json);
PlayerInfo playerInfo3 = JsonUtility.FromJson<PlayerInfo>(p3Json);
//Use
Debug.Log("Player 1 Name: " + playerInfo1.playerName);
Debug.Log("Player 2 Name: " + playerInfo2.playerName);
Debug.Log("Player 3 Name: " + playerInfo3.playerName);
}
To make it more easier to iterate through them, make it an array then use p0 to p49 as the key. This assumes that you need player info for 50 players.
To read:
PlayerInfo[] players;
void loadPlayerArrayInfo()
{
players = new PlayerInfo[50];
for (int i = 0; i < 50; i++)
{
players[i] = new PlayerInfo();
string tempPlayerKey = "p" + i;
string playerJson = PlayerPrefs.GetString(tempPlayerKey);
players[i] = JsonUtility.FromJson<PlayerInfo>(playerJson);
}
}
This keeps your registry clean and makes it easier to move your player settings to another Game Engine if you are moving away from Unity.
PlayerPrefs can read and set 3 types of variables. Float, int and string. int and float are both 32 bytes in memory length. A string takes up 20+(n/2)*4 bytes where n is the number of characters in the string. The string size may vary depending on how the unity devs compile the c# code to native code. As you can see the sizes are pretty small even for devices with just 1 gb of ram. You can use these metrics to calculate the amount of ram your variables will take up but I would not worry about that. What you are experiencing right now is called premature optimization. Just code it in this way and see if it causes a problem and then and only then optimize it.
I am writing a program in C# with the Kinect V2 SDK and am endeavoring to record the Body data. I attempted to just save the BodyFrame to a file, but it is not serializable and neither is the Body class. What would be the best way to accomplish this? My current thinking is to save the positional data for each joint in each body in each frame, but I have a feeling that will get complicated very fast. Suggestions? I've attached a portion of Microsoft's sample BodyBasics code below where it breaks the body data into joints. Thanks!
if (body.IsTracked)
{
//this.DrawClippedEdges(body, dc);
IReadOnlyDictionary<JointType, Joint> joints = body.Joints;
// convert the joint points to depth (display) space
Dictionary<JointType, Point> jointPoints = new Dictionary<JointType, Point>();
foreach (JointType jointType in joints.Keys)
{
// sometimes the depth(Z) of an inferred joint may show as negative
// clamp down to 0.1f to prevent coordinatemapper from returning (-Infinity, -Infinity)
CameraSpacePoint position = joints[jointType].Position;
if (position.Z < 0)
{
position.Z = InferredZPositionClamp;
}
DepthSpacePoint depthSpacePoint = this.coordinateMapper.MapCameraPointToDepthSpace(position);
jointPoints[jointType] = new Point(depthSpacePoint.X, depthSpacePoint.Y);
}
Use JSON.net.
static List<Body> trackedBodies = new List<Body>();
trackedBodies = bodies.Where(b => b.IsTracked == true).ToList();
if (trackedBodies.Count() < 1)
return null;
string kinectBodyDataString = JsonConvert.SerializeObject(trackedBodies);
I would like to store the motion capture data from Kinect 2 as a BVH file. I found code which does so for Kinect 1 which can be found here. I went through the code and found several things that I was not able to understand.
For example, in the mentioned code I've tried to understand what exactly the Skeleton skel object, found in several places in the code, actually is. If not, are there any known application available to accomplish the intended?
EDIT: I tried to change Skeleton skel to Body skel which I think is the correspondant object for kinect SDK 2.0. However I've got an error when I try to get the position of the body:
tempMotionVektor[0] = -Math.Round( skel.Position.X * 100,2);
tempMotionVektor[1] = Math.Round( skel.Position.Y * 100,2) + 120;
tempMotionVektor[2] = 300 - Math.Round( skel.Position.Z * 100,2);
I've gotten errors when calling the function Position for the Body skel. How can I retrieve the X, Y, Z of the skeleton in sdk 2.0?? I tried to change the above three lines to:
tempMotionVektor[0] = -Math.Round(skel.Joints[0].Position.X * 100, 2);
tempMotionVektor[1] = Math.Round(skel.Joints[0].Position.Y * 100, 2) + 120;
tempMotionVektor[2] = 300 - Math.Round(skel.Joints[0].Position.Z * 100, 2);
EDIT: Basically I managed to store the a bvh file after combining bodyBasicsWPF and kinect2bvh. However, it seems that the skeleton I am storing is not efficient. There are strange movements in the elbows. I am trying to understand if I have to change something in the file kinectSkeletonBVH.cp. More specifically, what are the changes in the joint axis orientation for the kinect 2 version. How can I change the following line: skel.BoneOrientations[JointType.ShoulderCenter].AbsoluteRotation.Quaternion; I tried to change that line with skel.JointOrientations[JointType.ShoulderCenter].Orientation. Am I right? I am using the following code to add the joint to BVHBone objects:
BVHBone hipCenter = new BVHBone(null, JointType.SpineBase.ToString(), 6, TransAxis.None, true);
BVHBone hipCenter2 = new BVHBone(hipCenter, "HipCenter2", 3, TransAxis.Y, false);
BVHBone spine = new BVHBone(hipCenter2, JointType.SpineMid.ToString(), 3, TransAxis.Y, true);
BVHBone shoulderCenter = new BVHBone(spine, JointType.SpineShoulder.ToString(), 3, TransAxis.Y, true);
BVHBone collarLeft = new BVHBone(shoulderCenter, "CollarLeft", 3, TransAxis.X, false);
BVHBone shoulderLeft = new BVHBone(collarLeft, JointType.ShoulderLeft.ToString(), 3, TransAxis.X, true);
BVHBone elbowLeft = new BVHBone(shoulderLeft, JointType.ElbowLeft.ToString(), 3, TransAxis.X, true);
BVHBone wristLeft = new BVHBone(elbowLeft, JointType.WristLeft.ToString(), 3, TransAxis.X, true);
BVHBone handLeft = new BVHBone(wristLeft, JointType.HandLeft.ToString(), 0, TransAxis.X, true);
BVHBone neck = new BVHBone(shoulderCenter, "Neck", 3, TransAxis.Y, false);
BVHBone head = new BVHBone(neck, JointType.Head.ToString(), 3, TransAxis.Y, true);
BVHBone headtop = new BVHBone(head, "Headtop", 0, TransAxis.None, false);
I can't understand where inside the code the axis for every Joint is calculated.
The code you used for Kinect 1.0 to obtain a BVH file use the joints information to build bone vectors by reading the Skeleton.
public static double[] getBoneVectorOutofJointPosition(BVHBone bvhBone, Skeleton skel)
{
double[] boneVector = new double[3] { 0, 0, 0 };
double[] boneVectorParent = new double[3] { 0, 0, 0 };
string boneName = bvhBone.Name;
JointType Joint;
if (bvhBone.Root == true)
{
boneVector = new double[3] { 0, 0, 0 };
}
else
{
if (bvhBone.IsKinectJoint == true)
{
Joint = KinectSkeletonBVH.String2JointType(boneName);
boneVector[0] = skel.Joints[Joint].Position.X;
boneVector[1] = skel.Joints[Joint].Position.Y;
boneVector[2] = skel.Joints[Joint].Position.Z;
..
Source: Nguyên Lê Đặng - Kinect2BVH.V2
Except in Kinect 2.0, Skeleton class has been replaced by the Body class, so you need to change it to deal with a Body instead, and obtain the joints by following the steps quoted below.
// Kinect namespace
using Microsoft.Kinect;
// ...
// Kinect sensor and Kinect stream reader objects
KinectSensor _sensor;
MultiSourceFrameReader _reader;
IList<Body> _bodies;
// Kinect sensor initialization
_sensor = KinectSensor.GetDefault();
if (_sensor != null)
{
_sensor.Open();
}
We also added a list of bodies, where all of the body/skeleton related
data will be saved. If you have developed for Kinect version 1, you
notice that the Skeleton class has been replaced by the Body class.
Remember the MultiSourceFrameReader? This class gives us access on
every stream, including the body stream! We simply need to let the
sensor know that we need body tracking functionality by adding an
additional parameter when initializing the reader:
_reader = _sensor.OpenMultiSourceFrameReader(FrameSourceTypes.Color |
FrameSourceTypes.Depth |
FrameSourceTypes.Infrared |
FrameSourceTypes.Body);
_reader.MultiSourceFrameArrived += Reader_MultiSourceFrameArrived;
The Reader_MultiSourceFrameArrived method will be called whenever a
new frame is available. Let’s specify what will happen in terms of the
body data:
Get a reference to the body frame
Check whether the body frame is null – this is crucial
Initialize the _bodies list
Call the GetAndRefreshBodyData method, so as to copy the body data into the list
Loop through the list of bodies and do awesome stuff!
Always remember to check for null values. Kinect provides you with
approximately 30 frames per second – anything could be null or
missing! Here is the code so far:
void Reader_MultiSourceFrameArrived(object sender,
MultiSourceFrameArrivedEventArgs e)
{
var reference = e.FrameReference.AcquireFrame();
// Color
// ...
// Depth
// ...
// Infrared
// ...
// Body
using (var frame = reference.BodyFrameReference.AcquireFrame())
{
if (frame != null)
{
_bodies = new Body[frame.BodyFrameSource.BodyCount];
frame.GetAndRefreshBodyData(_bodies);
foreach (var body in _bodies)
{
if (body != null)
{
// Do something with the body...
}
}
}
}
}
This is it! We now have access to the bodies Kinect identifies. Next
step is to display the skeleton information on-screen. Each body
consists of 25 joints. The sensor provides us with the position (X, Y,
Z) and the rotation information for each one of them. Moreover, Kinect
lets us know whether the joints are tracked, hypothsized or not
tracked. It’s a good practice to check whether a body is tracked
before performing any critical functions.
The following code illustrates how we can access the different body
joints:
if (body != null)
{
if (body.IsTracked)
{
Joint head = body.Joints[JointType.Head];
float x = head.Position.X;
float y = head.Position.Y;
float z = head.Position.Z;
// Draw the joints...
}
}
Source: Vangos Pterneas Blog - KINECT FOR WINDOWS VERSION 2: BODY TRACKING
Update 10/03
Ok, so i figured out the problem. C# is a funny old language..I changed
int navMeshCount = navMesh.GetPath(ref start, ref end, routePolys, navMeshRoute, false);
to
var navMeshCount = navMesh.GetPath(ref start, ref end, routePolys, navMeshRoute, false);
and finally im getting the pathfinding values to work!
When i debug the routeNavMesh array fills up with the values i require.
http://i.imgur.com/QgH8UL6.png [Screencap of debug in question]
Ill update again once im done.
Having some major problems getting a navigational mesh to work, in particular i cant get it to do any pathfinding or get it to respond to my vector3 input in any useful way.
Im working on the sunburn engine, it sits on top of XNA 4.0, so all of XNAs functions are still usable.
Recently Recast Navigation from digesting Duck's blog was ported over to c# and i've used it to create navigation meshes for my levels. Here is a link to the tutorial/guide i've been trying to follow: http://xboxforums.create.msdn.com/forums/p/109484/647991.aspx
im not sure how to pass in the start and end values on the getpath segment, are these meant to be values in world space or object space or something? If i do vector3 values and enter them as the start and end values( and then subsequently set them in a place on the array), i dont get an array of values that shows path finding, i just get those two verbatim values inside the navmeshroute array.
Here is where i try and run the path, its in my Update.
routePolys = new ushort[dtStatNavMesh.MAX_POLYS];
navMeshRoute = new Vector3[dtStatNavMesh.MAX_POLYS];
if (ks.IsKeyDown(Keys.L))
{
if (!runOnce)
{
start = new Vector3(0, 0, 0);
end = new Vector3(1000, 0, 1000);
ppos = x;
navMeshRoute[0].X = start.X;
navMeshRoute[0].Y = start.Y;
navMeshRoute[0].Z = start.Z;
navMeshRoute[count].X = end.X;
navMeshRoute[count].Y = end.Y;
navMeshRoute[count].Z = end.Z;
int navMeshStart = 0;
navMesh.GetPath(ref start, ref end, routePolys, navMeshRoute, true);
Console.WriteLine("navMeshPC" + navMesh.getPolyCount());
int navMeshCount = navMesh.GetPath(ref start, ref end, routePolys, navMeshRoute, true);
while (navMeshStart < navMeshCount)
{
routeNode = navMeshRoute[navMeshStart++];
}
Console.Out.WriteLine("NMc : " + navMeshCount);
}
}
I searched around on Google for this, but the only things I came up with were outdated and did not work.
Does anyone have any information on how to get joystick data using C# .NET?
Since this was the top hit I got on google while researching joystick / gamepad input in C#, I thought I should post a response for others to see.
The easiest way I found was to use SharpDX and DirectInput. You can install it via NuGet (SharpDX.DirectInput)
After that, it's simply a matter of calling a few methods:
Sample code from SharpDX
static void Main()
{
// Initialize DirectInput
var directInput = new DirectInput();
// Find a Joystick Guid
var joystickGuid = Guid.Empty;
foreach (var deviceInstance in directInput.GetDevices(DeviceType.Gamepad,
DeviceEnumerationFlags.AllDevices))
joystickGuid = deviceInstance.InstanceGuid;
// If Gamepad not found, look for a Joystick
if (joystickGuid == Guid.Empty)
foreach (var deviceInstance in directInput.GetDevices(DeviceType.Joystick,
DeviceEnumerationFlags.AllDevices))
joystickGuid = deviceInstance.InstanceGuid;
// If Joystick not found, throws an error
if (joystickGuid == Guid.Empty)
{
Console.WriteLine("No joystick/Gamepad found.");
Console.ReadKey();
Environment.Exit(1);
}
// Instantiate the joystick
var joystick = new Joystick(directInput, joystickGuid);
Console.WriteLine("Found Joystick/Gamepad with GUID: {0}", joystickGuid);
// Query all suported ForceFeedback effects
var allEffects = joystick.GetEffects();
foreach (var effectInfo in allEffects)
Console.WriteLine("Effect available {0}", effectInfo.Name);
// Set BufferSize in order to use buffered data.
joystick.Properties.BufferSize = 128;
// Acquire the joystick
joystick.Acquire();
// Poll events from joystick
while (true)
{
joystick.Poll();
var datas = joystick.GetBufferedData();
foreach (var state in datas)
Console.WriteLine(state);
}
}
I hope this helps.
I even got this to work with a DualShock3 and the MotioninJoy drivers.
One: use SlimDX.
Two: it looks something like this (where GamepadDevice is my own wrapper, and the code is slimmed down to just the relevant parts).
Find the joystick / pad GUIDs:
public virtual IList<GamepadDevice> Available()
{
IList<GamepadDevice> result = new List<GamepadDevice>();
DirectInput dinput = new DirectInput();
foreach (DeviceInstance di in dinput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
{
GamepadDevice dev = new GamepadDevice();
dev.Guid = di.InstanceGuid;
dev.Name = di.InstanceName;
result.Add(dev);
}
return result;
}
Once the user has selected from the list, acquire the gamepad:
private void acquire(System.Windows.Forms.Form parent)
{
DirectInput dinput = new DirectInput();
pad = new Joystick(dinput, this.Device.Guid);
foreach (DeviceObjectInstance doi in pad.GetObjects(ObjectDeviceType.Axis))
{
pad.GetObjectPropertiesById((int)doi.ObjectType).SetRange(-5000, 5000);
}
pad.Properties.AxisMode = DeviceAxisMode.Absolute;
pad.SetCooperativeLevel(parent, (CooperativeLevel.Nonexclusive | CooperativeLevel.Background));
pad.Acquire();
}
Polling the pad looks like this:
JoystickState state = new JoystickState();
if (pad.Poll().IsFailure)
{
result.Disconnect = true;
return result;
}
if (pad.GetCurrentState(ref state).IsFailure)
{
result.Disconnect = true;
return result;
}
result.X = state.X / 5000.0f;
result.Y = state.Y / 5000.0f;
int ispressed = 0;
bool[] buttons = state.GetButtons();
The bad news is that Microsoft seems to stop supporting their NET libraries for DirectX and focus on XNA instead. I don't work in GameDev so I don't need to use XNA but you may try it if you developing computer games. The good news is that there are other approaches. One is SlimDX the new framework to help you to wok with DirectX from C#. The other way is to directly add references of "Microsoft.DirectX.dll" and "Microsoft.DirectX.DirectInput.dll" to your project. you can find them "..\Windows\Microsoft.NET\DirectX for Managed Code\". if you you are going to use last approach here is a link to codeproject where you can read how to work with a joystick.
EDIT:
If your application is based on NET version newer then 2.0 the application may hang on. To fix this problem change config file and add this:
<startup useLegacyV2RuntimeActivationPolicy="true">
Google led me here and while not a requirement of this question, OpenTK is a good option for Windows and Linux (under mono) support.
From the OpenTK docs, this code works on Raspberry Pi + Raspbian + Mono 3.12.0:
for (int i = 0; i < 4; i++)
{
var state = Joystick.GetState(i);
if (state.IsConnected)
{
float x = state.GetAxis(JoystickAxis.Axis0);
float y = state.GetAxis(JoystickAxis.Axis1);
// Print the current state of the joystick
Console.WriteLine(state);
}
}
This question is old, but it seems to be active even to this day, so I'm posting anyway.
If you need to get input from XInput only, take a look at XInputium. This is a .NET library that is specialized in XInput controllers. It is pretty straightforward, and has many code samples you can look at.