Commit 89ea71a6 authored by Jonas Stienen's avatar Jonas Stienen

Merge branch 'master' of https://git.rwth-aachen.de/ita/toolbox

parents 458eec75 8db66692
......@@ -2,9 +2,9 @@ classdef itaOptitrack < handle
% class itaOptitrack
%
% Constructs an itaOptitrack object which is able to communicate with a
% NatNet server application (e.g. Motive). It can be used to log
% tracking data to be further processed or saved in Matlab.
% Constructs an itaOptitrack object to communicate with a NatNet server
% application (e.g. Motive). Can be used to log tracking data for further
% usage in Matlab.
%
% For proper functionality:
% (1) Run Optitrack's Motive tracker software
......@@ -198,7 +198,7 @@ classdef itaOptitrack < handle
% as the orientation of the head-mounted rigid body is changed.
%
% Author: Florian Pausch, fpa@akustik.rwth-aachen.de
% Version: 2016-06-21
% Version: 2016-11-18
%
% <ITA-Toolbox>
% This file is part of the ITA-Toolbox. Some rights reserved.
......@@ -259,7 +259,7 @@ classdef itaOptitrack < handle
end
properties(SetAccess = 'private', GetAccess = 'private')
dllPath = fullfile(ita_toolbox_path,'applications','Tracking','Optitrack','NatNet_SDK_2-7/lib/x64','NatNetML.dll'); % path to NatNet SDK
dllPath = fullfile(ita_toolbox_path,'applications/Hardware/Tracking/Optitrack/NatNetSDK'); % path to itaOptitrack
timerData = []; % Matlab timer handle
singleShot = 0; % only log 1 frame of tracking data (e.g. for geometric measurement purposes)
correctRowIdx = 1; % idx to fill up Optitrack_obj.rigidBodyLogData.data ignoring duplicate frames
......@@ -290,13 +290,47 @@ classdef itaOptitrack < handle
Optitrack_obj.ip = char(sArgs.ip);
Optitrack_obj.port = char(sArgs.port);
NET.addAssembly(Optitrack_obj.dllPath);
% Check if NatNet dll's are existing
if ~exist(Optitrack_obj.dllPath,'dir')
% download NatNet version
url = 'http://s3.amazonaws.com/naturalpoint/software/NatNetSDK/NatNet_SDK_2.10.zip';
try
% check Internet connection and if url is existing
urljava = java.net.URL(url);
openStream(urljava);
catch
% url is not existing or computer is not connected to Internet
error(['[itaOptitrack] No Internet connection or, ',url,' does not exist. Missing NatNet SDK cannot be downloaded. Please update URL (l.297) and version (l. 313/317/321).'])
end
% create directory
mkdir(Optitrack_obj.dllPath)
fprintf( '[itaOptitrack] Cannot find NatNet SDK. Downloading...' );
websave(fullfile(Optitrack_obj.dllPath,'NatNet_SDK_2.10.zip'),url);
% unzip
fprintf('.')
unzip(fullfile(Optitrack_obj.dllPath,'NatNet_SDK_2.10.zip'),fullfile(Optitrack_obj.dllPath,'NatNet_SDK_2.10'));
% delete zip file
fprintf('.\n')
delete(fullfile(Optitrack_obj.dllPath,'NatNet_SDK_2.10.zip'))
fprintf( '[itaOptitrack] NatNet SDK has been successfully downloaded.\n' );
end
NET.addAssembly(fullfile(Optitrack_obj.dllPath,'NatNet_SDK_2.10/NatNetSDK/lib/x64/NatNetML.dll'));
% Create an instance of a NatNet client
Optitrack_obj.theClient = NatNetML.NatNetClientML(0); % Input = iConnectionType: 0 = Multicast, 1 = Unicast
version = Optitrack_obj.theClient.NatNetVersion();
fprintf( '[itaOptitrack] Initialization succeeded.\n' );
fprintf( '[itaOptitrack] NatNetML Client Version : %d.%d.%d.%d\n', version(1), version(2), version(3), version(4) );
fprintf( '[itaOptitrack] NatNetML Client Version: %d.%d.%d.%d\n', version(1), version(2), version(3), version(4) );
Optitrack_obj.isInitialized = true;
......
NaturalPoint, Inc.
NatNet SDK is a simple Client/Server networking SDK for sending and receiving
NaturalPoint data across networks. NatNet uses the UDP protocol in conjunction
with either multicasting or point-to-point unicasting for transmitting data.
Please refer to the NatNet API USer's Guide for more information.
Change Log
-----------
Version 2.7.0 (10/15/2014)
-----------------------
Added: Motive 1.7 Streaming support
Added: New timing sample for validating mocap streaming frame timing.
Added: New Broadcast Trigger sample illustrating how to use remote record
trigger/listen using XML formatted UDP broadcast packets instead of NatNet commands.
Added: NatNetML - added SMPTE Timecode and Timecode Subframe members. See WinForms sample for usage.
Fixed: Fix for FrameID periodically displays dropped/duplicate packets during live mode.
Fixed: Fix for PacketClient incorrectly decoding rigid Body IsTracked parameter.
Fixed: Fix for crash in GetDataDescriptions() when streaming a Rigid Body with a single character name.
Fixed: Sample Clint incorrectly reports skeleton marker data
Changed: Update SampleClient3D to clarify quaterion decomposition, add new visuals.
Changed: Maximum markers per rigid body changed from 10 to 20 to match new RigidBody tracking
capabilities in Motive.
Changed: Frame timestamp now keyed off hardware frame id. fTimestamp resolution increased
from float to double *.
* DirectDepackatization clients should update their code (see timestamp in PacketClient.cpp for an example).
Version 2.6.0 (5/8/2014)
------------------------------
Added: Motive 1.6 Streaming support
Added: RigidBody tracking state parameter
Added: IsRecording flag on FrameOfMocapData indicating frame was recorded in Motive
Added: ModelsChanged flag on FrameOfMocapData indicating actively tracked model list has changed.
Added: Additional flags on LabelMarkerList indicating marker occlusion and marker position
calculation method.
Added: Additional FrameOfMocapData timestamp
Added: NatCap remote capture sample for illustrating send/receive remote Motive control commands via
UDP broadcast direct.
Added: UDP Repeater / Unity3D
Changed: Increase unlabeled/other marker count cap to 1000
Fixed: SampleClient latency value
Version 2.5.0 (9/2013)
------------------------------
Added: Motive 1.5 streaming support.
Added: New Matlab sample.
Added: Additional function signature overloads to better support MatLab.
Added: Motive remote control commands Start/Stop Recording, Start/Stop Playback,
LiveMode, EditMode, SetRecordTakeName, SetLiveTakeName. Refer to WinForms sample for usage examples.
Added: Motive record broadcast message parser sample.
Added: Samples updated to illustrate accessing point cloud model solved marker locations.
Added: Timing information to WinForms sample.
Added: New QuaternionToEuler() helper routines
Changed: Winforms Sample update for newer layout, sample Command/Requests for use with Motive
Fixed: SimplerServer compile issue.
Fixed: SampleClient when >2 skeletons are streaming.
Version 2.4.0 (3/19/2013)
------------------------------
Added: Motive 1.0 support.
Fixed: Memory leak in Client.
Fixed: Timecode during playback from file.
Fixed: Fix for crashes during large actor count (4-5) streaming.
Changed: Force "Dont Fragment" bit in IP header to off (0).
Changed: Update Winforms 2010 sample to target .NET 4.0 framework (same as NatNetML.dll assembly).
Changed: NatNetML - added additional MatLab compatible event signature (OnFrameReady2).
Version 2.3.0 (12/28/2011)
------------------------------
Added: SMPTE Timecode support (where supported, adds timecode stamp to every frame of mocap data).
Added: New "LabeledMarker" data type. This data type is used for labeled markers not associated
with a pre-defined "MarkerSet".
Changed: PacketClient example updated to reflect the new bitstream syntax containing "LabeledMarkers".
Changed: PacketClient example updated to reflect the new bitstream syntax containing Timecode data.
Version 2.2.0 (4/25/2010)
------------------------------
Added: New Unicast Point-to-Point connection type. Servers and clients can now
use MultiCast or Unicast as their connection type. Connection type between
server and client must be the same.
Added: Application-definable command and data port assignments, including Multicast address.
Added: VC redistributable installer (\Samples\VCRedist\vcredist_x86.exe) for running
the pre-compiled samples on machines without VisualStudio and/or the correct
version of the CRT runtime installed on them.
Changed: Changed PacketClient to support shared addresses (SO_REUSEADDR). Necessary
when server and client are running on same machine.
Changed: Updates to SimpleServer, SampleClient, and Winforms client to illustrate
Unicast usage.
Changed: Default Multicast address/port to IANA safe default values.
Fixed: Precompiled WinForms sample crashes on some machines.
Version 2.1.0 (11/20/2009)
------------------------------
Added: New "Skeleton" data type, representing a named, hierarchical collection
of RigidBodies.
Version 2.0.0 (11/12/2009)
------------------------------
Added: New RigidBody parameters
- RigidBody Name to RigidBody description
- MarkerData to RigidBody Data, including ID, position, and size
- MeanError to RigidBody data
Added: New managed (.NET) class library (NatNetML.dll). Allows for NatNetClient
and NatNet data types to be consumed directly in .NET compatible
environments (e.g. VB.Net, C#, LabView, MatLab).
Added: New WinForms .NET sample application illustrating NatNetML consumption.
Added: New depacketization sample (PacketClient) to replace the bitstream syntax.
This sample can be used to decode NatNet packets directly without the need
for the NatNet SDK. Intended only for clients that cannot use the NatNet SDK (e.g. Unix clients).
Added: New SDK documentation.
Added: Basic Client/Server message passing support (SendMessage(..)/SendMessageAndWait(..))
Added: Allow connections to a single server from multiple clients on same and/or different machines.
Changed: SampleClient updated to illustrate MarkerSet and RigidBody data handling.
Changed: SampleServer and SimpleServer samples merged into a single, simplified NatNet Server example.
Changed: SampleClient3D to include conversion and display of RigidBody quaternions to euler angles.
Changed: Updated to IPV6 protocol.
Version 1.2.0 (1/23/2008)
------------------------------
Added: VC8 static library (NatNetLibStatic.lib)
Added: VC6 static library (NatNetvc6StaticLib.lib)
Added: x64 libraries (dynamic and static)
Added: Bitstream syntax documentation.
Added: Rigid body data type support.
Added: Versioning information. NatNet version information is now available from
file (DLL), local version (NatNetHelper::NatNetVersion), and fom the
connected application(ServerDescription.NatNetVersion()) to help ensure NatNet
server/client versions are in synch.
Changed: Updated to Visual Studio 2005 Project files.
Changed: Removed all /clr references. NatNet and the samples use strictly
native code.
Changed: NatNet types and helper routines cleaned up to improve usage.
Changed: SampleServer and Sampleclient programs updated to illustrate new usages.
ccx
% <ITA-Toolbox>
% This file is part of the application TPA-TPS for the ITA-Toolbox. All rights reserved.
% You can find the license for this m-file in the application folder.
% </ITA-Toolbox>
a = ita_generate('impulse',1,44100,16);
b = a* 0;
a_mat = [a, b; b*2, -2*a];
b_mat = [1*a, 1*a; 1*a, 1*a];
c = [1 1; 1 1];
%% Y matrix
fft_degree = 16;
folder = '/Users/pascaldietrich/MATLAB/__Bosch/BOSCH - auralizationBox otpa/vonMLI/Y_r';
for idx = 1:3
for jdx = 1:3
Yr(idx,jdx) = ita_extract_dat(ita_read([folder filesep 'y' num2str(idx) num2str(jdx) '.ita']),fft_degree,'symmetric');
end
end
folder = '/Users/pascaldietrich/MATLAB/__Bosch/BOSCH - auralizationBox otpa/vonMLI/Ys_model';
for idx = 1:3
for jdx = 1:3
Ys(idx,jdx) = ita_extract_dat(ita_mpb_filter( ita_read([folder filesep 'y' num2str(idx) num2str(jdx) '.ita']),[10 0], 'zerophase'),fft_degree,'symmetric');
end
end
%% fit
tic
for idx = 1:3
for jdx = 1:3
x = ita_frequency_dependent_time_window(Ys(idx,jdx),[0.6 0.7; 0.2 0.3; 0.05 0.06], [1000 3000], 'symmetric');
Ys_fit(idx,jdx) = ita_audio2zpk_rationalfit(x,'degree',80,'freqRange',[30 8000]);
end
end
for idx = 1:3
for jdx = 1:3
x = ita_frequency_dependent_time_window(Yr(idx,jdx),[0.6 0.7; 0.2 0.3; 0.05 0.06], [1000 3000], 'symmetric');
Yr_fit(idx,jdx) = ita_audio2zpk_rationalfit(Yr(idx,jdx),'degree',80,'freqRange',[30 8000],'mode','log');
end
end
toc
%% write
folder = 'E:\pdi_daten\MATLAB\TPA-TPS';
ita_write(Ys_fit,[folder filesep 'Ys_fit.ita'])
ita_write(Yr_fit,[folder filesep 'Yr_fit.ita'])
%% load
folder = 'E:\pdi_daten\MATLAB\TPA-TPS';
Ys_fit = load([folder filesep 'Ys_fit.ita'],'-mat');
Yr_fit = ita_read([folder filesep 'Yr_fit.ita']);
%%
for idx = 1:3
for jdx = 1:3
Ys_test(idx,jdx) = Ys_fit(idx,jdx)';% / Ys(idx,jdx);
Yr_test(idx,jdx) = Yr_fit(idx,jdx)';% / Yr(idx,jdx);
end
end
%% coupling
tic
K = Ys / (Yr + Ys);
toc
%%
% K_fit = Ys_fit / (Yr_fit + Ys_fit);
for idx = 1:3
for jdx = 1:3
% K_fit(idx,jdx).channelNames{1} = ['K' num2str(idx) num2str(jdx)];
K(idx,jdx).channelNames{1} = ['K' num2str(idx) num2str(jdx)];
end
end
%%
K_test = Ys_test / (Yr_test + Ys_test);
%%
for idx = 1:3
for jdx = 1:3
K(idx,jdx).channelNames{1} = ['K' num2str(idx) num2str(jdx)];
end
end
ita_plot_spkphase(merge(K))
%%
res1 = a_mat * c;
ita_plot_spk(merge(res1),'nodb','ylim',[-5 5])
res2 = a_mat * b_mat;
ita_plot_spk(merge(res2),'nodb','ylim',[-5 5])
%% coupling
Ys = [1 0; 0, 1];
Yr = [0.9 0.1; 0.1 0.9];
Ys_mat = [1*a, 0*a; 0*a, 1*a];
Yr_mat = [.9*a, .1*a; .1*a, .9*a];
K = Ys / (Yr + Ys)
for idx = 1:3
for jdx = 1:3
Yr(idx,jdx) = ita_extract_dat(ita_read([folder filesep 'y' num2str(idx) num2str(jdx) '.ita']),fft_degree,'symmetric');
end
end
K_mat = Ys_mat / (Yr_mat + Ys_mat)
%%
ccx
%% mli raw TP with hammer
clear TP
for foot_idx = 1:3
for idx = [1]
data = ita_read(['\\verdi\scratch\lievens\pdi\steel_cones\tps\Yc_foot' num2str(foot_idx) '_MDF_25e-3__pvc_run' num2str(idx) '.ita']);
F = ita_time_window(data.ch(1),[0.02 0 0.5 0.7],'time');
p = data.ch(2:6);
TP = p/F;
end
res(foot_idx) = ita_time_window(TP,[0.9 1.1],'time');
end
%% mli
data = ita_read('Z:\lievens\pdi\steel_cones\Fvp__4-20Hz_expsweep_fft20_8WashT.ita');
a = data.ch([2 3 1]);
p = data.ch([7:11]);
F = data.ch(4:6);
% imp = F.ch(1)*0;
% imp.timeData(:,1) = imp.nSamples;
% F = merge(F,imp);
%% OPA
TP = ita_otpa(p,F,'blocksize',4096*8,'overlap',0.5,'tol',0.01,'window',@hann);
TPopa = merge(TP.ch(1));
TPopa.plot_spk
x = ita_time_window(TPopa,[0.002 0 double(TPopa.trackLength)*[0.9 0.99]],'time');
x.plot_spk
%% pre-white spectrum
TP = ita_otpa(p,F,'blocksize',4096*8,'overlap',0.5,'tol',0.1,'window',@hann,'prewhite');
for idx = 1:TP(1).nChannels
TPopa(idx) = merge(TP.ch(idx));
end
% TPopa(2).plot_spk
% x = ita_time_window(TPopa,[0.002 0 double(TPopa.trackLength)*[0.5 0.99]],'time');
% x.plot_spk
%% comparison
close all
idx = 1;
TP(idx).plot_spk('ylim',[-40 0]);
x = merge(res.ch(idx));
x.plot_spk('ylim',[-40 0]);
%% synthesis
for pidx = 1:numel(TP)
p_test(pidx) = ita_sum(F * ita_extend_dat(TP(pidx),a.nSamples,'symmetric'));
end
p_test = merge(p_test);
%% hammer messung
data_hammer = ita_read('Z:\lievens\pdi\steel_cones\Yc_foot1_MDF_25e-3__pvc_run1.ita');
data_hammer = ita_time_shift(data_hammer,'30dB');
data_hammer = ita_time_shift(data_hammer,0.025,'time');
data_hammer = ita_time_window(data_hammer,[0.02 0],'time');
data_hammer = ita_frequency_dependent_time_window(data_hammer,[0.5 1; 0.05 0.1],500);
res = ita_divide_spk( data_hammer.ch([1:3 5:12]),data_hammer.ch(4),'regularization',[20 4000]);
TPorig = ita_divide_spk(res,res.ch(4),'regularization',[20 4000]);
TPorigF = TPorig.ch(7:11);
TPorigF.plot_spk
%% synthesis with orig
for pidx = 1:numel(TP)
p_test_orig(pidx) = ita_sum(F * ita_extend_dat(TPorigF.ch(pidx),a.nSamples,'symmetric'));
end
p_test_orig = merge(p_test_orig);
%% OPA with synthesis data
TP = ita_otpa(p_test_orig,F,'blocksize',4096,'overlap',0.5,'tol',0.00000000001,'window',@hann);
TPopa = merge(TP.ch(1))
TPopa.plot_spk
%% OPA with randomized phase
TPrand = ita_otpa(ita_randomize_phase(p),ita_randomize_phase(F),'blocksize',4096*8,'overlap',0.5,'tol',0.00000000001,'window',@hann);
TPoparand = merge(TPrand.ch(1))
TPoparand.plot_spk
%% ************************************************************************
%% Excitation Signal
F0 = itaAudio();
F0.samplingRate = 100;
F0.time = zeros(100,1);
F0.time = 0.2*sin(2*F0.timeVector* pi);
F0.time(1) = 1;
F0.time(20) = -1;
n = itaAudio; n.trackLength = 15;
n.time = (n.timeVector / n.trackLength)*50 + 20;
% n.time = 500 * n.time * 0;
F1 = F0;
F1.time = sin(1*F1.timeVector*2*pi) + 0.3 * sin(2*F1.timeVector*2*pi) + cos(4*F1.timeVector*2*pi);
n1 = itaAudio; n1.trackLength = double(n.trackLength);
n1.time = (n.timeVector / n1.trackLength)*1300 + 100+ 20*sin(40*n.timeVector/double(n1.trackLength) * 2 * pi);
excitationsignal(1) = ita_normalize_dat( ita_iem_force_transform (F0, n,'oversample',100,'periodic',true));
excitationsignal(2) = 0.1 * ita_normalize_dat( ita_iem_force_transform (F1, n1));
%%
amp = 1;
sr = n.samplingRate;
nSamples = n1.samplingRate * double(n1.trackLength);
freq_vec = [20 10000];
stop_margin = 1;
NTIcoeffs = [1 0.2];
% Generating a long MLS signal
mls_raw = ita_generate('mls', amp, sr, 20);
% Performing a hole in the MLS signal
mls = mls_raw;
mls.timeData(1:30000) = 0;
% Sweep and compensation
sweep = amp*ita_generate('linsweep',freq_vec,0.1,sr,nSamples);
sweep = ita_extend_dat(sweep,mls.nSamples);
% sweep = ita_time_shift(sweep,stop_margin/4);
sweep.signalType = 'energy'; % because acts as a filter
silencesweep = mls*sweep;
silencesweep = ita_extend_dat(silencesweep,nSamples);
% Silence Sweep
excitationsignal(3) = ita_normalize_dat(silencesweep);
%% expsweep
%% playback
test = merge(excitationsignal);
%%
ita_portaudio(test,'OutputChannels',[3 4 1])
%%
ita_portaudio(test.ch(3),'OutputChannels',[1])
%% MS
MS = ita_measurement
%% MS messung
ex = ita_amplify( MS.excitation ,'-15dB');
ex.trackLength = 10;
ex = merge(ex,0.5*ita_time_shift(ex,3,'time'),ita_time_shift(ex,6,'time'));
ex = ita_time_shift(ex,1,'time');
%%
ita_portaudio(ex,'OutputChannels',[3 4 1]);
%%
ita_portaudio(ex.ch(1),'OutputChannels',[1]);
%% test motor
out_ch = [3 2];
motor_sweep = ita_generate('expsweep',[5000 17000],0.1,sr,nSamples);
ita_portaudio(motor_sweep,'OutputChannels',out_ch)
%% folder
folder = '/Users/pascaldietrich/MATLAB/BOSCH - auralizationBox otpa';
cd (folder)
%% auswertung
F_ch = 1:3;
p_ch = 13:15;
TP = ita_otpa(data.ch(p_ch),data.ch(F_ch),'blocksize',4096,'overlap',0.5,'tol',0.00000000001,'window',@hann);
%% deconv
ir = ita_divide_spk(data,data.ch(14),'regularization',[20 10000]);
ir_win = ita_time_window(ir,[0.5 1],'symmetric');