@@ -2,13 +2,21 @@ | |||
"name" : "MYO4Live", | |||
"version" : 1, | |||
"creationdate" : 3654856293, | |||
"modificationdate" : 3654856293, | |||
"modificationdate" : 3654856392, | |||
"viewrect" : [ 25.0, 70.0, 300.0, 500.0 ], | |||
"autoorganize" : 1, | |||
"hideprojectwindow" : 0, | |||
"showdependencies" : 1, | |||
"autolocalize" : 0, | |||
"contents" : { | |||
"patchers" : { | |||
"main.maxpat" : { | |||
"kind" : "patcher", | |||
"local" : 1, | |||
"toplevel" : 1 | |||
} | |||
} | |||
} | |||
, |
@@ -0,0 +1,197 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <stdint.h> | |||
#include "Pose.hpp" | |||
namespace myo { | |||
class Myo; | |||
template<typename T> | |||
class Quaternion; | |||
template<typename T> | |||
class Vector3; | |||
/// Enumeration identifying a right arm or left arm. | |||
enum Arm { | |||
armLeft = libmyo_arm_left, | |||
armRight = libmyo_arm_right, | |||
armUnknown = libmyo_arm_unknown | |||
}; | |||
/// Possible directions for Myo's +x axis relative to a user's arm. | |||
enum XDirection { | |||
xDirectionTowardWrist = libmyo_x_direction_toward_wrist, | |||
xDirectionTowardElbow = libmyo_x_direction_toward_elbow, | |||
xDirectionUnknown = libmyo_x_direction_unknown | |||
}; | |||
/// Possible warmup states for a Myo. | |||
enum WarmupState { | |||
warmupStateUnknown = libmyo_warmup_state_unknown, | |||
warmupStateCold = libmyo_warmup_state_cold, | |||
warmupStateWarm = libmyo_warmup_state_warm, | |||
}; | |||
/// Possible warmup results for a Myo. | |||
enum WarmupResult { | |||
warmupResultUnknown = libmyo_warmup_result_unknown, | |||
warmupResultSuccess = libmyo_warmup_result_success, | |||
warmupResultFailedTimeout = libmyo_warmup_result_failed_timeout, | |||
}; | |||
/// Firmware version of Myo. | |||
struct FirmwareVersion { | |||
unsigned int firmwareVersionMajor; ///< Myo's major version must match the required major version. | |||
unsigned int firmwareVersionMinor; ///< Myo's minor version must match the required minor version. | |||
unsigned int firmwareVersionPatch; ///< Myo's patch version must greater or equal to the required patch version. | |||
unsigned int firmwareVersionHardwareRev; ///< Myo's hardware revision; not used to detect firmware version mismatch. | |||
}; | |||
/// A DeviceListener receives events about a Myo. | |||
/// @see Hub::addListener() | |||
class DeviceListener { | |||
public: | |||
virtual ~DeviceListener() {} | |||
/// Called when a Myo has been paired. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param firmwareVersion The firmware version of \a myo. | |||
virtual void onPair(Myo* myo, uint64_t timestamp, FirmwareVersion firmwareVersion) {} | |||
/// Called when a Myo has been unpaired. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onUnpair(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo has been connected. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param firmwareVersion The firmware version of \a myo. | |||
virtual void onConnect(Myo* myo, uint64_t timestamp, FirmwareVersion firmwareVersion) {} | |||
/// Called when a paired Myo has been disconnected. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onDisconnect(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo recognizes that it is on an arm. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param arm The identified Arm of \a myo. | |||
/// @param xDirection The identified XDirection of \a myo. | |||
/// @param rotation The estimated rotation of Myo on the user's arm after a sync. | |||
/// @param warmupState The warmup state of \a myo. If \a warmupState is equal to WarmupState::warmupStateCold, | |||
/// onWarmupCompleted() will be called when the warmup period has completed. | |||
virtual void onArmSync(Myo* myo, uint64_t timestamp, Arm arm, XDirection xDirection, float rotation, | |||
WarmupState warmupState) {} | |||
/// Called when a paired Myo is moved or removed from the arm. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onArmUnsync(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo becomes unlocked. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onUnlock(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo becomes locked. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onLock(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo has provided a new pose. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param pose The identified Pose of \a myo. | |||
virtual void onPose(Myo* myo, uint64_t timestamp, Pose pose) {} | |||
/// Called when a paired Myo has provided new orientation data. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param rotation The orientation data of \a myo, as a Quaternion. | |||
virtual void onOrientationData(Myo* myo, uint64_t timestamp, const Quaternion<float>& rotation) {} | |||
/// Called when a paired Myo has provided new accelerometer data in units of g. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param accel The accelerometer data of \a myo, in units of g. | |||
virtual void onAccelerometerData(Myo* myo, uint64_t timestamp, const Vector3<float>& accel) {} | |||
/// Called when a paired Myo has provided new gyroscope data in units of deg/s. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param gyro The gyroscope data of \a myo, in units of deg/s. | |||
virtual void onGyroscopeData(Myo* myo, uint64_t timestamp, const Vector3<float>& gyro) {} | |||
/// Called when a paired Myo has provided a new RSSI value. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param rssi The RSSI (received signal strength indication) of \a myo. | |||
/// @see Myo::requestRssi() to request an RSSI value from the Myo. | |||
virtual void onRssi(Myo* myo, uint64_t timestamp, int8_t rssi) {} | |||
/// Called when a paired Myo receives an battery level update. | |||
/// Updates occur when the battery level changes and when the battery level is explicitly requested. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param level battery level reported by the myo the value is a number from 0 to 100 representing the percentage | |||
/// of battery life remaining. | |||
virtual void onBatteryLevelReceived(myo::Myo* myo, uint64_t timestamp, uint8_t level) {} | |||
/// Called when a paired Myo has provided new EMG data. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param emg An array of 8 elements, each corresponding to one sensor. | |||
virtual void onEmgData(myo::Myo* myo, uint64_t timestamp, const int8_t* emg) {} | |||
/// Called when the warmup period for a Myo has completed. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param warmupResult The warmup result of \a myo. | |||
virtual void onWarmupCompleted(myo::Myo* myo, uint64_t timestamp, WarmupResult warmupResult) {} | |||
/// @cond LIBMYO_INTERNALS | |||
virtual void onOpaqueEvent(libmyo_event_t event) {} | |||
/// @endcond | |||
}; | |||
} // namespace myo |
@@ -0,0 +1,91 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <vector> | |||
#include <myo/libmyo.h> | |||
namespace myo { | |||
class Myo; | |||
class DeviceListener; | |||
/// @brief A Hub provides access to one or more Myo instances. | |||
class Hub { | |||
public: | |||
/// Construct a hub. | |||
/// \a applicationIdentifier must follow a reverse domain name format (ex. com.domainname.appname). Application | |||
/// identifiers can be formed from the set of alphanumeric ASCII characters (a-z, A-Z, 0-9). The hyphen (-) and | |||
/// underscore (_) characters are permitted if they are not adjacent to a period (.) character (i.e. not at the | |||
/// start or end of each segment), but are not permitted in the top-level domain. Application identifiers must have | |||
/// three or more segments. For example, if a company's domain is example.com and the application is named | |||
/// hello-world, one could use "com.example.hello-world" as a valid application identifier. \a applicationIdentifier | |||
/// can be an empty string. | |||
/// Throws an exception of type std::invalid_argument if \a applicationIdentifier is not in the proper reverse | |||
/// domain name format or is longer than 255 characters. | |||
/// Throws an exception of type std::runtime_error if the hub initialization failed for some reason, typically | |||
/// because Myo Connect is not running and a connection can thus not be established. | |||
Hub(const std::string& applicationIdentifier = ""); | |||
/// Deallocate any resources associated with a Hub. | |||
/// This will cause all Myo instances retrieved from this Hub to become invalid. | |||
~Hub(); | |||
/// Wait for a Myo to become paired, or time out after \a timeout_ms milliseconds if provided. | |||
/// If \a timeout_ms is zero, this function blocks until a Myo is found. | |||
/// This function must not be called concurrently with run() or runOnce(). | |||
Myo* waitForMyo(unsigned int milliseconds = 0); | |||
/// Register a listener to be called when device events occur. | |||
void addListener(DeviceListener* listener); | |||
/// Remove a previously registered listener. | |||
void removeListener(DeviceListener* listener); | |||
/// Locking policies supported by Myo. | |||
enum LockingPolicy { | |||
lockingPolicyNone = libmyo_locking_policy_none, | |||
lockingPolicyStandard = libmyo_locking_policy_standard | |||
}; | |||
/// Set the locking policy for Myos connected to the Hub. | |||
void setLockingPolicy(LockingPolicy lockingPolicy); | |||
/// Run the event loop for the specified duration (in milliseconds). | |||
void run(unsigned int duration_ms); | |||
/// Run the event loop until a single event occurs, or the specified duration (in milliseconds) has elapsed. | |||
void runOnce(unsigned int duration_ms); | |||
/// @cond MYO_INTERNALS | |||
/// Return the internal libmyo object corresponding to this hub. | |||
libmyo_hub_t libmyoObject(); | |||
protected: | |||
void onDeviceEvent(libmyo_event_t event); | |||
Myo* lookupMyo(libmyo_myo_t opaqueMyo) const; | |||
Myo* addMyo(libmyo_myo_t opaqueMyo); | |||
libmyo_hub_t _hub; | |||
std::vector<Myo*> _myos; | |||
std::vector<DeviceListener*> _listeners; | |||
/// @endcond | |||
private: | |||
// Not implemented | |||
Hub(const Hub&); | |||
Hub& operator=(const Hub&); | |||
}; | |||
/// @example hello-myo.cpp | |||
/// @example multiple-myos.cpp | |||
/// @example emg-data-sample.cpp | |||
} // namespace myo | |||
#include "impl/Hub_impl.hpp" |
@@ -0,0 +1,83 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <myo/libmyo.h> | |||
namespace myo { | |||
/// Represents a Myo device with a specific MAC address. | |||
/// This class can not be instantiated directly; instead, use Hub to get access to a Myo. | |||
/// There is only one Myo instance corresponding to each device; thus, if the addresses of two Myo instances compare | |||
/// equal, they refer to the same device. | |||
class Myo { | |||
public: | |||
/// Types of vibration supported by the Myo. | |||
enum VibrationType { | |||
vibrationShort = libmyo_vibration_short, | |||
vibrationMedium = libmyo_vibration_medium, | |||
vibrationLong = libmyo_vibration_long | |||
}; | |||
/// Vibrate the Myo. | |||
void vibrate(VibrationType type); | |||
/// Request the RSSI of the Myo. An onRssi event will likely be generated with the value of the RSSI. | |||
/// @see DeviceListener::onRssi() | |||
void requestRssi() const; | |||
/// Request the battery level of the Myo. An onBatteryLevelReceived event will be generated with the value. | |||
/// @see DeviceListener::onBatteryLevelReceived(). | |||
void requestBatteryLevel() const; | |||
/// Unlock types supported by Myo. | |||
enum UnlockType { | |||
unlockTimed = libmyo_unlock_timed, | |||
unlockHold = libmyo_unlock_hold | |||
}; | |||
/// Unlock the Myo. | |||
/// Myo will remain unlocked for a short amount of time, after which it will automatically lock again. | |||
/// If Myo was locked, an onUnlock event will be generated. | |||
void unlock(UnlockType type); | |||
/// Force the Myo to lock immediately. | |||
/// If Myo was unlocked, an onLock event will be generated. | |||
void lock(); | |||
/// Notify the Myo that a user action was recognized. | |||
/// Will cause Myo to vibrate. | |||
void notifyUserAction(); | |||
/// Valid EMG streaming modes for a Myo. | |||
enum StreamEmgType { | |||
streamEmgDisabled = libmyo_stream_emg_disabled, | |||
streamEmgEnabled = libmyo_stream_emg_enabled | |||
}; | |||
/// Sets the EMG streaming mode for a Myo. | |||
void setStreamEmg(StreamEmgType type); | |||
/// @cond MYO_INTERNALS | |||
/// Return the internal libmyo object corresponding to this device. | |||
libmyo_myo_t libmyoObject() const; | |||
/// @endcond | |||
private: | |||
Myo(libmyo_myo_t myo); | |||
~Myo(); | |||
libmyo_myo_t _myo; | |||
// Not implemented. | |||
Myo(const Myo&); | |||
Myo& operator=(const Myo&); | |||
friend class Hub; | |||
}; | |||
} // namespace myo | |||
#include "impl/Myo_impl.hpp" |
@@ -0,0 +1,70 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <iosfwd> | |||
#include <string> | |||
#include <myo/libmyo.h> | |||
namespace myo { | |||
/// A pose represents a detected configuration of the user's hand. | |||
class Pose { | |||
public: | |||
/// Types of poses supported by the SDK. | |||
enum Type { | |||
rest = libmyo_pose_rest, | |||
fist = libmyo_pose_fist, | |||
waveIn = libmyo_pose_wave_in, | |||
waveOut = libmyo_pose_wave_out, | |||
fingersSpread = libmyo_pose_fingers_spread, | |||
doubleTap = libmyo_pose_double_tap, | |||
unknown = libmyo_pose_unknown | |||
}; | |||
/// Construct a pose of type Pose::none. | |||
Pose(); | |||
/// Construct a pose with the given type. | |||
Pose(Type type); | |||
/// Returns true if and only if the two poses are of the same type. | |||
bool operator==(Pose other) const; | |||
/// Equivalent to `!(*this == other)`. | |||
bool operator!=(Pose other) const; | |||
/// Returns the type of this pose. | |||
Type type() const; | |||
/// Return a human-readable string representation of the pose. | |||
std::string toString() const; | |||
private: | |||
Type _type; | |||
}; | |||
/// @relates Pose | |||
/// Returns true if and only if the type of pose is the same as the provided type. | |||
bool operator==(Pose pose, Pose::Type t); | |||
/// @relates Pose | |||
/// Equivalent to `pose == type`. | |||
bool operator==(Pose::Type type, Pose pose); | |||
/// @relates Pose | |||
/// Equivalent to `!(pose == type)`. | |||
bool operator!=(Pose pose, Pose::Type type); | |||
/// @relates Pose | |||
/// Equivalent to `!(type == pose)`. | |||
bool operator!=(Pose::Type type, Pose pose); | |||
/// @relates Pose | |||
/// Write the name of the provided pose to the provided output stream. | |||
std::ostream& operator<<(std::ostream& out, const Pose& pose); | |||
} // namespace myo | |||
#include "impl/Pose_impl.hpp" |
@@ -0,0 +1,158 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <cmath> | |||
#include "Vector3.hpp" | |||
namespace myo { | |||
/// A quaternion that can be used to represent a rotation. | |||
/// This type provides only very basic functionality to store quaternions that's sufficient to retrieve the data to | |||
/// be placed in a full featured quaternion type. | |||
template<typename T> | |||
class Quaternion { | |||
public: | |||
/// Construct a quaternion that represents zero rotation (i.e. the multiplicative identity). | |||
Quaternion() | |||
: _x(0) | |||
, _y(0) | |||
, _z(0) | |||
, _w(1) | |||
{ | |||
} | |||
/// Construct a quaternion with the provided components. | |||
Quaternion(T x, T y, T z, T w) | |||
: _x(x) | |||
, _y(y) | |||
, _z(z) | |||
, _w(w) | |||
{ | |||
} | |||
/// Set the components of this quaternion to be those of the other. | |||
Quaternion& operator=(const Quaternion other) | |||
{ | |||
_x = other._x; | |||
_y = other._y; | |||
_z = other._z; | |||
_w = other._w; | |||
return *this; | |||
} | |||
/// Return the x-component of this quaternion's vector. | |||
T x() const { return _x; } | |||
/// Return the y-component of this quaternion's vector. | |||
T y() const { return _y; } | |||
/// Return the z-component of this quaternion's vector. | |||
T z() const { return _z; } | |||
/// Return the w-component (scalar) of this quaternion. | |||
T w() const { return _w; } | |||
/// Return the quaternion multiplied by \a rhs. | |||
/// Note that quaternion multiplication is not commutative. | |||
Quaternion operator*(const Quaternion& rhs) const | |||
{ | |||
return Quaternion( | |||
_w * rhs._x + _x * rhs._w + _y * rhs._z - _z * rhs._y, | |||
_w * rhs._y - _x * rhs._z + _y * rhs._w + _z * rhs._x, | |||
_w * rhs._z + _x * rhs._y - _y * rhs._x + _z * rhs._w, | |||
_w * rhs._w - _x * rhs._x - _y * rhs._y - _z * rhs._z | |||
); | |||
} | |||
/// Multiply this quaternion by \a rhs. | |||
/// Return this quaternion updated with the result. | |||
Quaternion& operator*=(const Quaternion& rhs) | |||
{ | |||
*this = *this * rhs; | |||
return *this; | |||
} | |||
/// Return the unit quaternion corresponding to the same rotation as this one. | |||
Quaternion normalized() const | |||
{ | |||
T magnitude = std::sqrt(_x * _x + _y * _y + _z * _z + _w * _w); | |||
return Quaternion(_x / magnitude, _y / magnitude, _z / magnitude, _w / magnitude); | |||
} | |||
/// Return this quaternion's conjugate. | |||
Quaternion conjugate() const | |||
{ | |||
return Quaternion(-_x, -_y, -_z, _w); | |||
} | |||
/// Return a quaternion that represents a right-handed rotation of \a angle radians about the given \a axis. | |||
/// \a axis The unit vector representing the axis of rotation. | |||
/// \a angle The angle of rotation, in radians. | |||
static Quaternion fromAxisAngle(const myo::Vector3<T>& axis, T angle) | |||
{ | |||
return Quaternion(axis.x() * std::sin(angle / 2), | |||
axis.y() * std::sin(angle / 2), | |||
axis.z() * std::sin(angle / 2), | |||
std::cos(angle / 2)); | |||
} | |||
private: | |||
T _x, _y, _z, _w; | |||
}; | |||
/// Return a copy of this \a vec rotated by \a quat. | |||
/// \relates myo::Quaternion | |||
template<typename T> | |||
Vector3<T> rotate(const Quaternion<T>& quat, const Vector3<T>& vec) | |||
{ | |||
myo::Quaternion<T> qvec(vec.x(), vec.y(), vec.z(), 0); | |||
myo::Quaternion<T> result = quat * qvec * quat.conjugate(); | |||
return Vector3<T>(result.x(), result.y(), result.z()); | |||
} | |||
/// Return a quaternion that represents a rotation from vector \a from to \a to. | |||
/// \relates myo::Quaternion | |||
/// See http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another | |||
/// for some explanation. | |||
template<typename T> | |||
Quaternion<T> rotate(const Vector3<T>& from, const Vector3<T>& to) | |||
{ | |||
Vector3<T> cross = from.cross(to); | |||
// The product of the square of magnitudes and the cosine of the angle between from and to. | |||
T cosTheta = from.dot(to); | |||
// Return identity if the vectors are the same direction. | |||
if (cosTheta >= 1) { | |||
return Quaternion<T>(); | |||
} | |||
// The product of the square of the magnitudes | |||
T k = std::sqrt(from.dot(from) * to.dot(to)); | |||
// Return identity in the degenerate case. | |||
if (k <= 0) { | |||
return Quaternion<T>(); | |||
} | |||
// Special handling for vectors facing opposite directions. | |||
if (cosTheta / k <= -1) { | |||
Vector3<T> xAxis(1, 0, 0); | |||
Vector3<T> yAxis(0, 1, 0); | |||
cross = from.cross(std::abs(from.dot(xAxis)) < 1 ? xAxis : yAxis); | |||
k = cosTheta = 0; | |||
} | |||
return Quaternion<T>( | |||
cross.x(), | |||
cross.y(), | |||
cross.z(), | |||
k + cosTheta); | |||
} | |||
} // namespace myo |
@@ -0,0 +1,103 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#define _USE_MATH_DEFINES | |||
#include <cmath> | |||
namespace myo { | |||
/// A vector of three components. | |||
/// This type provides very basic functionality to store a three dimensional vector that's sufficient to retrieve | |||
/// the data to be placed in a full featured vector type. A few common vector operations, such as dot product and | |||
/// cross product, are also provided. | |||
template<typename T> | |||
class Vector3 { | |||
public: | |||
/// Construct a vector of all zeroes. | |||
Vector3() | |||
{ | |||
_data[0] = 0; | |||
_data[1] = 0; | |||
_data[2] = 0; | |||
} | |||
/// Construct a vector with the three provided components. | |||
Vector3(T x, T y, T z) | |||
{ | |||
_data[0] = x; | |||
_data[1] = y; | |||
_data[2] = z; | |||
} | |||
/// Construct a vector with the same components as \a other. | |||
Vector3(const Vector3& other) | |||
{ | |||
*this = other; | |||
} | |||
/// Set the components of this vector to be the same as \a other. | |||
Vector3& operator=(const Vector3& other) | |||
{ | |||
_data[0] = other._data[0]; | |||
_data[1] = other._data[1]; | |||
_data[2] = other._data[2]; | |||
return *this; | |||
} | |||
/// Return a copy of the component of this vector at \a index, which should be 0, 1, or 2. | |||
T operator[](unsigned int index) const | |||
{ | |||
return _data[index]; | |||
} | |||
/// Return the x-component of this vector. | |||
T x() const { return _data[0]; } | |||
/// Return the y-component of this vector. | |||
T y() const { return _data[1]; } | |||
/// Return the z-component of this vector. | |||
T z() const { return _data[2]; } | |||
/// Return the magnitude of this vector. | |||
T magnitude() const | |||
{ | |||
return std::sqrt(x() * x() + y() * y() + z() * z()); | |||
} | |||
/// Return a normalized copy of this vector. | |||
Vector3 normalized() const | |||
{ | |||
T norm = magnitude(); | |||
return Vector3(x() / norm, y() / norm, z() / norm); | |||
} | |||
/// Return the dot product of this vector and \a rhs. | |||
T dot(const Vector3& rhs) const | |||
{ | |||
return x() * rhs.x() + y() * rhs.y() + z() * rhs.z(); | |||
} | |||
/// Return the cross product of this vector and \a rhs. | |||
Vector3 cross(const Vector3& rhs) const | |||
{ | |||
return Vector3( | |||
y() * rhs.z() - z() * rhs.y(), | |||
z() * rhs.x() - x() * rhs.z(), | |||
x() * rhs.y() - y() * rhs.x() | |||
); | |||
} | |||
/// Return the angle between this vector and \a rhs, in radians. | |||
T angleTo(const Vector3& rhs) const | |||
{ | |||
return std::acos(dot(rhs) / (magnitude() * rhs.magnitude())); | |||
} | |||
private: | |||
T _data[3]; | |||
}; | |||
} // namespace myo |
@@ -0,0 +1,70 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_CXX_DETAIL_THROWONERROR_HPP | |||
#define MYO_CXX_DETAIL_THROWONERROR_HPP | |||
#include <stdexcept> | |||
#include <myo/libmyo.h> | |||
#if defined(_MSC_VER) && _MSC_VER <= 1800 | |||
#define LIBMYO_NOEXCEPT(b) | |||
#else | |||
#if __cplusplus >= 201103L | |||
# define LIBMYO_NOEXCEPT(b) noexcept(b) | |||
#else | |||
# define LIBMYO_NOEXCEPT(b) | |||
#endif | |||
#endif | |||
namespace myo { | |||
class ThrowOnError { | |||
public: | |||
ThrowOnError() | |||
: _error() | |||
{ | |||
} | |||
~ThrowOnError() LIBMYO_NOEXCEPT(false) | |||
{ | |||
if (_error) | |||
{ | |||
switch (libmyo_error_kind(_error)) { | |||
case libmyo_error: | |||
case libmyo_error_runtime: | |||
{ | |||
std::runtime_error exception(libmyo_error_cstring(_error)); | |||
libmyo_free_error_details(_error); | |||
throw exception; | |||
} | |||
case libmyo_error_invalid_argument: | |||
{ | |||
std::invalid_argument exception(libmyo_error_cstring(_error)); | |||
libmyo_free_error_details(_error); | |||
throw exception; | |||
} | |||
case libmyo_success: | |||
{ | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
operator libmyo_error_details_t*() | |||
{ | |||
return &_error; | |||
} | |||
private: | |||
libmyo_error_details_t _error; | |||
// Not implemented | |||
ThrowOnError(const ThrowOnError&); // = delete; | |||
ThrowOnError& operator=(const ThrowOnError&); // = delete; | |||
}; | |||
} //namespace libmyo | |||
#endif // MYO_CXX_DETAIL_THROWONERROR_HPP |
@@ -0,0 +1,265 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#include "../Hub.hpp" | |||
#include <algorithm> | |||
#include <exception> | |||
#include "../DeviceListener.hpp" | |||
#include "../Myo.hpp" | |||
#include "../Pose.hpp" | |||
#include "../Quaternion.hpp" | |||
#include "../Vector3.hpp" | |||
#include "../detail/ThrowOnError.hpp" | |||
namespace myo { | |||
inline | |||
Hub::Hub(const std::string& applicationIdentifier) | |||
: _hub(0) | |||
, _myos() | |||
, _listeners() | |||
{ | |||
libmyo_init_hub(&_hub, applicationIdentifier.c_str(), ThrowOnError()); | |||
} | |||
inline | |||
Hub::~Hub() | |||
{ | |||
for (std::vector<Myo*>::iterator I = _myos.begin(), IE = _myos.end(); I != IE; ++I) { | |||
delete *I; | |||
} | |||
libmyo_shutdown_hub(_hub, 0); | |||
} | |||
inline | |||
Myo* Hub::waitForMyo(unsigned int timeout_ms) | |||
{ | |||
std::size_t prevSize = _myos.size(); | |||
struct local { | |||
static libmyo_handler_result_t handler(void* user_data, libmyo_event_t event) { | |||
Hub* hub = static_cast<Hub*>(user_data); | |||
libmyo_myo_t opaque_myo = libmyo_event_get_myo(event); | |||
switch (libmyo_event_get_type(event)) { | |||
case libmyo_event_paired: | |||
hub->addMyo(opaque_myo); | |||
return libmyo_handler_stop; | |||
default: | |||
break; | |||
} | |||
return libmyo_handler_continue; | |||
} | |||
}; | |||
do { | |||
libmyo_run(_hub, timeout_ms ? timeout_ms : 1000, &local::handler, this, ThrowOnError()); | |||
} while (!timeout_ms && _myos.size() <= prevSize); | |||
if (_myos.size() <= prevSize) { | |||
return 0; | |||
} | |||
return _myos.back(); | |||
} | |||
inline | |||
void Hub::addListener(DeviceListener* listener) | |||
{ | |||
if (std::find(_listeners.begin(), _listeners.end(), listener) != _listeners.end()) { | |||
// Listener was already added. | |||
return; | |||
} | |||
_listeners.push_back(listener); | |||
} | |||
inline | |||
void Hub::removeListener(DeviceListener* listener) | |||
{ | |||
std::vector<DeviceListener*>::iterator I = std::find(_listeners.begin(), _listeners.end(), listener); | |||
if (I == _listeners.end()) { | |||
// Don't have this listener. | |||
return; | |||
} | |||
_listeners.erase(I); | |||
} | |||
inline | |||
void Hub::setLockingPolicy(LockingPolicy lockingPolicy) | |||
{ | |||
libmyo_set_locking_policy(_hub, static_cast<libmyo_locking_policy_t>(lockingPolicy), ThrowOnError()); | |||
} | |||
inline | |||
void Hub::onDeviceEvent(libmyo_event_t event) | |||
{ | |||
libmyo_myo_t opaqueMyo = libmyo_event_get_myo(event); | |||
Myo* myo = lookupMyo(opaqueMyo); | |||
if (!myo && libmyo_event_get_type(event) == libmyo_event_paired) { | |||
myo = addMyo(opaqueMyo); | |||
} | |||
if (!myo) { | |||
// Ignore events for Myos we don't know about. | |||
return; | |||
} | |||
for (std::vector<DeviceListener*>::iterator I = _listeners.begin(), IE = _listeners.end(); I != IE; ++I) { | |||
DeviceListener* listener = *I; | |||
listener->onOpaqueEvent(event); | |||
uint64_t time = libmyo_event_get_timestamp(event); | |||
switch (libmyo_event_get_type(event)) { | |||
case libmyo_event_paired: { | |||
FirmwareVersion version = {libmyo_event_get_firmware_version(event, libmyo_version_major), | |||
libmyo_event_get_firmware_version(event, libmyo_version_minor), | |||
libmyo_event_get_firmware_version(event, libmyo_version_patch), | |||
libmyo_event_get_firmware_version(event, libmyo_version_hardware_rev)}; | |||
listener->onPair(myo, time, version); | |||
break; | |||
} | |||
case libmyo_event_unpaired: | |||
listener->onUnpair(myo, time); | |||
break; | |||
case libmyo_event_connected: { | |||
FirmwareVersion version = {libmyo_event_get_firmware_version(event, libmyo_version_major), | |||
libmyo_event_get_firmware_version(event, libmyo_version_minor), | |||
libmyo_event_get_firmware_version(event, libmyo_version_patch), | |||
libmyo_event_get_firmware_version(event, libmyo_version_hardware_rev)}; | |||
listener->onConnect(myo, time, version); | |||
break; | |||
} | |||
case libmyo_event_disconnected: | |||
listener->onDisconnect(myo, time); | |||
break; | |||
case libmyo_event_arm_synced: | |||
listener->onArmSync(myo, time, | |||
static_cast<Arm>(libmyo_event_get_arm(event)), | |||
static_cast<XDirection>(libmyo_event_get_x_direction(event)), | |||
libmyo_event_get_rotation_on_arm(event), | |||
static_cast<WarmupState>(libmyo_event_get_warmup_state(event))); | |||
break; | |||
case libmyo_event_arm_unsynced: | |||
listener->onArmUnsync(myo, time); | |||
break; | |||
case libmyo_event_unlocked: | |||
listener->onUnlock(myo, time); | |||
break; | |||
case libmyo_event_locked: | |||
listener->onLock(myo, time); | |||
break; | |||
case libmyo_event_orientation: | |||
listener->onOrientationData(myo, time, | |||
Quaternion<float>(libmyo_event_get_orientation(event, libmyo_orientation_x), | |||
libmyo_event_get_orientation(event, libmyo_orientation_y), | |||
libmyo_event_get_orientation(event, libmyo_orientation_z), | |||
libmyo_event_get_orientation(event, libmyo_orientation_w))); | |||
listener->onAccelerometerData(myo, time, | |||
Vector3<float>(libmyo_event_get_accelerometer(event, 0), | |||
libmyo_event_get_accelerometer(event, 1), | |||
libmyo_event_get_accelerometer(event, 2))); | |||
listener->onGyroscopeData(myo, time, | |||
Vector3<float>(libmyo_event_get_gyroscope(event, 0), | |||
libmyo_event_get_gyroscope(event, 1), | |||
libmyo_event_get_gyroscope(event, 2))); | |||
break; | |||
case libmyo_event_pose: | |||
listener->onPose(myo, time, Pose(static_cast<Pose::Type>(libmyo_event_get_pose(event)))); | |||
break; | |||
case libmyo_event_rssi: | |||
listener->onRssi(myo, time, libmyo_event_get_rssi(event)); | |||
break; | |||
case libmyo_event_battery_level: | |||
listener->onBatteryLevelReceived(myo, time, libmyo_event_get_battery_level(event)); | |||
break; | |||
case libmyo_event_emg: { | |||
int8_t emg[] = { libmyo_event_get_emg(event, 0), | |||
libmyo_event_get_emg(event, 1), | |||
libmyo_event_get_emg(event, 2), | |||
libmyo_event_get_emg(event, 3), | |||
libmyo_event_get_emg(event, 4), | |||
libmyo_event_get_emg(event, 5), | |||
libmyo_event_get_emg(event, 6), | |||
libmyo_event_get_emg(event, 7) }; | |||
listener->onEmgData(myo, time, emg); | |||
break; | |||
} | |||
case libmyo_event_warmup_completed: { | |||
listener->onWarmupCompleted(myo, time, static_cast<WarmupResult>(libmyo_event_get_warmup_result(event))); | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
inline | |||
void Hub::run(unsigned int duration_ms) | |||
{ | |||
struct local { | |||
static libmyo_handler_result_t handler(void* user_data, libmyo_event_t event) { | |||
Hub* hub = static_cast<Hub*>(user_data); | |||
hub->onDeviceEvent(event); | |||
return libmyo_handler_continue; | |||
} | |||
}; | |||
libmyo_run(_hub, duration_ms, &local::handler, this, ThrowOnError()); | |||
} | |||
inline | |||
void Hub::runOnce(unsigned int duration_ms) | |||
{ | |||
struct local { | |||
static libmyo_handler_result_t handler(void* user_data, libmyo_event_t event) { | |||
Hub* hub = static_cast<Hub*>(user_data); | |||
hub->onDeviceEvent(event); | |||
return libmyo_handler_stop; | |||
} | |||
}; | |||
libmyo_run(_hub, duration_ms, &local::handler, this, ThrowOnError()); | |||
} | |||
inline | |||
libmyo_hub_t Hub::libmyoObject() | |||
{ | |||
return _hub; | |||
} | |||
inline | |||
Myo* Hub::lookupMyo(libmyo_myo_t opaqueMyo) const | |||
{ | |||
Myo* myo = 0; | |||
for (std::vector<Myo*>::const_iterator I = _myos.begin(), IE = _myos.end(); I != IE; ++I) { | |||
if ((*I)->libmyoObject() == opaqueMyo) { | |||
myo = *I; | |||
break; | |||
} | |||
} | |||
return myo; | |||
} | |||
inline | |||
Myo* Hub::addMyo(libmyo_myo_t opaqueMyo) | |||
{ | |||
Myo* myo = new Myo(opaqueMyo); | |||
_myos.push_back(myo); | |||
return myo; | |||
} | |||
} // namespace myo |
@@ -0,0 +1,72 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#include "../Myo.hpp" | |||
#include "../detail/ThrowOnError.hpp" | |||
#include <stdexcept> | |||
namespace myo { | |||
inline | |||
void Myo::vibrate(VibrationType type) | |||
{ | |||
libmyo_vibrate(_myo, static_cast<libmyo_vibration_type_t>(type), ThrowOnError()); | |||
} | |||
inline | |||
void Myo::requestRssi() const | |||
{ | |||
libmyo_request_rssi(_myo, ThrowOnError()); | |||
} | |||
inline | |||
void Myo::requestBatteryLevel() const | |||
{ | |||
libmyo_request_battery_level(_myo, myo::ThrowOnError()); | |||
} | |||
inline | |||
void Myo::unlock(UnlockType type) | |||
{ | |||
libmyo_myo_unlock(_myo, static_cast<libmyo_unlock_type_t>(type), ThrowOnError()); | |||
} | |||
inline | |||
void Myo::lock() | |||
{ | |||
libmyo_myo_lock(_myo, ThrowOnError()); | |||
} | |||
inline | |||
void Myo::notifyUserAction() | |||
{ | |||
libmyo_myo_notify_user_action(_myo, libmyo_user_action_single, ThrowOnError()); | |||
} | |||
inline | |||
void Myo::setStreamEmg(StreamEmgType type) | |||
{ | |||
libmyo_set_stream_emg(_myo, static_cast<libmyo_stream_emg_t>(type), ThrowOnError()); | |||
} | |||
inline | |||
libmyo_myo_t Myo::libmyoObject() const | |||
{ | |||
return _myo; | |||
} | |||
inline | |||
Myo::Myo(libmyo_myo_t myo) | |||
: _myo(myo) | |||
{ | |||
if (!_myo) { | |||
throw std::invalid_argument("Cannot construct Myo instance with null pointer"); | |||
} | |||
} | |||
inline | |||
Myo::~Myo() | |||
{ | |||
} | |||
} // namespace myo |
@@ -0,0 +1,97 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_CXX_IMPL_POSE_IMPL_HPP | |||
#define MYO_CXX_IMPL_POSE_IMPL_HPP | |||
#include "../Pose.hpp" | |||
#include <iostream> | |||
namespace myo { | |||
inline | |||
Pose::Pose() | |||
: _type(unknown) | |||
{ | |||
} | |||
inline | |||
Pose::Pose(Pose::Type type) | |||
: _type(type) | |||
{ | |||
} | |||
inline | |||
bool Pose::operator==(Pose other) const | |||
{ | |||
return _type == other._type; | |||
} | |||
inline | |||
bool Pose::operator!=(Pose other) const | |||
{ | |||
return !(*this == other); | |||
} | |||
inline | |||
Pose::Type Pose::type() const | |||
{ | |||
return _type; | |||
} | |||
inline | |||
bool operator==(Pose pose, Pose::Type type) | |||
{ | |||
return pose.type() == type; | |||
} | |||
inline | |||
bool operator==(Pose::Type type, Pose pose) | |||
{ | |||
return pose == type; | |||
} | |||
inline | |||
bool operator!=(Pose pose, Pose::Type type) | |||
{ | |||
return !(pose == type); | |||
} | |||
inline | |||
bool operator!=(Pose::Type type, Pose pose) | |||
{ | |||
return !(type == pose); | |||
} | |||
inline | |||
std::string Pose::toString() const | |||
{ | |||
switch (type()) { | |||
case Pose::rest: | |||
return "rest"; | |||
case Pose::fist: | |||
return "fist"; | |||
case Pose::waveIn: | |||
return "waveIn"; | |||
case Pose::waveOut: | |||
return "waveOut"; | |||
case Pose::fingersSpread: | |||
return "fingersSpread"; | |||
case Pose::doubleTap: | |||
return "doubleTap"; | |||
case Pose::unknown: | |||
return "unknown"; | |||
} | |||
return "<invalid>"; | |||
} | |||
inline | |||
std::ostream& operator<<(std::ostream& out, const Pose& pose) | |||
{ | |||
return out << pose.toString(); | |||
} | |||
} // namespace myo | |||
#endif // MYO_CXX_IMPL_POSE_IMPL_HPP |
@@ -0,0 +1,425 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_LIBMYO_H | |||
#define MYO_LIBMYO_H | |||
#include <stdint.h> | |||
#include "libmyo/detail/visibility.h" | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/// @file libmyo.h | |||
/// libmyo C API declarations. | |||
typedef void* libmyo_hub_t; | |||
/// \defgroup errors Error Handling | |||
/// @{ | |||
/// Function result codes. | |||
/// All libmyo functions that can fail return a value of this type. | |||
typedef enum { | |||
libmyo_success, | |||
libmyo_error, | |||
libmyo_error_invalid_argument, | |||
libmyo_error_runtime | |||
} libmyo_result_t; | |||
/// Opaque handle to detailed error information. | |||
typedef void* libmyo_error_details_t; | |||
/// Return a null-terminated string with a detailed error message. | |||
LIBMYO_EXPORT | |||
const char* libmyo_error_cstring(libmyo_error_details_t); | |||
/// Returns the kind of error that occurred. | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_error_kind(libmyo_error_details_t); | |||
/// Free the resources allocated by an error object. | |||
LIBMYO_EXPORT | |||
void libmyo_free_error_details(libmyo_error_details_t); | |||
/// @} | |||
/// \defgroup libmyo_string Strings | |||
/// @{ | |||
// Opaque string. | |||
typedef void* libmyo_string_t; | |||
// Return a null-terminated string from the opaque string. | |||
LIBMYO_EXPORT | |||
const char* libmyo_string_c_str(libmyo_string_t); | |||
// Free the resources allocated by the string object. | |||
LIBMYO_EXPORT | |||
void libmyo_string_free(libmyo_string_t); | |||
/// @} | |||
/// \defgroup libmyo_direct_mac_addresses MAC address utilities | |||
/// @{ | |||
/// Retrieve the string representation of a MAC address in hex. | |||
/// Returns a string in the format of 00-00-00-00-00-00. | |||
LIBMYO_EXPORT | |||
libmyo_string_t libmyo_mac_address_to_string(uint64_t); | |||
/// Retrieve the MAC address from a null-terminated string in the format of 00-00-00-00-00-00. | |||
/// Returns 0 if the string does not match the format. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_string_to_mac_address(const char*); | |||
/// @} | |||
/// @defgroup libmyo_hub Hub instance | |||
/// @{ | |||
/// Initialize a connection to the hub. | |||
/// \a application_identifier must follow a reverse domain name format (ex. com.domainname.appname). Application | |||
/// identifiers can be formed from the set of alphanumeric ASCII characters (a-z, A-Z, 0-9). The hyphen (-) and | |||
/// underscore (_) characters are permitted if they are not adjacent to a period (.) character (i.e. not at the start or | |||
/// end of each segment), but are not permitted in the top-level domain. Application identifiers must have three or more | |||
/// segments. For example, if a company's domain is example.com and the application is named hello-world, one could use | |||
/// "com.example.hello-world" as a valid application identifier. \a application_identifier can be NULL or empty. | |||
/// @returns libmyo_success if the connection is successfully established, otherwise: | |||
/// - libmyo_error_runtime if a connection could not be established | |||
/// - libmyo_error_invalid_argument if \a out_hub is NULL | |||
/// - libmyo_error_invalid_argument if \a application_identifier is longer than 255 characters | |||
/// - libmyo_error_invalid_argument if \a application_identifier is not in the proper reverse domain name format | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_init_hub(libmyo_hub_t* out_hub, const char* application_identifier, | |||
libmyo_error_details_t* out_error); | |||
/// Free the resources allocated to a hub. | |||
/// @returns libmyo_success if shutdown is successful, otherwise: | |||
/// - libmyo_error_invalid_argument if \a hub is NULL | |||
/// - libmyo_error if \a hub is not a valid hub | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_shutdown_hub(libmyo_hub_t hub, libmyo_error_details_t* out_error); | |||
// Locking policies. | |||
typedef enum { | |||
libmyo_locking_policy_none, ///< Pose events are always sent. | |||
libmyo_locking_policy_standard ///< Pose events are not sent while a Myo is locked. | |||
} libmyo_locking_policy_t; | |||
/// Set the locking policy for Myos connected to the hub. | |||
/// @returns libmyo_success if the locking policy is successfully set, otherwise | |||
/// - libmyo_error_invalid_argument if \a hub is NULL | |||
/// - libmyo_error if \a hub is not a valid hub | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_set_locking_policy(libmyo_hub_t hub, libmyo_locking_policy_t locking_policy, | |||
libmyo_error_details_t* out_error); | |||
/// @} | |||
/// @defgroup libmyo_myo Myo instances | |||
/// @{ | |||
/// Opaque type corresponding to a known Myo device. | |||
typedef void* libmyo_myo_t; | |||
/// Types of vibration | |||
typedef enum { | |||
libmyo_vibration_short, | |||
libmyo_vibration_medium, | |||
libmyo_vibration_long | |||
} libmyo_vibration_type_t; | |||
/// Retrieve the MAC address of a Myo. | |||
/// The MAC address is unique to the physical Myo, and is a 48-bit number. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_get_mac_address(libmyo_myo_t myo); | |||
/// Vibrate the given myo. | |||
/// Can be called when a Myo is paired. | |||
/// @returns libmyo_success if the Myo successfully vibrated, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_vibrate(libmyo_myo_t myo, libmyo_vibration_type_t type, libmyo_error_details_t* out_error); | |||
/// Request the RSSI for a given myo. | |||
/// Can be called when a Myo is paired. A libmyo_event_rssi event will likely be generated with the value of the RSSI. | |||
/// @returns libmyo_success if the Myo successfully got the RSSI, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_request_rssi(libmyo_myo_t myo, libmyo_error_details_t* out_error); | |||
/// Request the battery level for a given Myo. | |||
/// A libmyo_event_battery_level event will be generated with the value of the battery level. | |||
/// @returns libmyo_success if the Myo successfully requested the battery level, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_request_battery_level(libmyo_myo_t myo_opq, libmyo_error_details_t* out_error); | |||
/// EMG streaming modes. | |||
typedef enum { | |||
libmyo_stream_emg_disabled, ///< Do not send EMG data. | |||
libmyo_stream_emg_enabled ///< Send EMG data. | |||
} libmyo_stream_emg_t; | |||
/// Set whether or not to stream EMG data for a given myo. | |||
/// Can be called when a Myo is paired. | |||
/// @returns libmyo_success if the EMG mode was set successfully, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_set_stream_emg(libmyo_myo_t myo, libmyo_stream_emg_t emg, libmyo_error_details_t* out_error); | |||
/// @} | |||
/// @defgroup libmyo_poses Pose recognition. | |||
/// @{ | |||
/// Supported poses. | |||
typedef enum { | |||
libmyo_pose_rest = 0, ///< Rest pose. | |||
libmyo_pose_fist = 1, ///< User is making a fist. | |||
libmyo_pose_wave_in = 2, ///< User has an open palm rotated towards the posterior of their wrist. | |||
libmyo_pose_wave_out = 3, ///< User has an open palm rotated towards the anterior of their wrist. | |||
libmyo_pose_fingers_spread = 4, ///< User has an open palm with their fingers spread away from each other. | |||
libmyo_pose_double_tap = 5, ///< User tapped their thumb and middle finger together twice in succession. | |||
libmyo_num_poses, ///< Number of poses supported; not a valid pose. | |||
libmyo_pose_unknown = 0xffff ///< Unknown pose. | |||
} libmyo_pose_t; | |||
/// @} | |||
/// @defgroup libmyo_locking Myo locking mechanism | |||
/// Valid unlock types. | |||
typedef enum { | |||
libmyo_unlock_timed = 0, ///< Unlock for a fixed period of time. | |||
libmyo_unlock_hold = 1, ///< Unlock until explicitly told to re-lock. | |||
} libmyo_unlock_type_t; | |||
/// Unlock the given Myo. | |||
/// Can be called when a Myo is paired. A libmyo_event_unlocked event will be generated if the Myo was locked. | |||
/// @returns libmyo_success if the Myo was successfully unlocked, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_myo_unlock(libmyo_myo_t myo, libmyo_unlock_type_t type, libmyo_error_details_t* out_error); | |||
/// Lock the given Myo immediately. | |||
/// Can be called when a Myo is paired. A libmyo_event_locked event will be generated if the Myo was unlocked. | |||
/// @returns libmyo_success if the Myo was successfully locked, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_myo_lock(libmyo_myo_t myo, libmyo_error_details_t* out_error); | |||
/// User action types. | |||
typedef enum { | |||
libmyo_user_action_single = 0, ///< User did a single, discrete action, such as pausing a video. | |||
} libmyo_user_action_type_t; | |||
/// Notify the given Myo that a user action was recognized. | |||
/// Can be called when a Myo is paired. Will cause Myo to vibrate. | |||
/// @returns libmyo_success if the Myo was successfully notified, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_myo_notify_user_action(libmyo_myo_t myo, libmyo_user_action_type_t type, | |||
libmyo_error_details_t* out_error); | |||
/// @} | |||
/// @defgroup libmyo_events Event Handling | |||
/// @{ | |||
/// Types of events. | |||
typedef enum { | |||
libmyo_event_paired, ///< Successfully paired with a Myo. | |||
libmyo_event_unpaired, ///< Successfully unpaired from a Myo. | |||
libmyo_event_connected, ///< A Myo has successfully connected. | |||
libmyo_event_disconnected, ///< A Myo has been disconnected. | |||
libmyo_event_arm_synced, ///< A Myo has recognized that the sync gesture has been successfully performed. | |||
libmyo_event_arm_unsynced, ///< A Myo has been moved or removed from the arm. | |||
libmyo_event_orientation, ///< Orientation data has been received. | |||
libmyo_event_pose, ///< A change in pose has been detected. @see libmyo_pose_t. | |||
libmyo_event_rssi, ///< An RSSI value has been received. | |||
libmyo_event_unlocked, ///< A Myo has become unlocked. | |||
libmyo_event_locked, ///< A Myo has become locked. | |||
libmyo_event_emg, ///< EMG data has been received. | |||
libmyo_event_battery_level, ///< A battery level value has been received. | |||
libmyo_event_warmup_completed, ///< The warmup period has completed. | |||
} libmyo_event_type_t; | |||
/// Information about an event. | |||
typedef const void* libmyo_event_t; | |||
/// Retrieve the type of an event. | |||
LIBMYO_EXPORT | |||
uint32_t libmyo_event_get_type(libmyo_event_t event); | |||
/// Retrieve the timestamp of an event. | |||
/// @see libmyo_now() for details on timestamps. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_event_get_timestamp(libmyo_event_t event); | |||
/// Retrieve the Myo associated with an event. | |||
LIBMYO_EXPORT | |||
libmyo_myo_t libmyo_event_get_myo(libmyo_event_t event); | |||
/// Retrieve the MAC address of the myo associated with an event. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_event_get_mac_address(libmyo_event_t event_opq); | |||
/// Retrieve the name of the myo associated with an event. | |||
/// Caller must free the returned string. @see libmyo_string functions. | |||
LIBMYO_EXPORT | |||
libmyo_string_t libmyo_event_get_myo_name(libmyo_event_t event); | |||
/// Components of version. | |||
typedef enum { | |||
libmyo_version_major, ///< Major version. | |||
libmyo_version_minor, ///< Minor version. | |||
libmyo_version_patch, ///< Patch version. | |||
libmyo_version_hardware_rev, ///< Hardware revision. | |||
} libmyo_version_component_t; | |||
/// Hardware revisions. | |||
typedef enum { | |||
libmyo_hardware_rev_c = 1, ///< Alpha units | |||
libmyo_hardware_rev_d = 2, ///< Consumer units | |||
} libmyo_hardware_rev_t; | |||
/// Retrieve the Myo armband's firmware version from this event. | |||
/// Valid for libmyo_event_paired and libmyo_event_connected events. | |||
LIBMYO_EXPORT | |||
unsigned int libmyo_event_get_firmware_version(libmyo_event_t event, libmyo_version_component_t); | |||
/// Enumeration identifying a right arm or left arm. @see libmyo_event_get_arm(). | |||
typedef enum { | |||
libmyo_arm_right, ///< Myo is on the right arm. | |||
libmyo_arm_left, ///< Myo is on the left arm. | |||
libmyo_arm_unknown, ///< Unknown arm. | |||
} libmyo_arm_t; | |||
/// Retrieve the arm associated with an event. | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
libmyo_arm_t libmyo_event_get_arm(libmyo_event_t event); | |||
/// Possible directions for Myo's +x axis relative to a user's arm. | |||
typedef enum { | |||
libmyo_x_direction_toward_wrist, ///< Myo's +x axis is pointing toward the user's wrist. | |||
libmyo_x_direction_toward_elbow, ///< Myo's +x axis is pointing toward the user's elbow. | |||
libmyo_x_direction_unknown, ///< Unknown +x axis direction. | |||
} libmyo_x_direction_t; | |||
/// Retrieve the x-direction associated with an event. | |||
/// The x-direction specifies which way Myo's +x axis is pointing relative to the user's arm. | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
libmyo_x_direction_t libmyo_event_get_x_direction(libmyo_event_t event); | |||
/// Possible warmup states for Myo. | |||
typedef enum { | |||
libmyo_warmup_state_unknown = 0, ///< Unknown warm up state. | |||
libmyo_warmup_state_cold = 1, ///< Myo needs to warm up. | |||
libmyo_warmup_state_warm = 2, ///< Myo is already in a warmed up state. | |||
} libmyo_warmup_state_t; | |||
/// Retrieve the warmup state of the Myo associated with an event. | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
libmyo_warmup_state_t libmyo_event_get_warmup_state(libmyo_event_t event); | |||
/// Possible warmup results for Myo. | |||
typedef enum { | |||
libmyo_warmup_result_unknown = 0, ///< Unknown warm up result. | |||
libmyo_warmup_result_success = 1, ///< The warm up period has completed successfully. | |||
libmyo_warmup_result_failed_timeout = 2, ///< The warm up period timed out. | |||
} libmyo_warmup_result_t; | |||
/// Retrieve the warmup result of the Myo associated with an event. | |||
/// Valid for libmyo_event_warmup_completed events only. | |||
LIBMYO_EXPORT | |||
libmyo_warmup_result_t libmyo_event_get_warmup_result(libmyo_event_t event); | |||
/// Retrieve the estimated rotation of Myo on the user's arm after a sync. | |||
/// The values specifies the rotation of the myo on the arm (0 - logo facing down, pi - logo facing up) | |||
/// Only supported by FW 1.3.x and above (older firmware will always report 0 for the rotation) | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_rotation_on_arm(libmyo_event_t event); | |||
/// Index into orientation data, which is provided as a quaternion. | |||
/// Orientation data is returned as a unit quaternion of floats, represented as `w + x * i + y * j + z * k`. | |||
typedef enum { | |||
libmyo_orientation_x = 0, ///< First component of the quaternion's vector part | |||
libmyo_orientation_y = 1, ///< Second component of the quaternion's vector part | |||
libmyo_orientation_z = 2, ///< Third component of the quaternion's vector part | |||
libmyo_orientation_w = 3, ///< Scalar component of the quaternion. | |||
} libmyo_orientation_index; | |||
/// Retrieve orientation data associated with an event. | |||
/// Valid for libmyo_event_orientation events only. | |||
/// @see libmyo_orientation_index | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_orientation(libmyo_event_t event, libmyo_orientation_index index); | |||
/// Retrieve raw accelerometer data associated with an event in units of g. | |||
/// Valid for libmyo_event_orientation events only. | |||
/// Requires `index < 3`. | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_accelerometer(libmyo_event_t event, unsigned int index); | |||
/// Retrieve raw gyroscope data associated with an event in units of deg/s. | |||
/// Valid for libmyo_event_orientation events only. | |||
/// Requires `index < 3`. | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_gyroscope(libmyo_event_t event, unsigned int index); | |||
/// Retrieve the pose associated with an event. | |||
/// Valid for libmyo_event_pose events only. | |||
LIBMYO_EXPORT | |||
libmyo_pose_t libmyo_event_get_pose(libmyo_event_t event); | |||
/// Retreive the RSSI associated with an event. | |||
/// Valid for libmyo_event_rssi events only. | |||
LIBMYO_EXPORT | |||
int8_t libmyo_event_get_rssi(libmyo_event_t event); | |||
/// Retrieve the battery level of the Myo armband associated with an event. | |||
/// Only valid for libmyo_event_battery_level event. | |||
LIBMYO_EXPORT | |||
uint8_t libmyo_event_get_battery_level(libmyo_event_t event); | |||
/// Retrieve an EMG data point associated with an event. | |||
/// Valid for libmyo_event_emg events only. | |||
/// @a sensor must be smaller than 8. | |||
LIBMYO_EXPORT | |||
int8_t libmyo_event_get_emg(libmyo_event_t event, unsigned int sensor); | |||
/// Return type for event handlers. | |||
typedef enum { | |||
libmyo_handler_continue, ///< Continue processing events | |||
libmyo_handler_stop, ///< Stop processing events | |||
} libmyo_handler_result_t; | |||
/// Callback function type to handle events as they occur from libmyo_run(). | |||
typedef libmyo_handler_result_t (*libmyo_handler_t)(void* user_data, libmyo_event_t event); | |||
/// Process events and call the provided callback as they occur. | |||
/// Runs for up to approximately \a duration_ms milliseconds or until a called handler returns libmyo_handler_stop. | |||
/// @returns libmyo_success after a successful run, otherwise | |||
/// - libmyo_error_invalid_argument if \a hub is NULL | |||
/// - libmyo_error_invalid_argument if \a handler is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_run(libmyo_hub_t hub, unsigned int duration_ms, libmyo_handler_t handler, void* user_data, | |||
libmyo_error_details_t* out_error); | |||
/// @} | |||
#ifdef __cplusplus | |||
} // extern "C" | |||
#endif | |||
#endif // MYO_LIBMYO_H |
@@ -0,0 +1,32 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_LIBMYO_DETAIL_VISIBILITY_H | |||
#define MYO_LIBMYO_DETAIL_VISIBILITY_H | |||
#if defined(_WIN32) || defined(__CYGWIN__) | |||
#ifdef myo_EXPORTS | |||
#ifdef __GNUC__ | |||
#define LIBMYO_EXPORT __attribute__ ((dllexport)) | |||
#else | |||
#define LIBMYO_EXPORT __declspec(dllexport) | |||
#endif | |||
#else | |||
#ifdef LIBMYO_STATIC_BUILD | |||
#define LIBMYO_EXPORT | |||
#else | |||
#ifdef __GNUC__ | |||
#define LIBMYO_EXPORT __attribute__ ((dllimport)) | |||
#else | |||
#define LIBMYO_EXPORT __declspec(dllimport) | |||
#endif | |||
#endif | |||
#endif | |||
#else | |||
#if __GNUC__ >= 4 | |||
#define LIBMYO_EXPORT __attribute__ ((visibility ("default"))) | |||
#else | |||
#define LIBMYO_EXPORT | |||
#endif | |||
#endif | |||
#endif // MYO_LIBMYO_DETAIL_VISIBILITY_H |
@@ -0,0 +1,13 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
/// The namespace in which all of the %Myo C++ bindings are contained. | |||
namespace myo {} | |||
#include "cxx/DeviceListener.hpp" | |||
#include "cxx/Hub.hpp" | |||
#include "cxx/Myo.hpp" | |||
#include "cxx/Pose.hpp" | |||
#include "cxx/Quaternion.hpp" | |||
#include "cxx/Vector3.hpp" |
@@ -0,0 +1,26 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
<plist version="1.0"> | |||
<dict> | |||
<key>CFBundleDevelopmentRegion</key> | |||
<string>English</string> | |||
<key>CFBundleExecutable</key> | |||
<string>myo</string> | |||
<key>CFBundleIconFile</key> | |||
<string></string> | |||
<key>CFBundleIdentifier</key> | |||
<string></string> | |||
<key>CFBundleInfoDictionaryVersion</key> | |||
<string>6.0</string> | |||
<key>CFBundlePackageType</key> | |||
<string>FMWK</string> | |||
<key>CFBundleSignature</key> | |||
<string>????</string> | |||
<key>CFBundleVersion</key> | |||
<string></string> | |||
<key>CFBundleShortVersionString</key> | |||
<string></string> | |||
<key>CSResourcesFileMapped</key> | |||
<true/> | |||
</dict> | |||
</plist> |
@@ -0,0 +1,197 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <stdint.h> | |||
#include "Pose.hpp" | |||
namespace myo { | |||
class Myo; | |||
template<typename T> | |||
class Quaternion; | |||
template<typename T> | |||
class Vector3; | |||
/// Enumeration identifying a right arm or left arm. | |||
enum Arm { | |||
armLeft = libmyo_arm_left, | |||
armRight = libmyo_arm_right, | |||
armUnknown = libmyo_arm_unknown | |||
}; | |||
/// Possible directions for Myo's +x axis relative to a user's arm. | |||
enum XDirection { | |||
xDirectionTowardWrist = libmyo_x_direction_toward_wrist, | |||
xDirectionTowardElbow = libmyo_x_direction_toward_elbow, | |||
xDirectionUnknown = libmyo_x_direction_unknown | |||
}; | |||
/// Possible warmup states for a Myo. | |||
enum WarmupState { | |||
warmupStateUnknown = libmyo_warmup_state_unknown, | |||
warmupStateCold = libmyo_warmup_state_cold, | |||
warmupStateWarm = libmyo_warmup_state_warm, | |||
}; | |||
/// Possible warmup results for a Myo. | |||
enum WarmupResult { | |||
warmupResultUnknown = libmyo_warmup_result_unknown, | |||
warmupResultSuccess = libmyo_warmup_result_success, | |||
warmupResultFailedTimeout = libmyo_warmup_result_failed_timeout, | |||
}; | |||
/// Firmware version of Myo. | |||
struct FirmwareVersion { | |||
unsigned int firmwareVersionMajor; ///< Myo's major version must match the required major version. | |||
unsigned int firmwareVersionMinor; ///< Myo's minor version must match the required minor version. | |||
unsigned int firmwareVersionPatch; ///< Myo's patch version must greater or equal to the required patch version. | |||
unsigned int firmwareVersionHardwareRev; ///< Myo's hardware revision; not used to detect firmware version mismatch. | |||
}; | |||
/// A DeviceListener receives events about a Myo. | |||
/// @see Hub::addListener() | |||
class DeviceListener { | |||
public: | |||
virtual ~DeviceListener() {} | |||
/// Called when a Myo has been paired. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param firmwareVersion The firmware version of \a myo. | |||
virtual void onPair(Myo* myo, uint64_t timestamp, FirmwareVersion firmwareVersion) {} | |||
/// Called when a Myo has been unpaired. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onUnpair(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo has been connected. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param firmwareVersion The firmware version of \a myo. | |||
virtual void onConnect(Myo* myo, uint64_t timestamp, FirmwareVersion firmwareVersion) {} | |||
/// Called when a paired Myo has been disconnected. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onDisconnect(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo recognizes that it is on an arm. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param arm The identified Arm of \a myo. | |||
/// @param xDirection The identified XDirection of \a myo. | |||
/// @param rotation The estimated rotation of Myo on the user's arm after a sync. | |||
/// @param warmupState The warmup state of \a myo. If \a warmupState is equal to WarmupState::warmupStateCold, | |||
/// onWarmupCompleted() will be called when the warmup period has completed. | |||
virtual void onArmSync(Myo* myo, uint64_t timestamp, Arm arm, XDirection xDirection, float rotation, | |||
WarmupState warmupState) {} | |||
/// Called when a paired Myo is moved or removed from the arm. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onArmUnsync(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo becomes unlocked. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onUnlock(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo becomes locked. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onLock(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo has provided a new pose. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param pose The identified Pose of \a myo. | |||
virtual void onPose(Myo* myo, uint64_t timestamp, Pose pose) {} | |||
/// Called when a paired Myo has provided new orientation data. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param rotation The orientation data of \a myo, as a Quaternion. | |||
virtual void onOrientationData(Myo* myo, uint64_t timestamp, const Quaternion<float>& rotation) {} | |||
/// Called when a paired Myo has provided new accelerometer data in units of g. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param accel The accelerometer data of \a myo, in units of g. | |||
virtual void onAccelerometerData(Myo* myo, uint64_t timestamp, const Vector3<float>& accel) {} | |||
/// Called when a paired Myo has provided new gyroscope data in units of deg/s. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param gyro The gyroscope data of \a myo, in units of deg/s. | |||
virtual void onGyroscopeData(Myo* myo, uint64_t timestamp, const Vector3<float>& gyro) {} | |||
/// Called when a paired Myo has provided a new RSSI value. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param rssi The RSSI (received signal strength indication) of \a myo. | |||
/// @see Myo::requestRssi() to request an RSSI value from the Myo. | |||
virtual void onRssi(Myo* myo, uint64_t timestamp, int8_t rssi) {} | |||
/// Called when a paired Myo receives an battery level update. | |||
/// Updates occur when the battery level changes and when the battery level is explicitly requested. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param level battery level reported by the myo the value is a number from 0 to 100 representing the percentage | |||
/// of battery life remaining. | |||
virtual void onBatteryLevelReceived(myo::Myo* myo, uint64_t timestamp, uint8_t level) {} | |||
/// Called when a paired Myo has provided new EMG data. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param emg An array of 8 elements, each corresponding to one sensor. | |||
virtual void onEmgData(myo::Myo* myo, uint64_t timestamp, const int8_t* emg) {} | |||
/// Called when the warmup period for a Myo has completed. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param warmupResult The warmup result of \a myo. | |||
virtual void onWarmupCompleted(myo::Myo* myo, uint64_t timestamp, WarmupResult warmupResult) {} | |||
/// @cond LIBMYO_INTERNALS | |||
virtual void onOpaqueEvent(libmyo_event_t event) {} | |||
/// @endcond | |||
}; | |||
} // namespace myo |
@@ -0,0 +1,91 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <vector> | |||
#include <myo/libmyo.h> | |||
namespace myo { | |||
class Myo; | |||
class DeviceListener; | |||
/// @brief A Hub provides access to one or more Myo instances. | |||
class Hub { | |||
public: | |||
/// Construct a hub. | |||
/// \a applicationIdentifier must follow a reverse domain name format (ex. com.domainname.appname). Application | |||
/// identifiers can be formed from the set of alphanumeric ASCII characters (a-z, A-Z, 0-9). The hyphen (-) and | |||
/// underscore (_) characters are permitted if they are not adjacent to a period (.) character (i.e. not at the | |||
/// start or end of each segment), but are not permitted in the top-level domain. Application identifiers must have | |||
/// three or more segments. For example, if a company's domain is example.com and the application is named | |||
/// hello-world, one could use "com.example.hello-world" as a valid application identifier. \a applicationIdentifier | |||
/// can be an empty string. | |||
/// Throws an exception of type std::invalid_argument if \a applicationIdentifier is not in the proper reverse | |||
/// domain name format or is longer than 255 characters. | |||
/// Throws an exception of type std::runtime_error if the hub initialization failed for some reason, typically | |||
/// because Myo Connect is not running and a connection can thus not be established. | |||
Hub(const std::string& applicationIdentifier = ""); | |||
/// Deallocate any resources associated with a Hub. | |||
/// This will cause all Myo instances retrieved from this Hub to become invalid. | |||
~Hub(); | |||
/// Wait for a Myo to become paired, or time out after \a timeout_ms milliseconds if provided. | |||
/// If \a timeout_ms is zero, this function blocks until a Myo is found. | |||
/// This function must not be called concurrently with run() or runOnce(). | |||
Myo* waitForMyo(unsigned int milliseconds = 0); | |||
/// Register a listener to be called when device events occur. | |||
void addListener(DeviceListener* listener); | |||
/// Remove a previously registered listener. | |||
void removeListener(DeviceListener* listener); | |||
/// Locking policies supported by Myo. | |||
enum LockingPolicy { | |||
lockingPolicyNone = libmyo_locking_policy_none, | |||
lockingPolicyStandard = libmyo_locking_policy_standard | |||
}; | |||
/// Set the locking policy for Myos connected to the Hub. | |||
void setLockingPolicy(LockingPolicy lockingPolicy); | |||
/// Run the event loop for the specified duration (in milliseconds). | |||
void run(unsigned int duration_ms); | |||
/// Run the event loop until a single event occurs, or the specified duration (in milliseconds) has elapsed. | |||
void runOnce(unsigned int duration_ms); | |||
/// @cond MYO_INTERNALS | |||
/// Return the internal libmyo object corresponding to this hub. | |||
libmyo_hub_t libmyoObject(); | |||
protected: | |||
void onDeviceEvent(libmyo_event_t event); | |||
Myo* lookupMyo(libmyo_myo_t opaqueMyo) const; | |||
Myo* addMyo(libmyo_myo_t opaqueMyo); | |||
libmyo_hub_t _hub; | |||
std::vector<Myo*> _myos; | |||
std::vector<DeviceListener*> _listeners; | |||
/// @endcond | |||
private: | |||
// Not implemented | |||
Hub(const Hub&); | |||
Hub& operator=(const Hub&); | |||
}; | |||
/// @example hello-myo.cpp | |||
/// @example multiple-myos.cpp | |||
/// @example emg-data-sample.cpp | |||
} // namespace myo | |||
#include "impl/Hub_impl.hpp" |
@@ -0,0 +1,83 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <myo/libmyo.h> | |||
namespace myo { | |||
/// Represents a Myo device with a specific MAC address. | |||
/// This class can not be instantiated directly; instead, use Hub to get access to a Myo. | |||
/// There is only one Myo instance corresponding to each device; thus, if the addresses of two Myo instances compare | |||
/// equal, they refer to the same device. | |||
class Myo { | |||
public: | |||
/// Types of vibration supported by the Myo. | |||
enum VibrationType { | |||
vibrationShort = libmyo_vibration_short, | |||
vibrationMedium = libmyo_vibration_medium, | |||
vibrationLong = libmyo_vibration_long | |||
}; | |||
/// Vibrate the Myo. | |||
void vibrate(VibrationType type); | |||
/// Request the RSSI of the Myo. An onRssi event will likely be generated with the value of the RSSI. | |||
/// @see DeviceListener::onRssi() | |||
void requestRssi() const; | |||
/// Request the battery level of the Myo. An onBatteryLevelReceived event will be generated with the value. | |||
/// @see DeviceListener::onBatteryLevelReceived(). | |||
void requestBatteryLevel() const; | |||
/// Unlock types supported by Myo. | |||
enum UnlockType { | |||
unlockTimed = libmyo_unlock_timed, | |||
unlockHold = libmyo_unlock_hold | |||
}; | |||
/// Unlock the Myo. | |||
/// Myo will remain unlocked for a short amount of time, after which it will automatically lock again. | |||
/// If Myo was locked, an onUnlock event will be generated. | |||
void unlock(UnlockType type); | |||
/// Force the Myo to lock immediately. | |||
/// If Myo was unlocked, an onLock event will be generated. | |||
void lock(); | |||
/// Notify the Myo that a user action was recognized. | |||
/// Will cause Myo to vibrate. | |||
void notifyUserAction(); | |||
/// Valid EMG streaming modes for a Myo. | |||
enum StreamEmgType { | |||
streamEmgDisabled = libmyo_stream_emg_disabled, | |||
streamEmgEnabled = libmyo_stream_emg_enabled | |||
}; | |||
/// Sets the EMG streaming mode for a Myo. | |||
void setStreamEmg(StreamEmgType type); | |||
/// @cond MYO_INTERNALS | |||
/// Return the internal libmyo object corresponding to this device. | |||
libmyo_myo_t libmyoObject() const; | |||
/// @endcond | |||
private: | |||
Myo(libmyo_myo_t myo); | |||
~Myo(); | |||
libmyo_myo_t _myo; | |||
// Not implemented. | |||
Myo(const Myo&); | |||
Myo& operator=(const Myo&); | |||
friend class Hub; | |||
}; | |||
} // namespace myo | |||
#include "impl/Myo_impl.hpp" |
@@ -0,0 +1,70 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <iosfwd> | |||
#include <string> | |||
#include <myo/libmyo.h> | |||
namespace myo { | |||
/// A pose represents a detected configuration of the user's hand. | |||
class Pose { | |||
public: | |||
/// Types of poses supported by the SDK. | |||
enum Type { | |||
rest = libmyo_pose_rest, | |||
fist = libmyo_pose_fist, | |||
waveIn = libmyo_pose_wave_in, | |||
waveOut = libmyo_pose_wave_out, | |||
fingersSpread = libmyo_pose_fingers_spread, | |||
doubleTap = libmyo_pose_double_tap, | |||
unknown = libmyo_pose_unknown | |||
}; | |||
/// Construct a pose of type Pose::none. | |||
Pose(); | |||
/// Construct a pose with the given type. | |||
Pose(Type type); | |||
/// Returns true if and only if the two poses are of the same type. | |||
bool operator==(Pose other) const; | |||
/// Equivalent to `!(*this == other)`. | |||
bool operator!=(Pose other) const; | |||
/// Returns the type of this pose. | |||
Type type() const; | |||
/// Return a human-readable string representation of the pose. | |||
std::string toString() const; | |||
private: | |||
Type _type; | |||
}; | |||
/// @relates Pose | |||
/// Returns true if and only if the type of pose is the same as the provided type. | |||
bool operator==(Pose pose, Pose::Type t); | |||
/// @relates Pose | |||
/// Equivalent to `pose == type`. | |||
bool operator==(Pose::Type type, Pose pose); | |||
/// @relates Pose | |||
/// Equivalent to `!(pose == type)`. | |||
bool operator!=(Pose pose, Pose::Type type); | |||
/// @relates Pose | |||
/// Equivalent to `!(type == pose)`. | |||
bool operator!=(Pose::Type type, Pose pose); | |||
/// @relates Pose | |||
/// Write the name of the provided pose to the provided output stream. | |||
std::ostream& operator<<(std::ostream& out, const Pose& pose); | |||
} // namespace myo | |||
#include "impl/Pose_impl.hpp" |
@@ -0,0 +1,158 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <cmath> | |||
#include "Vector3.hpp" | |||
namespace myo { | |||
/// A quaternion that can be used to represent a rotation. | |||
/// This type provides only very basic functionality to store quaternions that's sufficient to retrieve the data to | |||
/// be placed in a full featured quaternion type. | |||
template<typename T> | |||
class Quaternion { | |||
public: | |||
/// Construct a quaternion that represents zero rotation (i.e. the multiplicative identity). | |||
Quaternion() | |||
: _x(0) | |||
, _y(0) | |||
, _z(0) | |||
, _w(1) | |||
{ | |||
} | |||
/// Construct a quaternion with the provided components. | |||
Quaternion(T x, T y, T z, T w) | |||
: _x(x) | |||
, _y(y) | |||
, _z(z) | |||
, _w(w) | |||
{ | |||
} | |||
/// Set the components of this quaternion to be those of the other. | |||
Quaternion& operator=(const Quaternion other) | |||
{ | |||
_x = other._x; | |||
_y = other._y; | |||
_z = other._z; | |||
_w = other._w; | |||
return *this; | |||
} | |||
/// Return the x-component of this quaternion's vector. | |||
T x() const { return _x; } | |||
/// Return the y-component of this quaternion's vector. | |||
T y() const { return _y; } | |||
/// Return the z-component of this quaternion's vector. | |||
T z() const { return _z; } | |||
/// Return the w-component (scalar) of this quaternion. | |||
T w() const { return _w; } | |||
/// Return the quaternion multiplied by \a rhs. | |||
/// Note that quaternion multiplication is not commutative. | |||
Quaternion operator*(const Quaternion& rhs) const | |||
{ | |||
return Quaternion( | |||
_w * rhs._x + _x * rhs._w + _y * rhs._z - _z * rhs._y, | |||
_w * rhs._y - _x * rhs._z + _y * rhs._w + _z * rhs._x, | |||
_w * rhs._z + _x * rhs._y - _y * rhs._x + _z * rhs._w, | |||
_w * rhs._w - _x * rhs._x - _y * rhs._y - _z * rhs._z | |||
); | |||
} | |||
/// Multiply this quaternion by \a rhs. | |||
/// Return this quaternion updated with the result. | |||
Quaternion& operator*=(const Quaternion& rhs) | |||
{ | |||
*this = *this * rhs; | |||
return *this; | |||
} | |||
/// Return the unit quaternion corresponding to the same rotation as this one. | |||
Quaternion normalized() const | |||
{ | |||
T magnitude = std::sqrt(_x * _x + _y * _y + _z * _z + _w * _w); | |||
return Quaternion(_x / magnitude, _y / magnitude, _z / magnitude, _w / magnitude); | |||
} | |||
/// Return this quaternion's conjugate. | |||
Quaternion conjugate() const | |||
{ | |||
return Quaternion(-_x, -_y, -_z, _w); | |||
} | |||
/// Return a quaternion that represents a right-handed rotation of \a angle radians about the given \a axis. | |||
/// \a axis The unit vector representing the axis of rotation. | |||
/// \a angle The angle of rotation, in radians. | |||
static Quaternion fromAxisAngle(const myo::Vector3<T>& axis, T angle) | |||
{ | |||
return Quaternion(axis.x() * std::sin(angle / 2), | |||
axis.y() * std::sin(angle / 2), | |||
axis.z() * std::sin(angle / 2), | |||
std::cos(angle / 2)); | |||
} | |||
private: | |||
T _x, _y, _z, _w; | |||
}; | |||
/// Return a copy of this \a vec rotated by \a quat. | |||
/// \relates myo::Quaternion | |||
template<typename T> | |||
Vector3<T> rotate(const Quaternion<T>& quat, const Vector3<T>& vec) | |||
{ | |||
myo::Quaternion<T> qvec(vec.x(), vec.y(), vec.z(), 0); | |||
myo::Quaternion<T> result = quat * qvec * quat.conjugate(); | |||
return Vector3<T>(result.x(), result.y(), result.z()); | |||
} | |||
/// Return a quaternion that represents a rotation from vector \a from to \a to. | |||
/// \relates myo::Quaternion | |||
/// See http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another | |||
/// for some explanation. | |||
template<typename T> | |||
Quaternion<T> rotate(const Vector3<T>& from, const Vector3<T>& to) | |||
{ | |||
Vector3<T> cross = from.cross(to); | |||
// The product of the square of magnitudes and the cosine of the angle between from and to. | |||
T cosTheta = from.dot(to); | |||
// Return identity if the vectors are the same direction. | |||
if (cosTheta >= 1) { | |||
return Quaternion<T>(); | |||
} | |||
// The product of the square of the magnitudes | |||
T k = std::sqrt(from.dot(from) * to.dot(to)); | |||
// Return identity in the degenerate case. | |||
if (k <= 0) { | |||
return Quaternion<T>(); | |||
} | |||
// Special handling for vectors facing opposite directions. | |||
if (cosTheta / k <= -1) { | |||
Vector3<T> xAxis(1, 0, 0); | |||
Vector3<T> yAxis(0, 1, 0); | |||
cross = from.cross(std::abs(from.dot(xAxis)) < 1 ? xAxis : yAxis); | |||
k = cosTheta = 0; | |||
} | |||
return Quaternion<T>( | |||
cross.x(), | |||
cross.y(), | |||
cross.z(), | |||
k + cosTheta); | |||
} | |||
} // namespace myo |
@@ -0,0 +1,103 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#define _USE_MATH_DEFINES | |||
#include <cmath> | |||
namespace myo { | |||
/// A vector of three components. | |||
/// This type provides very basic functionality to store a three dimensional vector that's sufficient to retrieve | |||
/// the data to be placed in a full featured vector type. A few common vector operations, such as dot product and | |||
/// cross product, are also provided. | |||
template<typename T> | |||
class Vector3 { | |||
public: | |||
/// Construct a vector of all zeroes. | |||
Vector3() | |||
{ | |||
_data[0] = 0; | |||
_data[1] = 0; | |||
_data[2] = 0; | |||
} | |||
/// Construct a vector with the three provided components. | |||
Vector3(T x, T y, T z) | |||
{ | |||
_data[0] = x; | |||
_data[1] = y; | |||
_data[2] = z; | |||
} | |||
/// Construct a vector with the same components as \a other. | |||
Vector3(const Vector3& other) | |||
{ | |||
*this = other; | |||
} | |||
/// Set the components of this vector to be the same as \a other. | |||
Vector3& operator=(const Vector3& other) | |||
{ | |||
_data[0] = other._data[0]; | |||
_data[1] = other._data[1]; | |||
_data[2] = other._data[2]; | |||
return *this; | |||
} | |||
/// Return a copy of the component of this vector at \a index, which should be 0, 1, or 2. | |||
T operator[](unsigned int index) const | |||
{ | |||
return _data[index]; | |||
} | |||
/// Return the x-component of this vector. | |||
T x() const { return _data[0]; } | |||
/// Return the y-component of this vector. | |||
T y() const { return _data[1]; } | |||
/// Return the z-component of this vector. | |||
T z() const { return _data[2]; } | |||
/// Return the magnitude of this vector. | |||
T magnitude() const | |||
{ | |||
return std::sqrt(x() * x() + y() * y() + z() * z()); | |||
} | |||
/// Return a normalized copy of this vector. | |||
Vector3 normalized() const | |||
{ | |||
T norm = magnitude(); | |||
return Vector3(x() / norm, y() / norm, z() / norm); | |||
} | |||
/// Return the dot product of this vector and \a rhs. | |||
T dot(const Vector3& rhs) const | |||
{ | |||
return x() * rhs.x() + y() * rhs.y() + z() * rhs.z(); | |||
} | |||
/// Return the cross product of this vector and \a rhs. | |||
Vector3 cross(const Vector3& rhs) const | |||
{ | |||
return Vector3( | |||
y() * rhs.z() - z() * rhs.y(), | |||
z() * rhs.x() - x() * rhs.z(), | |||
x() * rhs.y() - y() * rhs.x() | |||
); | |||
} | |||
/// Return the angle between this vector and \a rhs, in radians. | |||
T angleTo(const Vector3& rhs) const | |||
{ | |||
return std::acos(dot(rhs) / (magnitude() * rhs.magnitude())); | |||
} | |||
private: | |||
T _data[3]; | |||
}; | |||
} // namespace myo |
@@ -0,0 +1,70 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_CXX_DETAIL_THROWONERROR_HPP | |||
#define MYO_CXX_DETAIL_THROWONERROR_HPP | |||
#include <stdexcept> | |||
#include <myo/libmyo.h> | |||
#if defined(_MSC_VER) && _MSC_VER <= 1800 | |||
#define LIBMYO_NOEXCEPT(b) | |||
#else | |||
#if __cplusplus >= 201103L | |||
# define LIBMYO_NOEXCEPT(b) noexcept(b) | |||
#else | |||
# define LIBMYO_NOEXCEPT(b) | |||
#endif | |||
#endif | |||
namespace myo { | |||
class ThrowOnError { | |||
public: | |||
ThrowOnError() | |||
: _error() | |||
{ | |||
} | |||
~ThrowOnError() LIBMYO_NOEXCEPT(false) | |||
{ | |||
if (_error) | |||
{ | |||
switch (libmyo_error_kind(_error)) { | |||
case libmyo_error: | |||
case libmyo_error_runtime: | |||
{ | |||
std::runtime_error exception(libmyo_error_cstring(_error)); | |||
libmyo_free_error_details(_error); | |||
throw exception; | |||
} | |||
case libmyo_error_invalid_argument: | |||
{ | |||
std::invalid_argument exception(libmyo_error_cstring(_error)); | |||
libmyo_free_error_details(_error); | |||
throw exception; | |||
} | |||
case libmyo_success: | |||
{ | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
operator libmyo_error_details_t*() | |||
{ | |||
return &_error; | |||
} | |||
private: | |||
libmyo_error_details_t _error; | |||
// Not implemented | |||
ThrowOnError(const ThrowOnError&); // = delete; | |||
ThrowOnError& operator=(const ThrowOnError&); // = delete; | |||
}; | |||
} //namespace libmyo | |||
#endif // MYO_CXX_DETAIL_THROWONERROR_HPP |
@@ -0,0 +1,265 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#include "../Hub.hpp" | |||
#include <algorithm> | |||
#include <exception> | |||
#include "../DeviceListener.hpp" | |||
#include "../Myo.hpp" | |||
#include "../Pose.hpp" | |||
#include "../Quaternion.hpp" | |||
#include "../Vector3.hpp" | |||
#include "../detail/ThrowOnError.hpp" | |||
namespace myo { | |||
inline | |||
Hub::Hub(const std::string& applicationIdentifier) | |||
: _hub(0) | |||
, _myos() | |||
, _listeners() | |||
{ | |||
libmyo_init_hub(&_hub, applicationIdentifier.c_str(), ThrowOnError()); | |||
} | |||
inline | |||
Hub::~Hub() | |||
{ | |||
for (std::vector<Myo*>::iterator I = _myos.begin(), IE = _myos.end(); I != IE; ++I) { | |||
delete *I; | |||
} | |||
libmyo_shutdown_hub(_hub, 0); | |||
} | |||
inline | |||
Myo* Hub::waitForMyo(unsigned int timeout_ms) | |||
{ | |||
std::size_t prevSize = _myos.size(); | |||
struct local { | |||
static libmyo_handler_result_t handler(void* user_data, libmyo_event_t event) { | |||
Hub* hub = static_cast<Hub*>(user_data); | |||
libmyo_myo_t opaque_myo = libmyo_event_get_myo(event); | |||
switch (libmyo_event_get_type(event)) { | |||
case libmyo_event_paired: | |||
hub->addMyo(opaque_myo); | |||
return libmyo_handler_stop; | |||
default: | |||
break; | |||
} | |||
return libmyo_handler_continue; | |||
} | |||
}; | |||
do { | |||
libmyo_run(_hub, timeout_ms ? timeout_ms : 1000, &local::handler, this, ThrowOnError()); | |||
} while (!timeout_ms && _myos.size() <= prevSize); | |||
if (_myos.size() <= prevSize) { | |||
return 0; | |||
} | |||
return _myos.back(); | |||
} | |||
inline | |||
void Hub::addListener(DeviceListener* listener) | |||
{ | |||
if (std::find(_listeners.begin(), _listeners.end(), listener) != _listeners.end()) { | |||
// Listener was already added. | |||
return; | |||
} | |||
_listeners.push_back(listener); | |||
} | |||
inline | |||
void Hub::removeListener(DeviceListener* listener) | |||
{ | |||
std::vector<DeviceListener*>::iterator I = std::find(_listeners.begin(), _listeners.end(), listener); | |||
if (I == _listeners.end()) { | |||
// Don't have this listener. | |||
return; | |||
} | |||
_listeners.erase(I); | |||
} | |||
inline | |||
void Hub::setLockingPolicy(LockingPolicy lockingPolicy) | |||
{ | |||
libmyo_set_locking_policy(_hub, static_cast<libmyo_locking_policy_t>(lockingPolicy), ThrowOnError()); | |||
} | |||
inline | |||
void Hub::onDeviceEvent(libmyo_event_t event) | |||
{ | |||
libmyo_myo_t opaqueMyo = libmyo_event_get_myo(event); | |||
Myo* myo = lookupMyo(opaqueMyo); | |||
if (!myo && libmyo_event_get_type(event) == libmyo_event_paired) { | |||
myo = addMyo(opaqueMyo); | |||
} | |||
if (!myo) { | |||
// Ignore events for Myos we don't know about. | |||
return; | |||
} | |||
for (std::vector<DeviceListener*>::iterator I = _listeners.begin(), IE = _listeners.end(); I != IE; ++I) { | |||
DeviceListener* listener = *I; | |||
listener->onOpaqueEvent(event); | |||
uint64_t time = libmyo_event_get_timestamp(event); | |||
switch (libmyo_event_get_type(event)) { | |||
case libmyo_event_paired: { | |||
FirmwareVersion version = {libmyo_event_get_firmware_version(event, libmyo_version_major), | |||
libmyo_event_get_firmware_version(event, libmyo_version_minor), | |||
libmyo_event_get_firmware_version(event, libmyo_version_patch), | |||
libmyo_event_get_firmware_version(event, libmyo_version_hardware_rev)}; | |||
listener->onPair(myo, time, version); | |||
break; | |||
} | |||
case libmyo_event_unpaired: | |||
listener->onUnpair(myo, time); | |||
break; | |||
case libmyo_event_connected: { | |||
FirmwareVersion version = {libmyo_event_get_firmware_version(event, libmyo_version_major), | |||
libmyo_event_get_firmware_version(event, libmyo_version_minor), | |||
libmyo_event_get_firmware_version(event, libmyo_version_patch), | |||
libmyo_event_get_firmware_version(event, libmyo_version_hardware_rev)}; | |||
listener->onConnect(myo, time, version); | |||
break; | |||
} | |||
case libmyo_event_disconnected: | |||
listener->onDisconnect(myo, time); | |||
break; | |||
case libmyo_event_arm_synced: | |||
listener->onArmSync(myo, time, | |||
static_cast<Arm>(libmyo_event_get_arm(event)), | |||
static_cast<XDirection>(libmyo_event_get_x_direction(event)), | |||
libmyo_event_get_rotation_on_arm(event), | |||
static_cast<WarmupState>(libmyo_event_get_warmup_state(event))); | |||
break; | |||
case libmyo_event_arm_unsynced: | |||
listener->onArmUnsync(myo, time); | |||
break; | |||
case libmyo_event_unlocked: | |||
listener->onUnlock(myo, time); | |||
break; | |||
case libmyo_event_locked: | |||
listener->onLock(myo, time); | |||
break; | |||
case libmyo_event_orientation: | |||
listener->onOrientationData(myo, time, | |||
Quaternion<float>(libmyo_event_get_orientation(event, libmyo_orientation_x), | |||
libmyo_event_get_orientation(event, libmyo_orientation_y), | |||
libmyo_event_get_orientation(event, libmyo_orientation_z), | |||
libmyo_event_get_orientation(event, libmyo_orientation_w))); | |||
listener->onAccelerometerData(myo, time, | |||
Vector3<float>(libmyo_event_get_accelerometer(event, 0), | |||
libmyo_event_get_accelerometer(event, 1), | |||
libmyo_event_get_accelerometer(event, 2))); | |||
listener->onGyroscopeData(myo, time, | |||
Vector3<float>(libmyo_event_get_gyroscope(event, 0), | |||
libmyo_event_get_gyroscope(event, 1), | |||
libmyo_event_get_gyroscope(event, 2))); | |||
break; | |||
case libmyo_event_pose: | |||
listener->onPose(myo, time, Pose(static_cast<Pose::Type>(libmyo_event_get_pose(event)))); | |||
break; | |||
case libmyo_event_rssi: | |||
listener->onRssi(myo, time, libmyo_event_get_rssi(event)); | |||
break; | |||
case libmyo_event_battery_level: | |||
listener->onBatteryLevelReceived(myo, time, libmyo_event_get_battery_level(event)); | |||
break; | |||
case libmyo_event_emg: { | |||
int8_t emg[] = { libmyo_event_get_emg(event, 0), | |||
libmyo_event_get_emg(event, 1), | |||
libmyo_event_get_emg(event, 2), | |||
libmyo_event_get_emg(event, 3), | |||
libmyo_event_get_emg(event, 4), | |||
libmyo_event_get_emg(event, 5), | |||
libmyo_event_get_emg(event, 6), | |||
libmyo_event_get_emg(event, 7) }; | |||
listener->onEmgData(myo, time, emg); | |||
break; | |||
} | |||
case libmyo_event_warmup_completed: { | |||
listener->onWarmupCompleted(myo, time, static_cast<WarmupResult>(libmyo_event_get_warmup_result(event))); | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
inline | |||
void Hub::run(unsigned int duration_ms) | |||
{ | |||
struct local { | |||
static libmyo_handler_result_t handler(void* user_data, libmyo_event_t event) { | |||
Hub* hub = static_cast<Hub*>(user_data); | |||
hub->onDeviceEvent(event); | |||
return libmyo_handler_continue; | |||
} | |||
}; | |||
libmyo_run(_hub, duration_ms, &local::handler, this, ThrowOnError()); | |||
} | |||
inline | |||
void Hub::runOnce(unsigned int duration_ms) | |||
{ | |||
struct local { | |||
static libmyo_handler_result_t handler(void* user_data, libmyo_event_t event) { | |||
Hub* hub = static_cast<Hub*>(user_data); | |||
hub->onDeviceEvent(event); | |||
return libmyo_handler_stop; | |||
} | |||
}; | |||
libmyo_run(_hub, duration_ms, &local::handler, this, ThrowOnError()); | |||
} | |||
inline | |||
libmyo_hub_t Hub::libmyoObject() | |||
{ | |||
return _hub; | |||
} | |||
inline | |||
Myo* Hub::lookupMyo(libmyo_myo_t opaqueMyo) const | |||
{ | |||
Myo* myo = 0; | |||
for (std::vector<Myo*>::const_iterator I = _myos.begin(), IE = _myos.end(); I != IE; ++I) { | |||
if ((*I)->libmyoObject() == opaqueMyo) { | |||
myo = *I; | |||
break; | |||
} | |||
} | |||
return myo; | |||
} | |||
inline | |||
Myo* Hub::addMyo(libmyo_myo_t opaqueMyo) | |||
{ | |||
Myo* myo = new Myo(opaqueMyo); | |||
_myos.push_back(myo); | |||
return myo; | |||
} | |||
} // namespace myo |
@@ -0,0 +1,72 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#include "../Myo.hpp" | |||
#include "../detail/ThrowOnError.hpp" | |||
#include <stdexcept> | |||
namespace myo { | |||
inline | |||
void Myo::vibrate(VibrationType type) | |||
{ | |||
libmyo_vibrate(_myo, static_cast<libmyo_vibration_type_t>(type), ThrowOnError()); | |||
} | |||
inline | |||
void Myo::requestRssi() const | |||
{ | |||
libmyo_request_rssi(_myo, ThrowOnError()); | |||
} | |||
inline | |||
void Myo::requestBatteryLevel() const | |||
{ | |||
libmyo_request_battery_level(_myo, myo::ThrowOnError()); | |||
} | |||
inline | |||
void Myo::unlock(UnlockType type) | |||
{ | |||
libmyo_myo_unlock(_myo, static_cast<libmyo_unlock_type_t>(type), ThrowOnError()); | |||
} | |||
inline | |||
void Myo::lock() | |||
{ | |||
libmyo_myo_lock(_myo, ThrowOnError()); | |||
} | |||
inline | |||
void Myo::notifyUserAction() | |||
{ | |||
libmyo_myo_notify_user_action(_myo, libmyo_user_action_single, ThrowOnError()); | |||
} | |||
inline | |||
void Myo::setStreamEmg(StreamEmgType type) | |||
{ | |||
libmyo_set_stream_emg(_myo, static_cast<libmyo_stream_emg_t>(type), ThrowOnError()); | |||
} | |||
inline | |||
libmyo_myo_t Myo::libmyoObject() const | |||
{ | |||
return _myo; | |||
} | |||
inline | |||
Myo::Myo(libmyo_myo_t myo) | |||
: _myo(myo) | |||
{ | |||
if (!_myo) { | |||
throw std::invalid_argument("Cannot construct Myo instance with null pointer"); | |||
} | |||
} | |||
inline | |||
Myo::~Myo() | |||
{ | |||
} | |||
} // namespace myo |
@@ -0,0 +1,97 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_CXX_IMPL_POSE_IMPL_HPP | |||
#define MYO_CXX_IMPL_POSE_IMPL_HPP | |||
#include "../Pose.hpp" | |||
#include <iostream> | |||
namespace myo { | |||
inline | |||
Pose::Pose() | |||
: _type(unknown) | |||
{ | |||
} | |||
inline | |||
Pose::Pose(Pose::Type type) | |||
: _type(type) | |||
{ | |||
} | |||
inline | |||
bool Pose::operator==(Pose other) const | |||
{ | |||
return _type == other._type; | |||
} | |||
inline | |||
bool Pose::operator!=(Pose other) const | |||
{ | |||
return !(*this == other); | |||
} | |||
inline | |||
Pose::Type Pose::type() const | |||
{ | |||
return _type; | |||
} | |||
inline | |||
bool operator==(Pose pose, Pose::Type type) | |||
{ | |||
return pose.type() == type; | |||
} | |||
inline | |||
bool operator==(Pose::Type type, Pose pose) | |||
{ | |||
return pose == type; | |||
} | |||
inline | |||
bool operator!=(Pose pose, Pose::Type type) | |||
{ | |||
return !(pose == type); | |||
} | |||
inline | |||
bool operator!=(Pose::Type type, Pose pose) | |||
{ | |||
return !(type == pose); | |||
} | |||
inline | |||
std::string Pose::toString() const | |||
{ | |||
switch (type()) { | |||
case Pose::rest: | |||
return "rest"; | |||
case Pose::fist: | |||
return "fist"; | |||
case Pose::waveIn: | |||
return "waveIn"; | |||
case Pose::waveOut: | |||
return "waveOut"; | |||
case Pose::fingersSpread: | |||
return "fingersSpread"; | |||
case Pose::doubleTap: | |||
return "doubleTap"; | |||
case Pose::unknown: | |||
return "unknown"; | |||
} | |||
return "<invalid>"; | |||
} | |||
inline | |||
std::ostream& operator<<(std::ostream& out, const Pose& pose) | |||
{ | |||
return out << pose.toString(); | |||
} | |||
} // namespace myo | |||
#endif // MYO_CXX_IMPL_POSE_IMPL_HPP |
@@ -0,0 +1,425 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_LIBMYO_H | |||
#define MYO_LIBMYO_H | |||
#include <stdint.h> | |||
#include "libmyo/detail/visibility.h" | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/// @file libmyo.h | |||
/// libmyo C API declarations. | |||
typedef void* libmyo_hub_t; | |||
/// \defgroup errors Error Handling | |||
/// @{ | |||
/// Function result codes. | |||
/// All libmyo functions that can fail return a value of this type. | |||
typedef enum { | |||
libmyo_success, | |||
libmyo_error, | |||
libmyo_error_invalid_argument, | |||
libmyo_error_runtime | |||
} libmyo_result_t; | |||
/// Opaque handle to detailed error information. | |||
typedef void* libmyo_error_details_t; | |||
/// Return a null-terminated string with a detailed error message. | |||
LIBMYO_EXPORT | |||
const char* libmyo_error_cstring(libmyo_error_details_t); | |||
/// Returns the kind of error that occurred. | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_error_kind(libmyo_error_details_t); | |||
/// Free the resources allocated by an error object. | |||
LIBMYO_EXPORT | |||
void libmyo_free_error_details(libmyo_error_details_t); | |||
/// @} | |||
/// \defgroup libmyo_string Strings | |||
/// @{ | |||
// Opaque string. | |||
typedef void* libmyo_string_t; | |||
// Return a null-terminated string from the opaque string. | |||
LIBMYO_EXPORT | |||
const char* libmyo_string_c_str(libmyo_string_t); | |||
// Free the resources allocated by the string object. | |||
LIBMYO_EXPORT | |||
void libmyo_string_free(libmyo_string_t); | |||
/// @} | |||
/// \defgroup libmyo_direct_mac_addresses MAC address utilities | |||
/// @{ | |||
/// Retrieve the string representation of a MAC address in hex. | |||
/// Returns a string in the format of 00-00-00-00-00-00. | |||
LIBMYO_EXPORT | |||
libmyo_string_t libmyo_mac_address_to_string(uint64_t); | |||
/// Retrieve the MAC address from a null-terminated string in the format of 00-00-00-00-00-00. | |||
/// Returns 0 if the string does not match the format. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_string_to_mac_address(const char*); | |||
/// @} | |||
/// @defgroup libmyo_hub Hub instance | |||
/// @{ | |||
/// Initialize a connection to the hub. | |||
/// \a application_identifier must follow a reverse domain name format (ex. com.domainname.appname). Application | |||
/// identifiers can be formed from the set of alphanumeric ASCII characters (a-z, A-Z, 0-9). The hyphen (-) and | |||
/// underscore (_) characters are permitted if they are not adjacent to a period (.) character (i.e. not at the start or | |||
/// end of each segment), but are not permitted in the top-level domain. Application identifiers must have three or more | |||
/// segments. For example, if a company's domain is example.com and the application is named hello-world, one could use | |||
/// "com.example.hello-world" as a valid application identifier. \a application_identifier can be NULL or empty. | |||
/// @returns libmyo_success if the connection is successfully established, otherwise: | |||
/// - libmyo_error_runtime if a connection could not be established | |||
/// - libmyo_error_invalid_argument if \a out_hub is NULL | |||
/// - libmyo_error_invalid_argument if \a application_identifier is longer than 255 characters | |||
/// - libmyo_error_invalid_argument if \a application_identifier is not in the proper reverse domain name format | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_init_hub(libmyo_hub_t* out_hub, const char* application_identifier, | |||
libmyo_error_details_t* out_error); | |||
/// Free the resources allocated to a hub. | |||
/// @returns libmyo_success if shutdown is successful, otherwise: | |||
/// - libmyo_error_invalid_argument if \a hub is NULL | |||
/// - libmyo_error if \a hub is not a valid hub | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_shutdown_hub(libmyo_hub_t hub, libmyo_error_details_t* out_error); | |||
// Locking policies. | |||
typedef enum { | |||
libmyo_locking_policy_none, ///< Pose events are always sent. | |||
libmyo_locking_policy_standard ///< Pose events are not sent while a Myo is locked. | |||
} libmyo_locking_policy_t; | |||
/// Set the locking policy for Myos connected to the hub. | |||
/// @returns libmyo_success if the locking policy is successfully set, otherwise | |||
/// - libmyo_error_invalid_argument if \a hub is NULL | |||
/// - libmyo_error if \a hub is not a valid hub | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_set_locking_policy(libmyo_hub_t hub, libmyo_locking_policy_t locking_policy, | |||
libmyo_error_details_t* out_error); | |||
/// @} | |||
/// @defgroup libmyo_myo Myo instances | |||
/// @{ | |||
/// Opaque type corresponding to a known Myo device. | |||
typedef void* libmyo_myo_t; | |||
/// Types of vibration | |||
typedef enum { | |||
libmyo_vibration_short, | |||
libmyo_vibration_medium, | |||
libmyo_vibration_long | |||
} libmyo_vibration_type_t; | |||
/// Retrieve the MAC address of a Myo. | |||
/// The MAC address is unique to the physical Myo, and is a 48-bit number. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_get_mac_address(libmyo_myo_t myo); | |||
/// Vibrate the given myo. | |||
/// Can be called when a Myo is paired. | |||
/// @returns libmyo_success if the Myo successfully vibrated, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_vibrate(libmyo_myo_t myo, libmyo_vibration_type_t type, libmyo_error_details_t* out_error); | |||
/// Request the RSSI for a given myo. | |||
/// Can be called when a Myo is paired. A libmyo_event_rssi event will likely be generated with the value of the RSSI. | |||
/// @returns libmyo_success if the Myo successfully got the RSSI, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_request_rssi(libmyo_myo_t myo, libmyo_error_details_t* out_error); | |||
/// Request the battery level for a given Myo. | |||
/// A libmyo_event_battery_level event will be generated with the value of the battery level. | |||
/// @returns libmyo_success if the Myo successfully requested the battery level, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_request_battery_level(libmyo_myo_t myo_opq, libmyo_error_details_t* out_error); | |||
/// EMG streaming modes. | |||
typedef enum { | |||
libmyo_stream_emg_disabled, ///< Do not send EMG data. | |||
libmyo_stream_emg_enabled ///< Send EMG data. | |||
} libmyo_stream_emg_t; | |||
/// Set whether or not to stream EMG data for a given myo. | |||
/// Can be called when a Myo is paired. | |||
/// @returns libmyo_success if the EMG mode was set successfully, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_set_stream_emg(libmyo_myo_t myo, libmyo_stream_emg_t emg, libmyo_error_details_t* out_error); | |||
/// @} | |||
/// @defgroup libmyo_poses Pose recognition. | |||
/// @{ | |||
/// Supported poses. | |||
typedef enum { | |||
libmyo_pose_rest = 0, ///< Rest pose. | |||
libmyo_pose_fist = 1, ///< User is making a fist. | |||
libmyo_pose_wave_in = 2, ///< User has an open palm rotated towards the posterior of their wrist. | |||
libmyo_pose_wave_out = 3, ///< User has an open palm rotated towards the anterior of their wrist. | |||
libmyo_pose_fingers_spread = 4, ///< User has an open palm with their fingers spread away from each other. | |||
libmyo_pose_double_tap = 5, ///< User tapped their thumb and middle finger together twice in succession. | |||
libmyo_num_poses, ///< Number of poses supported; not a valid pose. | |||
libmyo_pose_unknown = 0xffff ///< Unknown pose. | |||
} libmyo_pose_t; | |||
/// @} | |||
/// @defgroup libmyo_locking Myo locking mechanism | |||
/// Valid unlock types. | |||
typedef enum { | |||
libmyo_unlock_timed = 0, ///< Unlock for a fixed period of time. | |||
libmyo_unlock_hold = 1, ///< Unlock until explicitly told to re-lock. | |||
} libmyo_unlock_type_t; | |||
/// Unlock the given Myo. | |||
/// Can be called when a Myo is paired. A libmyo_event_unlocked event will be generated if the Myo was locked. | |||
/// @returns libmyo_success if the Myo was successfully unlocked, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_myo_unlock(libmyo_myo_t myo, libmyo_unlock_type_t type, libmyo_error_details_t* out_error); | |||
/// Lock the given Myo immediately. | |||
/// Can be called when a Myo is paired. A libmyo_event_locked event will be generated if the Myo was unlocked. | |||
/// @returns libmyo_success if the Myo was successfully locked, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_myo_lock(libmyo_myo_t myo, libmyo_error_details_t* out_error); | |||
/// User action types. | |||
typedef enum { | |||
libmyo_user_action_single = 0, ///< User did a single, discrete action, such as pausing a video. | |||
} libmyo_user_action_type_t; | |||
/// Notify the given Myo that a user action was recognized. | |||
/// Can be called when a Myo is paired. Will cause Myo to vibrate. | |||
/// @returns libmyo_success if the Myo was successfully notified, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_myo_notify_user_action(libmyo_myo_t myo, libmyo_user_action_type_t type, | |||
libmyo_error_details_t* out_error); | |||
/// @} | |||
/// @defgroup libmyo_events Event Handling | |||
/// @{ | |||
/// Types of events. | |||
typedef enum { | |||
libmyo_event_paired, ///< Successfully paired with a Myo. | |||
libmyo_event_unpaired, ///< Successfully unpaired from a Myo. | |||
libmyo_event_connected, ///< A Myo has successfully connected. | |||
libmyo_event_disconnected, ///< A Myo has been disconnected. | |||
libmyo_event_arm_synced, ///< A Myo has recognized that the sync gesture has been successfully performed. | |||
libmyo_event_arm_unsynced, ///< A Myo has been moved or removed from the arm. | |||
libmyo_event_orientation, ///< Orientation data has been received. | |||
libmyo_event_pose, ///< A change in pose has been detected. @see libmyo_pose_t. | |||
libmyo_event_rssi, ///< An RSSI value has been received. | |||
libmyo_event_unlocked, ///< A Myo has become unlocked. | |||
libmyo_event_locked, ///< A Myo has become locked. | |||
libmyo_event_emg, ///< EMG data has been received. | |||
libmyo_event_battery_level, ///< A battery level value has been received. | |||
libmyo_event_warmup_completed, ///< The warmup period has completed. | |||
} libmyo_event_type_t; | |||
/// Information about an event. | |||
typedef const void* libmyo_event_t; | |||
/// Retrieve the type of an event. | |||
LIBMYO_EXPORT | |||
uint32_t libmyo_event_get_type(libmyo_event_t event); | |||
/// Retrieve the timestamp of an event. | |||
/// @see libmyo_now() for details on timestamps. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_event_get_timestamp(libmyo_event_t event); | |||
/// Retrieve the Myo associated with an event. | |||
LIBMYO_EXPORT | |||
libmyo_myo_t libmyo_event_get_myo(libmyo_event_t event); | |||
/// Retrieve the MAC address of the myo associated with an event. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_event_get_mac_address(libmyo_event_t event_opq); | |||
/// Retrieve the name of the myo associated with an event. | |||
/// Caller must free the returned string. @see libmyo_string functions. | |||
LIBMYO_EXPORT | |||
libmyo_string_t libmyo_event_get_myo_name(libmyo_event_t event); | |||
/// Components of version. | |||
typedef enum { | |||
libmyo_version_major, ///< Major version. | |||
libmyo_version_minor, ///< Minor version. | |||
libmyo_version_patch, ///< Patch version. | |||
libmyo_version_hardware_rev, ///< Hardware revision. | |||
} libmyo_version_component_t; | |||
/// Hardware revisions. | |||
typedef enum { | |||
libmyo_hardware_rev_c = 1, ///< Alpha units | |||
libmyo_hardware_rev_d = 2, ///< Consumer units | |||
} libmyo_hardware_rev_t; | |||
/// Retrieve the Myo armband's firmware version from this event. | |||
/// Valid for libmyo_event_paired and libmyo_event_connected events. | |||
LIBMYO_EXPORT | |||
unsigned int libmyo_event_get_firmware_version(libmyo_event_t event, libmyo_version_component_t); | |||
/// Enumeration identifying a right arm or left arm. @see libmyo_event_get_arm(). | |||
typedef enum { | |||
libmyo_arm_right, ///< Myo is on the right arm. | |||
libmyo_arm_left, ///< Myo is on the left arm. | |||
libmyo_arm_unknown, ///< Unknown arm. | |||
} libmyo_arm_t; | |||
/// Retrieve the arm associated with an event. | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
libmyo_arm_t libmyo_event_get_arm(libmyo_event_t event); | |||
/// Possible directions for Myo's +x axis relative to a user's arm. | |||
typedef enum { | |||
libmyo_x_direction_toward_wrist, ///< Myo's +x axis is pointing toward the user's wrist. | |||
libmyo_x_direction_toward_elbow, ///< Myo's +x axis is pointing toward the user's elbow. | |||
libmyo_x_direction_unknown, ///< Unknown +x axis direction. | |||
} libmyo_x_direction_t; | |||
/// Retrieve the x-direction associated with an event. | |||
/// The x-direction specifies which way Myo's +x axis is pointing relative to the user's arm. | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
libmyo_x_direction_t libmyo_event_get_x_direction(libmyo_event_t event); | |||
/// Possible warmup states for Myo. | |||
typedef enum { | |||
libmyo_warmup_state_unknown = 0, ///< Unknown warm up state. | |||
libmyo_warmup_state_cold = 1, ///< Myo needs to warm up. | |||
libmyo_warmup_state_warm = 2, ///< Myo is already in a warmed up state. | |||
} libmyo_warmup_state_t; | |||
/// Retrieve the warmup state of the Myo associated with an event. | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
libmyo_warmup_state_t libmyo_event_get_warmup_state(libmyo_event_t event); | |||
/// Possible warmup results for Myo. | |||
typedef enum { | |||
libmyo_warmup_result_unknown = 0, ///< Unknown warm up result. | |||
libmyo_warmup_result_success = 1, ///< The warm up period has completed successfully. | |||
libmyo_warmup_result_failed_timeout = 2, ///< The warm up period timed out. | |||
} libmyo_warmup_result_t; | |||
/// Retrieve the warmup result of the Myo associated with an event. | |||
/// Valid for libmyo_event_warmup_completed events only. | |||
LIBMYO_EXPORT | |||
libmyo_warmup_result_t libmyo_event_get_warmup_result(libmyo_event_t event); | |||
/// Retrieve the estimated rotation of Myo on the user's arm after a sync. | |||
/// The values specifies the rotation of the myo on the arm (0 - logo facing down, pi - logo facing up) | |||
/// Only supported by FW 1.3.x and above (older firmware will always report 0 for the rotation) | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_rotation_on_arm(libmyo_event_t event); | |||
/// Index into orientation data, which is provided as a quaternion. | |||
/// Orientation data is returned as a unit quaternion of floats, represented as `w + x * i + y * j + z * k`. | |||
typedef enum { | |||
libmyo_orientation_x = 0, ///< First component of the quaternion's vector part | |||
libmyo_orientation_y = 1, ///< Second component of the quaternion's vector part | |||
libmyo_orientation_z = 2, ///< Third component of the quaternion's vector part | |||
libmyo_orientation_w = 3, ///< Scalar component of the quaternion. | |||
} libmyo_orientation_index; | |||
/// Retrieve orientation data associated with an event. | |||
/// Valid for libmyo_event_orientation events only. | |||
/// @see libmyo_orientation_index | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_orientation(libmyo_event_t event, libmyo_orientation_index index); | |||
/// Retrieve raw accelerometer data associated with an event in units of g. | |||
/// Valid for libmyo_event_orientation events only. | |||
/// Requires `index < 3`. | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_accelerometer(libmyo_event_t event, unsigned int index); | |||
/// Retrieve raw gyroscope data associated with an event in units of deg/s. | |||
/// Valid for libmyo_event_orientation events only. | |||
/// Requires `index < 3`. | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_gyroscope(libmyo_event_t event, unsigned int index); | |||
/// Retrieve the pose associated with an event. | |||
/// Valid for libmyo_event_pose events only. | |||
LIBMYO_EXPORT | |||
libmyo_pose_t libmyo_event_get_pose(libmyo_event_t event); | |||
/// Retreive the RSSI associated with an event. | |||
/// Valid for libmyo_event_rssi events only. | |||
LIBMYO_EXPORT | |||
int8_t libmyo_event_get_rssi(libmyo_event_t event); | |||
/// Retrieve the battery level of the Myo armband associated with an event. | |||
/// Only valid for libmyo_event_battery_level event. | |||
LIBMYO_EXPORT | |||
uint8_t libmyo_event_get_battery_level(libmyo_event_t event); | |||
/// Retrieve an EMG data point associated with an event. | |||
/// Valid for libmyo_event_emg events only. | |||
/// @a sensor must be smaller than 8. | |||
LIBMYO_EXPORT | |||
int8_t libmyo_event_get_emg(libmyo_event_t event, unsigned int sensor); | |||
/// Return type for event handlers. | |||
typedef enum { | |||
libmyo_handler_continue, ///< Continue processing events | |||
libmyo_handler_stop, ///< Stop processing events | |||
} libmyo_handler_result_t; | |||
/// Callback function type to handle events as they occur from libmyo_run(). | |||
typedef libmyo_handler_result_t (*libmyo_handler_t)(void* user_data, libmyo_event_t event); | |||
/// Process events and call the provided callback as they occur. | |||
/// Runs for up to approximately \a duration_ms milliseconds or until a called handler returns libmyo_handler_stop. | |||
/// @returns libmyo_success after a successful run, otherwise | |||
/// - libmyo_error_invalid_argument if \a hub is NULL | |||
/// - libmyo_error_invalid_argument if \a handler is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_run(libmyo_hub_t hub, unsigned int duration_ms, libmyo_handler_t handler, void* user_data, | |||
libmyo_error_details_t* out_error); | |||
/// @} | |||
#ifdef __cplusplus | |||
} // extern "C" | |||
#endif | |||
#endif // MYO_LIBMYO_H |
@@ -0,0 +1,32 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_LIBMYO_DETAIL_VISIBILITY_H | |||
#define MYO_LIBMYO_DETAIL_VISIBILITY_H | |||
#if defined(_WIN32) || defined(__CYGWIN__) | |||
#ifdef myo_EXPORTS | |||
#ifdef __GNUC__ | |||
#define LIBMYO_EXPORT __attribute__ ((dllexport)) | |||
#else | |||
#define LIBMYO_EXPORT __declspec(dllexport) | |||
#endif | |||
#else | |||
#ifdef LIBMYO_STATIC_BUILD | |||
#define LIBMYO_EXPORT | |||
#else | |||
#ifdef __GNUC__ | |||
#define LIBMYO_EXPORT __attribute__ ((dllimport)) | |||
#else | |||
#define LIBMYO_EXPORT __declspec(dllimport) | |||
#endif | |||
#endif | |||
#endif | |||
#else | |||
#if __GNUC__ >= 4 | |||
#define LIBMYO_EXPORT __attribute__ ((visibility ("default"))) | |||
#else | |||
#define LIBMYO_EXPORT | |||
#endif | |||
#endif | |||
#endif // MYO_LIBMYO_DETAIL_VISIBILITY_H |
@@ -0,0 +1,13 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
/// The namespace in which all of the %Myo C++ bindings are contained. | |||
namespace myo {} | |||
#include "cxx/DeviceListener.hpp" | |||
#include "cxx/Hub.hpp" | |||
#include "cxx/Myo.hpp" | |||
#include "cxx/Pose.hpp" | |||
#include "cxx/Quaternion.hpp" | |||
#include "cxx/Vector3.hpp" |
@@ -0,0 +1,26 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
<plist version="1.0"> | |||
<dict> | |||
<key>CFBundleDevelopmentRegion</key> | |||
<string>English</string> | |||
<key>CFBundleExecutable</key> | |||
<string>myo</string> | |||
<key>CFBundleIconFile</key> | |||
<string></string> | |||
<key>CFBundleIdentifier</key> | |||
<string></string> | |||
<key>CFBundleInfoDictionaryVersion</key> | |||
<string>6.0</string> | |||
<key>CFBundlePackageType</key> | |||
<string>FMWK</string> | |||
<key>CFBundleSignature</key> | |||
<string>????</string> | |||
<key>CFBundleVersion</key> | |||
<string></string> | |||
<key>CFBundleShortVersionString</key> | |||
<string></string> | |||
<key>CSResourcesFileMapped</key> | |||
<true/> | |||
</dict> | |||
</plist> |
@@ -0,0 +1,167 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
<plist version="1.0"> | |||
<dict> | |||
<key>files</key> | |||
<dict> | |||
<key>Resources/Info.plist</key> | |||
<data> | |||
tUgLZV94WtJ7c7dl1ZQDEnyfe2U= | |||
</data> | |||
</dict> | |||
<key>files2</key> | |||
<dict> | |||
<key>Headers/cxx/DeviceListener.hpp</key> | |||
<data> | |||
5frQIrDj5Rod49qbH8F/ODv03cg= | |||
</data> | |||
<key>Headers/cxx/Hub.hpp</key> | |||
<data> | |||
i2GwmXkJaAf8ZK1boAQLVFA9FuQ= | |||
</data> | |||
<key>Headers/cxx/Myo.hpp</key> | |||
<data> | |||
zkwa8CxGu7CxuY09ncg4cs2C0Ik= | |||
</data> | |||
<key>Headers/cxx/Pose.hpp</key> | |||
<data> | |||
bV/b65asnTpOQVVUseBE2Jks2yY= | |||
</data> | |||
<key>Headers/cxx/Quaternion.hpp</key> | |||
<data> | |||
bvsi/ZwGqVs0ZiHbWPUtsWlsK8k= | |||
</data> | |||
<key>Headers/cxx/Vector3.hpp</key> | |||
<data> | |||
OQUYhjK6FE/MwW8eyy24OtbHO4I= | |||
</data> | |||
<key>Headers/cxx/detail/ThrowOnError.hpp</key> | |||
<data> | |||
ZG7+E/cEH4UadH/3StifiGVjRxE= | |||
</data> | |||
<key>Headers/cxx/impl/Hub_impl.hpp</key> | |||
<data> | |||
jPk/hrtJnF4CumxpYjsOPpHH8PM= | |||
</data> | |||
<key>Headers/cxx/impl/Myo_impl.hpp</key> | |||
<data> | |||
1IleanLjzRkjPeQaDU5tHCnz3+k= | |||
</data> | |||
<key>Headers/cxx/impl/Pose_impl.hpp</key> | |||
<data> | |||
dimtyDcx8DWcpkDi1creWJADmRA= | |||
</data> | |||
<key>Headers/libmyo.h</key> | |||
<data> | |||
0nJ1nA0iCBjWxuXv2VZ2vRHjXnY= | |||
</data> | |||
<key>Headers/libmyo/detail/visibility.h</key> | |||
<data> | |||
dPUWLcemRGRDAJVc1Gonqqzo2K0= | |||
</data> | |||
<key>Headers/myo.hpp</key> | |||
<data> | |||
JeFdPeQ4BqtfHJyJxRiXrDHj6xw= | |||
</data> | |||
<key>Resources/Info.plist</key> | |||
<data> | |||
tUgLZV94WtJ7c7dl1ZQDEnyfe2U= | |||
</data> | |||
</dict> | |||
<key>rules</key> | |||
<dict> | |||
<key>^Resources/</key> | |||
<true/> | |||
<key>^Resources/.*\.lproj/</key> | |||
<dict> | |||
<key>optional</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>1000</real> | |||
</dict> | |||
<key>^Resources/.*\.lproj/locversion.plist$</key> | |||
<dict> | |||
<key>omit</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>1100</real> | |||
</dict> | |||
<key>^version.plist$</key> | |||
<true/> | |||
</dict> | |||
<key>rules2</key> | |||
<dict> | |||
<key>.*\.dSYM($|/)</key> | |||
<dict> | |||
<key>weight</key> | |||
<real>11</real> | |||
</dict> | |||
<key>^(.*/)?\.DS_Store$</key> | |||
<dict> | |||
<key>omit</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>2000</real> | |||
</dict> | |||
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key> | |||
<dict> | |||
<key>nested</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>10</real> | |||
</dict> | |||
<key>^.*</key> | |||
<true/> | |||
<key>^Info\.plist$</key> | |||
<dict> | |||
<key>omit</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>20</real> | |||
</dict> | |||
<key>^PkgInfo$</key> | |||
<dict> | |||
<key>omit</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>20</real> | |||
</dict> | |||
<key>^Resources/</key> | |||
<dict> | |||
<key>weight</key> | |||
<real>20</real> | |||
</dict> | |||
<key>^Resources/.*\.lproj/</key> | |||
<dict> | |||
<key>optional</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>1000</real> | |||
</dict> | |||
<key>^Resources/.*\.lproj/locversion.plist$</key> | |||
<dict> | |||
<key>omit</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>1100</real> | |||
</dict> | |||
<key>^[^/]+$</key> | |||
<dict> | |||
<key>nested</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>10</real> | |||
</dict> | |||
<key>^embedded\.provisionprofile$</key> | |||
<dict> | |||
<key>weight</key> | |||
<real>20</real> | |||
</dict> | |||
<key>^version\.plist$</key> | |||
<dict> | |||
<key>weight</key> | |||
<real>20</real> | |||
</dict> | |||
</dict> | |||
</dict> | |||
</plist> |
@@ -0,0 +1,197 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <stdint.h> | |||
#include "Pose.hpp" | |||
namespace myo { | |||
class Myo; | |||
template<typename T> | |||
class Quaternion; | |||
template<typename T> | |||
class Vector3; | |||
/// Enumeration identifying a right arm or left arm. | |||
enum Arm { | |||
armLeft = libmyo_arm_left, | |||
armRight = libmyo_arm_right, | |||
armUnknown = libmyo_arm_unknown | |||
}; | |||
/// Possible directions for Myo's +x axis relative to a user's arm. | |||
enum XDirection { | |||
xDirectionTowardWrist = libmyo_x_direction_toward_wrist, | |||
xDirectionTowardElbow = libmyo_x_direction_toward_elbow, | |||
xDirectionUnknown = libmyo_x_direction_unknown | |||
}; | |||
/// Possible warmup states for a Myo. | |||
enum WarmupState { | |||
warmupStateUnknown = libmyo_warmup_state_unknown, | |||
warmupStateCold = libmyo_warmup_state_cold, | |||
warmupStateWarm = libmyo_warmup_state_warm, | |||
}; | |||
/// Possible warmup results for a Myo. | |||
enum WarmupResult { | |||
warmupResultUnknown = libmyo_warmup_result_unknown, | |||
warmupResultSuccess = libmyo_warmup_result_success, | |||
warmupResultFailedTimeout = libmyo_warmup_result_failed_timeout, | |||
}; | |||
/// Firmware version of Myo. | |||
struct FirmwareVersion { | |||
unsigned int firmwareVersionMajor; ///< Myo's major version must match the required major version. | |||
unsigned int firmwareVersionMinor; ///< Myo's minor version must match the required minor version. | |||
unsigned int firmwareVersionPatch; ///< Myo's patch version must greater or equal to the required patch version. | |||
unsigned int firmwareVersionHardwareRev; ///< Myo's hardware revision; not used to detect firmware version mismatch. | |||
}; | |||
/// A DeviceListener receives events about a Myo. | |||
/// @see Hub::addListener() | |||
class DeviceListener { | |||
public: | |||
virtual ~DeviceListener() {} | |||
/// Called when a Myo has been paired. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param firmwareVersion The firmware version of \a myo. | |||
virtual void onPair(Myo* myo, uint64_t timestamp, FirmwareVersion firmwareVersion) {} | |||
/// Called when a Myo has been unpaired. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onUnpair(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo has been connected. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param firmwareVersion The firmware version of \a myo. | |||
virtual void onConnect(Myo* myo, uint64_t timestamp, FirmwareVersion firmwareVersion) {} | |||
/// Called when a paired Myo has been disconnected. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onDisconnect(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo recognizes that it is on an arm. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param arm The identified Arm of \a myo. | |||
/// @param xDirection The identified XDirection of \a myo. | |||
/// @param rotation The estimated rotation of Myo on the user's arm after a sync. | |||
/// @param warmupState The warmup state of \a myo. If \a warmupState is equal to WarmupState::warmupStateCold, | |||
/// onWarmupCompleted() will be called when the warmup period has completed. | |||
virtual void onArmSync(Myo* myo, uint64_t timestamp, Arm arm, XDirection xDirection, float rotation, | |||
WarmupState warmupState) {} | |||
/// Called when a paired Myo is moved or removed from the arm. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onArmUnsync(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo becomes unlocked. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onUnlock(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo becomes locked. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
virtual void onLock(Myo* myo, uint64_t timestamp) {} | |||
/// Called when a paired Myo has provided a new pose. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param pose The identified Pose of \a myo. | |||
virtual void onPose(Myo* myo, uint64_t timestamp, Pose pose) {} | |||
/// Called when a paired Myo has provided new orientation data. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param rotation The orientation data of \a myo, as a Quaternion. | |||
virtual void onOrientationData(Myo* myo, uint64_t timestamp, const Quaternion<float>& rotation) {} | |||
/// Called when a paired Myo has provided new accelerometer data in units of g. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param accel The accelerometer data of \a myo, in units of g. | |||
virtual void onAccelerometerData(Myo* myo, uint64_t timestamp, const Vector3<float>& accel) {} | |||
/// Called when a paired Myo has provided new gyroscope data in units of deg/s. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param gyro The gyroscope data of \a myo, in units of deg/s. | |||
virtual void onGyroscopeData(Myo* myo, uint64_t timestamp, const Vector3<float>& gyro) {} | |||
/// Called when a paired Myo has provided a new RSSI value. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param rssi The RSSI (received signal strength indication) of \a myo. | |||
/// @see Myo::requestRssi() to request an RSSI value from the Myo. | |||
virtual void onRssi(Myo* myo, uint64_t timestamp, int8_t rssi) {} | |||
/// Called when a paired Myo receives an battery level update. | |||
/// Updates occur when the battery level changes and when the battery level is explicitly requested. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param level battery level reported by the myo the value is a number from 0 to 100 representing the percentage | |||
/// of battery life remaining. | |||
virtual void onBatteryLevelReceived(myo::Myo* myo, uint64_t timestamp, uint8_t level) {} | |||
/// Called when a paired Myo has provided new EMG data. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param emg An array of 8 elements, each corresponding to one sensor. | |||
virtual void onEmgData(myo::Myo* myo, uint64_t timestamp, const int8_t* emg) {} | |||
/// Called when the warmup period for a Myo has completed. | |||
/// @param myo The Myo for this event. | |||
/// @param timestamp The timestamp of when the event is received by the SDK. Timestamps are 64 bit unsigned | |||
/// integers that correspond to a number of microseconds since some (unspecified) period in time. Timestamps | |||
/// are monotonically non-decreasing. | |||
/// @param warmupResult The warmup result of \a myo. | |||
virtual void onWarmupCompleted(myo::Myo* myo, uint64_t timestamp, WarmupResult warmupResult) {} | |||
/// @cond LIBMYO_INTERNALS | |||
virtual void onOpaqueEvent(libmyo_event_t event) {} | |||
/// @endcond | |||
}; | |||
} // namespace myo |
@@ -0,0 +1,91 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <vector> | |||
#include <myo/libmyo.h> | |||
namespace myo { | |||
class Myo; | |||
class DeviceListener; | |||
/// @brief A Hub provides access to one or more Myo instances. | |||
class Hub { | |||
public: | |||
/// Construct a hub. | |||
/// \a applicationIdentifier must follow a reverse domain name format (ex. com.domainname.appname). Application | |||
/// identifiers can be formed from the set of alphanumeric ASCII characters (a-z, A-Z, 0-9). The hyphen (-) and | |||
/// underscore (_) characters are permitted if they are not adjacent to a period (.) character (i.e. not at the | |||
/// start or end of each segment), but are not permitted in the top-level domain. Application identifiers must have | |||
/// three or more segments. For example, if a company's domain is example.com and the application is named | |||
/// hello-world, one could use "com.example.hello-world" as a valid application identifier. \a applicationIdentifier | |||
/// can be an empty string. | |||
/// Throws an exception of type std::invalid_argument if \a applicationIdentifier is not in the proper reverse | |||
/// domain name format or is longer than 255 characters. | |||
/// Throws an exception of type std::runtime_error if the hub initialization failed for some reason, typically | |||
/// because Myo Connect is not running and a connection can thus not be established. | |||
Hub(const std::string& applicationIdentifier = ""); | |||
/// Deallocate any resources associated with a Hub. | |||
/// This will cause all Myo instances retrieved from this Hub to become invalid. | |||
~Hub(); | |||
/// Wait for a Myo to become paired, or time out after \a timeout_ms milliseconds if provided. | |||
/// If \a timeout_ms is zero, this function blocks until a Myo is found. | |||
/// This function must not be called concurrently with run() or runOnce(). | |||
Myo* waitForMyo(unsigned int milliseconds = 0); | |||
/// Register a listener to be called when device events occur. | |||
void addListener(DeviceListener* listener); | |||
/// Remove a previously registered listener. | |||
void removeListener(DeviceListener* listener); | |||
/// Locking policies supported by Myo. | |||
enum LockingPolicy { | |||
lockingPolicyNone = libmyo_locking_policy_none, | |||
lockingPolicyStandard = libmyo_locking_policy_standard | |||
}; | |||
/// Set the locking policy for Myos connected to the Hub. | |||
void setLockingPolicy(LockingPolicy lockingPolicy); | |||
/// Run the event loop for the specified duration (in milliseconds). | |||
void run(unsigned int duration_ms); | |||
/// Run the event loop until a single event occurs, or the specified duration (in milliseconds) has elapsed. | |||
void runOnce(unsigned int duration_ms); | |||
/// @cond MYO_INTERNALS | |||
/// Return the internal libmyo object corresponding to this hub. | |||
libmyo_hub_t libmyoObject(); | |||
protected: | |||
void onDeviceEvent(libmyo_event_t event); | |||
Myo* lookupMyo(libmyo_myo_t opaqueMyo) const; | |||
Myo* addMyo(libmyo_myo_t opaqueMyo); | |||
libmyo_hub_t _hub; | |||
std::vector<Myo*> _myos; | |||
std::vector<DeviceListener*> _listeners; | |||
/// @endcond | |||
private: | |||
// Not implemented | |||
Hub(const Hub&); | |||
Hub& operator=(const Hub&); | |||
}; | |||
/// @example hello-myo.cpp | |||
/// @example multiple-myos.cpp | |||
/// @example emg-data-sample.cpp | |||
} // namespace myo | |||
#include "impl/Hub_impl.hpp" |
@@ -0,0 +1,83 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <myo/libmyo.h> | |||
namespace myo { | |||
/// Represents a Myo device with a specific MAC address. | |||
/// This class can not be instantiated directly; instead, use Hub to get access to a Myo. | |||
/// There is only one Myo instance corresponding to each device; thus, if the addresses of two Myo instances compare | |||
/// equal, they refer to the same device. | |||
class Myo { | |||
public: | |||
/// Types of vibration supported by the Myo. | |||
enum VibrationType { | |||
vibrationShort = libmyo_vibration_short, | |||
vibrationMedium = libmyo_vibration_medium, | |||
vibrationLong = libmyo_vibration_long | |||
}; | |||
/// Vibrate the Myo. | |||
void vibrate(VibrationType type); | |||
/// Request the RSSI of the Myo. An onRssi event will likely be generated with the value of the RSSI. | |||
/// @see DeviceListener::onRssi() | |||
void requestRssi() const; | |||
/// Request the battery level of the Myo. An onBatteryLevelReceived event will be generated with the value. | |||
/// @see DeviceListener::onBatteryLevelReceived(). | |||
void requestBatteryLevel() const; | |||
/// Unlock types supported by Myo. | |||
enum UnlockType { | |||
unlockTimed = libmyo_unlock_timed, | |||
unlockHold = libmyo_unlock_hold | |||
}; | |||
/// Unlock the Myo. | |||
/// Myo will remain unlocked for a short amount of time, after which it will automatically lock again. | |||
/// If Myo was locked, an onUnlock event will be generated. | |||
void unlock(UnlockType type); | |||
/// Force the Myo to lock immediately. | |||
/// If Myo was unlocked, an onLock event will be generated. | |||
void lock(); | |||
/// Notify the Myo that a user action was recognized. | |||
/// Will cause Myo to vibrate. | |||
void notifyUserAction(); | |||
/// Valid EMG streaming modes for a Myo. | |||
enum StreamEmgType { | |||
streamEmgDisabled = libmyo_stream_emg_disabled, | |||
streamEmgEnabled = libmyo_stream_emg_enabled | |||
}; | |||
/// Sets the EMG streaming mode for a Myo. | |||
void setStreamEmg(StreamEmgType type); | |||
/// @cond MYO_INTERNALS | |||
/// Return the internal libmyo object corresponding to this device. | |||
libmyo_myo_t libmyoObject() const; | |||
/// @endcond | |||
private: | |||
Myo(libmyo_myo_t myo); | |||
~Myo(); | |||
libmyo_myo_t _myo; | |||
// Not implemented. | |||
Myo(const Myo&); | |||
Myo& operator=(const Myo&); | |||
friend class Hub; | |||
}; | |||
} // namespace myo | |||
#include "impl/Myo_impl.hpp" |
@@ -0,0 +1,70 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <iosfwd> | |||
#include <string> | |||
#include <myo/libmyo.h> | |||
namespace myo { | |||
/// A pose represents a detected configuration of the user's hand. | |||
class Pose { | |||
public: | |||
/// Types of poses supported by the SDK. | |||
enum Type { | |||
rest = libmyo_pose_rest, | |||
fist = libmyo_pose_fist, | |||
waveIn = libmyo_pose_wave_in, | |||
waveOut = libmyo_pose_wave_out, | |||
fingersSpread = libmyo_pose_fingers_spread, | |||
doubleTap = libmyo_pose_double_tap, | |||
unknown = libmyo_pose_unknown | |||
}; | |||
/// Construct a pose of type Pose::none. | |||
Pose(); | |||
/// Construct a pose with the given type. | |||
Pose(Type type); | |||
/// Returns true if and only if the two poses are of the same type. | |||
bool operator==(Pose other) const; | |||
/// Equivalent to `!(*this == other)`. | |||
bool operator!=(Pose other) const; | |||
/// Returns the type of this pose. | |||
Type type() const; | |||
/// Return a human-readable string representation of the pose. | |||
std::string toString() const; | |||
private: | |||
Type _type; | |||
}; | |||
/// @relates Pose | |||
/// Returns true if and only if the type of pose is the same as the provided type. | |||
bool operator==(Pose pose, Pose::Type t); | |||
/// @relates Pose | |||
/// Equivalent to `pose == type`. | |||
bool operator==(Pose::Type type, Pose pose); | |||
/// @relates Pose | |||
/// Equivalent to `!(pose == type)`. | |||
bool operator!=(Pose pose, Pose::Type type); | |||
/// @relates Pose | |||
/// Equivalent to `!(type == pose)`. | |||
bool operator!=(Pose::Type type, Pose pose); | |||
/// @relates Pose | |||
/// Write the name of the provided pose to the provided output stream. | |||
std::ostream& operator<<(std::ostream& out, const Pose& pose); | |||
} // namespace myo | |||
#include "impl/Pose_impl.hpp" |
@@ -0,0 +1,158 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#include <cmath> | |||
#include "Vector3.hpp" | |||
namespace myo { | |||
/// A quaternion that can be used to represent a rotation. | |||
/// This type provides only very basic functionality to store quaternions that's sufficient to retrieve the data to | |||
/// be placed in a full featured quaternion type. | |||
template<typename T> | |||
class Quaternion { | |||
public: | |||
/// Construct a quaternion that represents zero rotation (i.e. the multiplicative identity). | |||
Quaternion() | |||
: _x(0) | |||
, _y(0) | |||
, _z(0) | |||
, _w(1) | |||
{ | |||
} | |||
/// Construct a quaternion with the provided components. | |||
Quaternion(T x, T y, T z, T w) | |||
: _x(x) | |||
, _y(y) | |||
, _z(z) | |||
, _w(w) | |||
{ | |||
} | |||
/// Set the components of this quaternion to be those of the other. | |||
Quaternion& operator=(const Quaternion other) | |||
{ | |||
_x = other._x; | |||
_y = other._y; | |||
_z = other._z; | |||
_w = other._w; | |||
return *this; | |||
} | |||
/// Return the x-component of this quaternion's vector. | |||
T x() const { return _x; } | |||
/// Return the y-component of this quaternion's vector. | |||
T y() const { return _y; } | |||
/// Return the z-component of this quaternion's vector. | |||
T z() const { return _z; } | |||
/// Return the w-component (scalar) of this quaternion. | |||
T w() const { return _w; } | |||
/// Return the quaternion multiplied by \a rhs. | |||
/// Note that quaternion multiplication is not commutative. | |||
Quaternion operator*(const Quaternion& rhs) const | |||
{ | |||
return Quaternion( | |||
_w * rhs._x + _x * rhs._w + _y * rhs._z - _z * rhs._y, | |||
_w * rhs._y - _x * rhs._z + _y * rhs._w + _z * rhs._x, | |||
_w * rhs._z + _x * rhs._y - _y * rhs._x + _z * rhs._w, | |||
_w * rhs._w - _x * rhs._x - _y * rhs._y - _z * rhs._z | |||
); | |||
} | |||
/// Multiply this quaternion by \a rhs. | |||
/// Return this quaternion updated with the result. | |||
Quaternion& operator*=(const Quaternion& rhs) | |||
{ | |||
*this = *this * rhs; | |||
return *this; | |||
} | |||
/// Return the unit quaternion corresponding to the same rotation as this one. | |||
Quaternion normalized() const | |||
{ | |||
T magnitude = std::sqrt(_x * _x + _y * _y + _z * _z + _w * _w); | |||
return Quaternion(_x / magnitude, _y / magnitude, _z / magnitude, _w / magnitude); | |||
} | |||
/// Return this quaternion's conjugate. | |||
Quaternion conjugate() const | |||
{ | |||
return Quaternion(-_x, -_y, -_z, _w); | |||
} | |||
/// Return a quaternion that represents a right-handed rotation of \a angle radians about the given \a axis. | |||
/// \a axis The unit vector representing the axis of rotation. | |||
/// \a angle The angle of rotation, in radians. | |||
static Quaternion fromAxisAngle(const myo::Vector3<T>& axis, T angle) | |||
{ | |||
return Quaternion(axis.x() * std::sin(angle / 2), | |||
axis.y() * std::sin(angle / 2), | |||
axis.z() * std::sin(angle / 2), | |||
std::cos(angle / 2)); | |||
} | |||
private: | |||
T _x, _y, _z, _w; | |||
}; | |||
/// Return a copy of this \a vec rotated by \a quat. | |||
/// \relates myo::Quaternion | |||
template<typename T> | |||
Vector3<T> rotate(const Quaternion<T>& quat, const Vector3<T>& vec) | |||
{ | |||
myo::Quaternion<T> qvec(vec.x(), vec.y(), vec.z(), 0); | |||
myo::Quaternion<T> result = quat * qvec * quat.conjugate(); | |||
return Vector3<T>(result.x(), result.y(), result.z()); | |||
} | |||
/// Return a quaternion that represents a rotation from vector \a from to \a to. | |||
/// \relates myo::Quaternion | |||
/// See http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another | |||
/// for some explanation. | |||
template<typename T> | |||
Quaternion<T> rotate(const Vector3<T>& from, const Vector3<T>& to) | |||
{ | |||
Vector3<T> cross = from.cross(to); | |||
// The product of the square of magnitudes and the cosine of the angle between from and to. | |||
T cosTheta = from.dot(to); | |||
// Return identity if the vectors are the same direction. | |||
if (cosTheta >= 1) { | |||
return Quaternion<T>(); | |||
} | |||
// The product of the square of the magnitudes | |||
T k = std::sqrt(from.dot(from) * to.dot(to)); | |||
// Return identity in the degenerate case. | |||
if (k <= 0) { | |||
return Quaternion<T>(); | |||
} | |||
// Special handling for vectors facing opposite directions. | |||
if (cosTheta / k <= -1) { | |||
Vector3<T> xAxis(1, 0, 0); | |||
Vector3<T> yAxis(0, 1, 0); | |||
cross = from.cross(std::abs(from.dot(xAxis)) < 1 ? xAxis : yAxis); | |||
k = cosTheta = 0; | |||
} | |||
return Quaternion<T>( | |||
cross.x(), | |||
cross.y(), | |||
cross.z(), | |||
k + cosTheta); | |||
} | |||
} // namespace myo |
@@ -0,0 +1,103 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
#define _USE_MATH_DEFINES | |||
#include <cmath> | |||
namespace myo { | |||
/// A vector of three components. | |||
/// This type provides very basic functionality to store a three dimensional vector that's sufficient to retrieve | |||
/// the data to be placed in a full featured vector type. A few common vector operations, such as dot product and | |||
/// cross product, are also provided. | |||
template<typename T> | |||
class Vector3 { | |||
public: | |||
/// Construct a vector of all zeroes. | |||
Vector3() | |||
{ | |||
_data[0] = 0; | |||
_data[1] = 0; | |||
_data[2] = 0; | |||
} | |||
/// Construct a vector with the three provided components. | |||
Vector3(T x, T y, T z) | |||
{ | |||
_data[0] = x; | |||
_data[1] = y; | |||
_data[2] = z; | |||
} | |||
/// Construct a vector with the same components as \a other. | |||
Vector3(const Vector3& other) | |||
{ | |||
*this = other; | |||
} | |||
/// Set the components of this vector to be the same as \a other. | |||
Vector3& operator=(const Vector3& other) | |||
{ | |||
_data[0] = other._data[0]; | |||
_data[1] = other._data[1]; | |||
_data[2] = other._data[2]; | |||
return *this; | |||
} | |||
/// Return a copy of the component of this vector at \a index, which should be 0, 1, or 2. | |||
T operator[](unsigned int index) const | |||
{ | |||
return _data[index]; | |||
} | |||
/// Return the x-component of this vector. | |||
T x() const { return _data[0]; } | |||
/// Return the y-component of this vector. | |||
T y() const { return _data[1]; } | |||
/// Return the z-component of this vector. | |||
T z() const { return _data[2]; } | |||
/// Return the magnitude of this vector. | |||
T magnitude() const | |||
{ | |||
return std::sqrt(x() * x() + y() * y() + z() * z()); | |||
} | |||
/// Return a normalized copy of this vector. | |||
Vector3 normalized() const | |||
{ | |||
T norm = magnitude(); | |||
return Vector3(x() / norm, y() / norm, z() / norm); | |||
} | |||
/// Return the dot product of this vector and \a rhs. | |||
T dot(const Vector3& rhs) const | |||
{ | |||
return x() * rhs.x() + y() * rhs.y() + z() * rhs.z(); | |||
} | |||
/// Return the cross product of this vector and \a rhs. | |||
Vector3 cross(const Vector3& rhs) const | |||
{ | |||
return Vector3( | |||
y() * rhs.z() - z() * rhs.y(), | |||
z() * rhs.x() - x() * rhs.z(), | |||
x() * rhs.y() - y() * rhs.x() | |||
); | |||
} | |||
/// Return the angle between this vector and \a rhs, in radians. | |||
T angleTo(const Vector3& rhs) const | |||
{ | |||
return std::acos(dot(rhs) / (magnitude() * rhs.magnitude())); | |||
} | |||
private: | |||
T _data[3]; | |||
}; | |||
} // namespace myo |
@@ -0,0 +1,70 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_CXX_DETAIL_THROWONERROR_HPP | |||
#define MYO_CXX_DETAIL_THROWONERROR_HPP | |||
#include <stdexcept> | |||
#include <myo/libmyo.h> | |||
#if defined(_MSC_VER) && _MSC_VER <= 1800 | |||
#define LIBMYO_NOEXCEPT(b) | |||
#else | |||
#if __cplusplus >= 201103L | |||
# define LIBMYO_NOEXCEPT(b) noexcept(b) | |||
#else | |||
# define LIBMYO_NOEXCEPT(b) | |||
#endif | |||
#endif | |||
namespace myo { | |||
class ThrowOnError { | |||
public: | |||
ThrowOnError() | |||
: _error() | |||
{ | |||
} | |||
~ThrowOnError() LIBMYO_NOEXCEPT(false) | |||
{ | |||
if (_error) | |||
{ | |||
switch (libmyo_error_kind(_error)) { | |||
case libmyo_error: | |||
case libmyo_error_runtime: | |||
{ | |||
std::runtime_error exception(libmyo_error_cstring(_error)); | |||
libmyo_free_error_details(_error); | |||
throw exception; | |||
} | |||
case libmyo_error_invalid_argument: | |||
{ | |||
std::invalid_argument exception(libmyo_error_cstring(_error)); | |||
libmyo_free_error_details(_error); | |||
throw exception; | |||
} | |||
case libmyo_success: | |||
{ | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
operator libmyo_error_details_t*() | |||
{ | |||
return &_error; | |||
} | |||
private: | |||
libmyo_error_details_t _error; | |||
// Not implemented | |||
ThrowOnError(const ThrowOnError&); // = delete; | |||
ThrowOnError& operator=(const ThrowOnError&); // = delete; | |||
}; | |||
} //namespace libmyo | |||
#endif // MYO_CXX_DETAIL_THROWONERROR_HPP |
@@ -0,0 +1,265 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#include "../Hub.hpp" | |||
#include <algorithm> | |||
#include <exception> | |||
#include "../DeviceListener.hpp" | |||
#include "../Myo.hpp" | |||
#include "../Pose.hpp" | |||
#include "../Quaternion.hpp" | |||
#include "../Vector3.hpp" | |||
#include "../detail/ThrowOnError.hpp" | |||
namespace myo { | |||
inline | |||
Hub::Hub(const std::string& applicationIdentifier) | |||
: _hub(0) | |||
, _myos() | |||
, _listeners() | |||
{ | |||
libmyo_init_hub(&_hub, applicationIdentifier.c_str(), ThrowOnError()); | |||
} | |||
inline | |||
Hub::~Hub() | |||
{ | |||
for (std::vector<Myo*>::iterator I = _myos.begin(), IE = _myos.end(); I != IE; ++I) { | |||
delete *I; | |||
} | |||
libmyo_shutdown_hub(_hub, 0); | |||
} | |||
inline | |||
Myo* Hub::waitForMyo(unsigned int timeout_ms) | |||
{ | |||
std::size_t prevSize = _myos.size(); | |||
struct local { | |||
static libmyo_handler_result_t handler(void* user_data, libmyo_event_t event) { | |||
Hub* hub = static_cast<Hub*>(user_data); | |||
libmyo_myo_t opaque_myo = libmyo_event_get_myo(event); | |||
switch (libmyo_event_get_type(event)) { | |||
case libmyo_event_paired: | |||
hub->addMyo(opaque_myo); | |||
return libmyo_handler_stop; | |||
default: | |||
break; | |||
} | |||
return libmyo_handler_continue; | |||
} | |||
}; | |||
do { | |||
libmyo_run(_hub, timeout_ms ? timeout_ms : 1000, &local::handler, this, ThrowOnError()); | |||
} while (!timeout_ms && _myos.size() <= prevSize); | |||
if (_myos.size() <= prevSize) { | |||
return 0; | |||
} | |||
return _myos.back(); | |||
} | |||
inline | |||
void Hub::addListener(DeviceListener* listener) | |||
{ | |||
if (std::find(_listeners.begin(), _listeners.end(), listener) != _listeners.end()) { | |||
// Listener was already added. | |||
return; | |||
} | |||
_listeners.push_back(listener); | |||
} | |||
inline | |||
void Hub::removeListener(DeviceListener* listener) | |||
{ | |||
std::vector<DeviceListener*>::iterator I = std::find(_listeners.begin(), _listeners.end(), listener); | |||
if (I == _listeners.end()) { | |||
// Don't have this listener. | |||
return; | |||
} | |||
_listeners.erase(I); | |||
} | |||
inline | |||
void Hub::setLockingPolicy(LockingPolicy lockingPolicy) | |||
{ | |||
libmyo_set_locking_policy(_hub, static_cast<libmyo_locking_policy_t>(lockingPolicy), ThrowOnError()); | |||
} | |||
inline | |||
void Hub::onDeviceEvent(libmyo_event_t event) | |||
{ | |||
libmyo_myo_t opaqueMyo = libmyo_event_get_myo(event); | |||
Myo* myo = lookupMyo(opaqueMyo); | |||
if (!myo && libmyo_event_get_type(event) == libmyo_event_paired) { | |||
myo = addMyo(opaqueMyo); | |||
} | |||
if (!myo) { | |||
// Ignore events for Myos we don't know about. | |||
return; | |||
} | |||
for (std::vector<DeviceListener*>::iterator I = _listeners.begin(), IE = _listeners.end(); I != IE; ++I) { | |||
DeviceListener* listener = *I; | |||
listener->onOpaqueEvent(event); | |||
uint64_t time = libmyo_event_get_timestamp(event); | |||
switch (libmyo_event_get_type(event)) { | |||
case libmyo_event_paired: { | |||
FirmwareVersion version = {libmyo_event_get_firmware_version(event, libmyo_version_major), | |||
libmyo_event_get_firmware_version(event, libmyo_version_minor), | |||
libmyo_event_get_firmware_version(event, libmyo_version_patch), | |||
libmyo_event_get_firmware_version(event, libmyo_version_hardware_rev)}; | |||
listener->onPair(myo, time, version); | |||
break; | |||
} | |||
case libmyo_event_unpaired: | |||
listener->onUnpair(myo, time); | |||
break; | |||
case libmyo_event_connected: { | |||
FirmwareVersion version = {libmyo_event_get_firmware_version(event, libmyo_version_major), | |||
libmyo_event_get_firmware_version(event, libmyo_version_minor), | |||
libmyo_event_get_firmware_version(event, libmyo_version_patch), | |||
libmyo_event_get_firmware_version(event, libmyo_version_hardware_rev)}; | |||
listener->onConnect(myo, time, version); | |||
break; | |||
} | |||
case libmyo_event_disconnected: | |||
listener->onDisconnect(myo, time); | |||
break; | |||
case libmyo_event_arm_synced: | |||
listener->onArmSync(myo, time, | |||
static_cast<Arm>(libmyo_event_get_arm(event)), | |||
static_cast<XDirection>(libmyo_event_get_x_direction(event)), | |||
libmyo_event_get_rotation_on_arm(event), | |||
static_cast<WarmupState>(libmyo_event_get_warmup_state(event))); | |||
break; | |||
case libmyo_event_arm_unsynced: | |||
listener->onArmUnsync(myo, time); | |||
break; | |||
case libmyo_event_unlocked: | |||
listener->onUnlock(myo, time); | |||
break; | |||
case libmyo_event_locked: | |||
listener->onLock(myo, time); | |||
break; | |||
case libmyo_event_orientation: | |||
listener->onOrientationData(myo, time, | |||
Quaternion<float>(libmyo_event_get_orientation(event, libmyo_orientation_x), | |||
libmyo_event_get_orientation(event, libmyo_orientation_y), | |||
libmyo_event_get_orientation(event, libmyo_orientation_z), | |||
libmyo_event_get_orientation(event, libmyo_orientation_w))); | |||
listener->onAccelerometerData(myo, time, | |||
Vector3<float>(libmyo_event_get_accelerometer(event, 0), | |||
libmyo_event_get_accelerometer(event, 1), | |||
libmyo_event_get_accelerometer(event, 2))); | |||
listener->onGyroscopeData(myo, time, | |||
Vector3<float>(libmyo_event_get_gyroscope(event, 0), | |||
libmyo_event_get_gyroscope(event, 1), | |||
libmyo_event_get_gyroscope(event, 2))); | |||
break; | |||
case libmyo_event_pose: | |||
listener->onPose(myo, time, Pose(static_cast<Pose::Type>(libmyo_event_get_pose(event)))); | |||
break; | |||
case libmyo_event_rssi: | |||
listener->onRssi(myo, time, libmyo_event_get_rssi(event)); | |||
break; | |||
case libmyo_event_battery_level: | |||
listener->onBatteryLevelReceived(myo, time, libmyo_event_get_battery_level(event)); | |||
break; | |||
case libmyo_event_emg: { | |||
int8_t emg[] = { libmyo_event_get_emg(event, 0), | |||
libmyo_event_get_emg(event, 1), | |||
libmyo_event_get_emg(event, 2), | |||
libmyo_event_get_emg(event, 3), | |||
libmyo_event_get_emg(event, 4), | |||
libmyo_event_get_emg(event, 5), | |||
libmyo_event_get_emg(event, 6), | |||
libmyo_event_get_emg(event, 7) }; | |||
listener->onEmgData(myo, time, emg); | |||
break; | |||
} | |||
case libmyo_event_warmup_completed: { | |||
listener->onWarmupCompleted(myo, time, static_cast<WarmupResult>(libmyo_event_get_warmup_result(event))); | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
inline | |||
void Hub::run(unsigned int duration_ms) | |||
{ | |||
struct local { | |||
static libmyo_handler_result_t handler(void* user_data, libmyo_event_t event) { | |||
Hub* hub = static_cast<Hub*>(user_data); | |||
hub->onDeviceEvent(event); | |||
return libmyo_handler_continue; | |||
} | |||
}; | |||
libmyo_run(_hub, duration_ms, &local::handler, this, ThrowOnError()); | |||
} | |||
inline | |||
void Hub::runOnce(unsigned int duration_ms) | |||
{ | |||
struct local { | |||
static libmyo_handler_result_t handler(void* user_data, libmyo_event_t event) { | |||
Hub* hub = static_cast<Hub*>(user_data); | |||
hub->onDeviceEvent(event); | |||
return libmyo_handler_stop; | |||
} | |||
}; | |||
libmyo_run(_hub, duration_ms, &local::handler, this, ThrowOnError()); | |||
} | |||
inline | |||
libmyo_hub_t Hub::libmyoObject() | |||
{ | |||
return _hub; | |||
} | |||
inline | |||
Myo* Hub::lookupMyo(libmyo_myo_t opaqueMyo) const | |||
{ | |||
Myo* myo = 0; | |||
for (std::vector<Myo*>::const_iterator I = _myos.begin(), IE = _myos.end(); I != IE; ++I) { | |||
if ((*I)->libmyoObject() == opaqueMyo) { | |||
myo = *I; | |||
break; | |||
} | |||
} | |||
return myo; | |||
} | |||
inline | |||
Myo* Hub::addMyo(libmyo_myo_t opaqueMyo) | |||
{ | |||
Myo* myo = new Myo(opaqueMyo); | |||
_myos.push_back(myo); | |||
return myo; | |||
} | |||
} // namespace myo |
@@ -0,0 +1,72 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#include "../Myo.hpp" | |||
#include "../detail/ThrowOnError.hpp" | |||
#include <stdexcept> | |||
namespace myo { | |||
inline | |||
void Myo::vibrate(VibrationType type) | |||
{ | |||
libmyo_vibrate(_myo, static_cast<libmyo_vibration_type_t>(type), ThrowOnError()); | |||
} | |||
inline | |||
void Myo::requestRssi() const | |||
{ | |||
libmyo_request_rssi(_myo, ThrowOnError()); | |||
} | |||
inline | |||
void Myo::requestBatteryLevel() const | |||
{ | |||
libmyo_request_battery_level(_myo, myo::ThrowOnError()); | |||
} | |||
inline | |||
void Myo::unlock(UnlockType type) | |||
{ | |||
libmyo_myo_unlock(_myo, static_cast<libmyo_unlock_type_t>(type), ThrowOnError()); | |||
} | |||
inline | |||
void Myo::lock() | |||
{ | |||
libmyo_myo_lock(_myo, ThrowOnError()); | |||
} | |||
inline | |||
void Myo::notifyUserAction() | |||
{ | |||
libmyo_myo_notify_user_action(_myo, libmyo_user_action_single, ThrowOnError()); | |||
} | |||
inline | |||
void Myo::setStreamEmg(StreamEmgType type) | |||
{ | |||
libmyo_set_stream_emg(_myo, static_cast<libmyo_stream_emg_t>(type), ThrowOnError()); | |||
} | |||
inline | |||
libmyo_myo_t Myo::libmyoObject() const | |||
{ | |||
return _myo; | |||
} | |||
inline | |||
Myo::Myo(libmyo_myo_t myo) | |||
: _myo(myo) | |||
{ | |||
if (!_myo) { | |||
throw std::invalid_argument("Cannot construct Myo instance with null pointer"); | |||
} | |||
} | |||
inline | |||
Myo::~Myo() | |||
{ | |||
} | |||
} // namespace myo |
@@ -0,0 +1,97 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_CXX_IMPL_POSE_IMPL_HPP | |||
#define MYO_CXX_IMPL_POSE_IMPL_HPP | |||
#include "../Pose.hpp" | |||
#include <iostream> | |||
namespace myo { | |||
inline | |||
Pose::Pose() | |||
: _type(unknown) | |||
{ | |||
} | |||
inline | |||
Pose::Pose(Pose::Type type) | |||
: _type(type) | |||
{ | |||
} | |||
inline | |||
bool Pose::operator==(Pose other) const | |||
{ | |||
return _type == other._type; | |||
} | |||
inline | |||
bool Pose::operator!=(Pose other) const | |||
{ | |||
return !(*this == other); | |||
} | |||
inline | |||
Pose::Type Pose::type() const | |||
{ | |||
return _type; | |||
} | |||
inline | |||
bool operator==(Pose pose, Pose::Type type) | |||
{ | |||
return pose.type() == type; | |||
} | |||
inline | |||
bool operator==(Pose::Type type, Pose pose) | |||
{ | |||
return pose == type; | |||
} | |||
inline | |||
bool operator!=(Pose pose, Pose::Type type) | |||
{ | |||
return !(pose == type); | |||
} | |||
inline | |||
bool operator!=(Pose::Type type, Pose pose) | |||
{ | |||
return !(type == pose); | |||
} | |||
inline | |||
std::string Pose::toString() const | |||
{ | |||
switch (type()) { | |||
case Pose::rest: | |||
return "rest"; | |||
case Pose::fist: | |||
return "fist"; | |||
case Pose::waveIn: | |||
return "waveIn"; | |||
case Pose::waveOut: | |||
return "waveOut"; | |||
case Pose::fingersSpread: | |||
return "fingersSpread"; | |||
case Pose::doubleTap: | |||
return "doubleTap"; | |||
case Pose::unknown: | |||
return "unknown"; | |||
} | |||
return "<invalid>"; | |||
} | |||
inline | |||
std::ostream& operator<<(std::ostream& out, const Pose& pose) | |||
{ | |||
return out << pose.toString(); | |||
} | |||
} // namespace myo | |||
#endif // MYO_CXX_IMPL_POSE_IMPL_HPP |
@@ -0,0 +1,425 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_LIBMYO_H | |||
#define MYO_LIBMYO_H | |||
#include <stdint.h> | |||
#include "libmyo/detail/visibility.h" | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/// @file libmyo.h | |||
/// libmyo C API declarations. | |||
typedef void* libmyo_hub_t; | |||
/// \defgroup errors Error Handling | |||
/// @{ | |||
/// Function result codes. | |||
/// All libmyo functions that can fail return a value of this type. | |||
typedef enum { | |||
libmyo_success, | |||
libmyo_error, | |||
libmyo_error_invalid_argument, | |||
libmyo_error_runtime | |||
} libmyo_result_t; | |||
/// Opaque handle to detailed error information. | |||
typedef void* libmyo_error_details_t; | |||
/// Return a null-terminated string with a detailed error message. | |||
LIBMYO_EXPORT | |||
const char* libmyo_error_cstring(libmyo_error_details_t); | |||
/// Returns the kind of error that occurred. | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_error_kind(libmyo_error_details_t); | |||
/// Free the resources allocated by an error object. | |||
LIBMYO_EXPORT | |||
void libmyo_free_error_details(libmyo_error_details_t); | |||
/// @} | |||
/// \defgroup libmyo_string Strings | |||
/// @{ | |||
// Opaque string. | |||
typedef void* libmyo_string_t; | |||
// Return a null-terminated string from the opaque string. | |||
LIBMYO_EXPORT | |||
const char* libmyo_string_c_str(libmyo_string_t); | |||
// Free the resources allocated by the string object. | |||
LIBMYO_EXPORT | |||
void libmyo_string_free(libmyo_string_t); | |||
/// @} | |||
/// \defgroup libmyo_direct_mac_addresses MAC address utilities | |||
/// @{ | |||
/// Retrieve the string representation of a MAC address in hex. | |||
/// Returns a string in the format of 00-00-00-00-00-00. | |||
LIBMYO_EXPORT | |||
libmyo_string_t libmyo_mac_address_to_string(uint64_t); | |||
/// Retrieve the MAC address from a null-terminated string in the format of 00-00-00-00-00-00. | |||
/// Returns 0 if the string does not match the format. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_string_to_mac_address(const char*); | |||
/// @} | |||
/// @defgroup libmyo_hub Hub instance | |||
/// @{ | |||
/// Initialize a connection to the hub. | |||
/// \a application_identifier must follow a reverse domain name format (ex. com.domainname.appname). Application | |||
/// identifiers can be formed from the set of alphanumeric ASCII characters (a-z, A-Z, 0-9). The hyphen (-) and | |||
/// underscore (_) characters are permitted if they are not adjacent to a period (.) character (i.e. not at the start or | |||
/// end of each segment), but are not permitted in the top-level domain. Application identifiers must have three or more | |||
/// segments. For example, if a company's domain is example.com and the application is named hello-world, one could use | |||
/// "com.example.hello-world" as a valid application identifier. \a application_identifier can be NULL or empty. | |||
/// @returns libmyo_success if the connection is successfully established, otherwise: | |||
/// - libmyo_error_runtime if a connection could not be established | |||
/// - libmyo_error_invalid_argument if \a out_hub is NULL | |||
/// - libmyo_error_invalid_argument if \a application_identifier is longer than 255 characters | |||
/// - libmyo_error_invalid_argument if \a application_identifier is not in the proper reverse domain name format | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_init_hub(libmyo_hub_t* out_hub, const char* application_identifier, | |||
libmyo_error_details_t* out_error); | |||
/// Free the resources allocated to a hub. | |||
/// @returns libmyo_success if shutdown is successful, otherwise: | |||
/// - libmyo_error_invalid_argument if \a hub is NULL | |||
/// - libmyo_error if \a hub is not a valid hub | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_shutdown_hub(libmyo_hub_t hub, libmyo_error_details_t* out_error); | |||
// Locking policies. | |||
typedef enum { | |||
libmyo_locking_policy_none, ///< Pose events are always sent. | |||
libmyo_locking_policy_standard ///< Pose events are not sent while a Myo is locked. | |||
} libmyo_locking_policy_t; | |||
/// Set the locking policy for Myos connected to the hub. | |||
/// @returns libmyo_success if the locking policy is successfully set, otherwise | |||
/// - libmyo_error_invalid_argument if \a hub is NULL | |||
/// - libmyo_error if \a hub is not a valid hub | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_set_locking_policy(libmyo_hub_t hub, libmyo_locking_policy_t locking_policy, | |||
libmyo_error_details_t* out_error); | |||
/// @} | |||
/// @defgroup libmyo_myo Myo instances | |||
/// @{ | |||
/// Opaque type corresponding to a known Myo device. | |||
typedef void* libmyo_myo_t; | |||
/// Types of vibration | |||
typedef enum { | |||
libmyo_vibration_short, | |||
libmyo_vibration_medium, | |||
libmyo_vibration_long | |||
} libmyo_vibration_type_t; | |||
/// Retrieve the MAC address of a Myo. | |||
/// The MAC address is unique to the physical Myo, and is a 48-bit number. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_get_mac_address(libmyo_myo_t myo); | |||
/// Vibrate the given myo. | |||
/// Can be called when a Myo is paired. | |||
/// @returns libmyo_success if the Myo successfully vibrated, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_vibrate(libmyo_myo_t myo, libmyo_vibration_type_t type, libmyo_error_details_t* out_error); | |||
/// Request the RSSI for a given myo. | |||
/// Can be called when a Myo is paired. A libmyo_event_rssi event will likely be generated with the value of the RSSI. | |||
/// @returns libmyo_success if the Myo successfully got the RSSI, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_request_rssi(libmyo_myo_t myo, libmyo_error_details_t* out_error); | |||
/// Request the battery level for a given Myo. | |||
/// A libmyo_event_battery_level event will be generated with the value of the battery level. | |||
/// @returns libmyo_success if the Myo successfully requested the battery level, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_request_battery_level(libmyo_myo_t myo_opq, libmyo_error_details_t* out_error); | |||
/// EMG streaming modes. | |||
typedef enum { | |||
libmyo_stream_emg_disabled, ///< Do not send EMG data. | |||
libmyo_stream_emg_enabled ///< Send EMG data. | |||
} libmyo_stream_emg_t; | |||
/// Set whether or not to stream EMG data for a given myo. | |||
/// Can be called when a Myo is paired. | |||
/// @returns libmyo_success if the EMG mode was set successfully, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_set_stream_emg(libmyo_myo_t myo, libmyo_stream_emg_t emg, libmyo_error_details_t* out_error); | |||
/// @} | |||
/// @defgroup libmyo_poses Pose recognition. | |||
/// @{ | |||
/// Supported poses. | |||
typedef enum { | |||
libmyo_pose_rest = 0, ///< Rest pose. | |||
libmyo_pose_fist = 1, ///< User is making a fist. | |||
libmyo_pose_wave_in = 2, ///< User has an open palm rotated towards the posterior of their wrist. | |||
libmyo_pose_wave_out = 3, ///< User has an open palm rotated towards the anterior of their wrist. | |||
libmyo_pose_fingers_spread = 4, ///< User has an open palm with their fingers spread away from each other. | |||
libmyo_pose_double_tap = 5, ///< User tapped their thumb and middle finger together twice in succession. | |||
libmyo_num_poses, ///< Number of poses supported; not a valid pose. | |||
libmyo_pose_unknown = 0xffff ///< Unknown pose. | |||
} libmyo_pose_t; | |||
/// @} | |||
/// @defgroup libmyo_locking Myo locking mechanism | |||
/// Valid unlock types. | |||
typedef enum { | |||
libmyo_unlock_timed = 0, ///< Unlock for a fixed period of time. | |||
libmyo_unlock_hold = 1, ///< Unlock until explicitly told to re-lock. | |||
} libmyo_unlock_type_t; | |||
/// Unlock the given Myo. | |||
/// Can be called when a Myo is paired. A libmyo_event_unlocked event will be generated if the Myo was locked. | |||
/// @returns libmyo_success if the Myo was successfully unlocked, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_myo_unlock(libmyo_myo_t myo, libmyo_unlock_type_t type, libmyo_error_details_t* out_error); | |||
/// Lock the given Myo immediately. | |||
/// Can be called when a Myo is paired. A libmyo_event_locked event will be generated if the Myo was unlocked. | |||
/// @returns libmyo_success if the Myo was successfully locked, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_myo_lock(libmyo_myo_t myo, libmyo_error_details_t* out_error); | |||
/// User action types. | |||
typedef enum { | |||
libmyo_user_action_single = 0, ///< User did a single, discrete action, such as pausing a video. | |||
} libmyo_user_action_type_t; | |||
/// Notify the given Myo that a user action was recognized. | |||
/// Can be called when a Myo is paired. Will cause Myo to vibrate. | |||
/// @returns libmyo_success if the Myo was successfully notified, otherwise | |||
/// - libmyo_error_invalid_argument if \a myo is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_myo_notify_user_action(libmyo_myo_t myo, libmyo_user_action_type_t type, | |||
libmyo_error_details_t* out_error); | |||
/// @} | |||
/// @defgroup libmyo_events Event Handling | |||
/// @{ | |||
/// Types of events. | |||
typedef enum { | |||
libmyo_event_paired, ///< Successfully paired with a Myo. | |||
libmyo_event_unpaired, ///< Successfully unpaired from a Myo. | |||
libmyo_event_connected, ///< A Myo has successfully connected. | |||
libmyo_event_disconnected, ///< A Myo has been disconnected. | |||
libmyo_event_arm_synced, ///< A Myo has recognized that the sync gesture has been successfully performed. | |||
libmyo_event_arm_unsynced, ///< A Myo has been moved or removed from the arm. | |||
libmyo_event_orientation, ///< Orientation data has been received. | |||
libmyo_event_pose, ///< A change in pose has been detected. @see libmyo_pose_t. | |||
libmyo_event_rssi, ///< An RSSI value has been received. | |||
libmyo_event_unlocked, ///< A Myo has become unlocked. | |||
libmyo_event_locked, ///< A Myo has become locked. | |||
libmyo_event_emg, ///< EMG data has been received. | |||
libmyo_event_battery_level, ///< A battery level value has been received. | |||
libmyo_event_warmup_completed, ///< The warmup period has completed. | |||
} libmyo_event_type_t; | |||
/// Information about an event. | |||
typedef const void* libmyo_event_t; | |||
/// Retrieve the type of an event. | |||
LIBMYO_EXPORT | |||
uint32_t libmyo_event_get_type(libmyo_event_t event); | |||
/// Retrieve the timestamp of an event. | |||
/// @see libmyo_now() for details on timestamps. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_event_get_timestamp(libmyo_event_t event); | |||
/// Retrieve the Myo associated with an event. | |||
LIBMYO_EXPORT | |||
libmyo_myo_t libmyo_event_get_myo(libmyo_event_t event); | |||
/// Retrieve the MAC address of the myo associated with an event. | |||
LIBMYO_EXPORT | |||
uint64_t libmyo_event_get_mac_address(libmyo_event_t event_opq); | |||
/// Retrieve the name of the myo associated with an event. | |||
/// Caller must free the returned string. @see libmyo_string functions. | |||
LIBMYO_EXPORT | |||
libmyo_string_t libmyo_event_get_myo_name(libmyo_event_t event); | |||
/// Components of version. | |||
typedef enum { | |||
libmyo_version_major, ///< Major version. | |||
libmyo_version_minor, ///< Minor version. | |||
libmyo_version_patch, ///< Patch version. | |||
libmyo_version_hardware_rev, ///< Hardware revision. | |||
} libmyo_version_component_t; | |||
/// Hardware revisions. | |||
typedef enum { | |||
libmyo_hardware_rev_c = 1, ///< Alpha units | |||
libmyo_hardware_rev_d = 2, ///< Consumer units | |||
} libmyo_hardware_rev_t; | |||
/// Retrieve the Myo armband's firmware version from this event. | |||
/// Valid for libmyo_event_paired and libmyo_event_connected events. | |||
LIBMYO_EXPORT | |||
unsigned int libmyo_event_get_firmware_version(libmyo_event_t event, libmyo_version_component_t); | |||
/// Enumeration identifying a right arm or left arm. @see libmyo_event_get_arm(). | |||
typedef enum { | |||
libmyo_arm_right, ///< Myo is on the right arm. | |||
libmyo_arm_left, ///< Myo is on the left arm. | |||
libmyo_arm_unknown, ///< Unknown arm. | |||
} libmyo_arm_t; | |||
/// Retrieve the arm associated with an event. | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
libmyo_arm_t libmyo_event_get_arm(libmyo_event_t event); | |||
/// Possible directions for Myo's +x axis relative to a user's arm. | |||
typedef enum { | |||
libmyo_x_direction_toward_wrist, ///< Myo's +x axis is pointing toward the user's wrist. | |||
libmyo_x_direction_toward_elbow, ///< Myo's +x axis is pointing toward the user's elbow. | |||
libmyo_x_direction_unknown, ///< Unknown +x axis direction. | |||
} libmyo_x_direction_t; | |||
/// Retrieve the x-direction associated with an event. | |||
/// The x-direction specifies which way Myo's +x axis is pointing relative to the user's arm. | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
libmyo_x_direction_t libmyo_event_get_x_direction(libmyo_event_t event); | |||
/// Possible warmup states for Myo. | |||
typedef enum { | |||
libmyo_warmup_state_unknown = 0, ///< Unknown warm up state. | |||
libmyo_warmup_state_cold = 1, ///< Myo needs to warm up. | |||
libmyo_warmup_state_warm = 2, ///< Myo is already in a warmed up state. | |||
} libmyo_warmup_state_t; | |||
/// Retrieve the warmup state of the Myo associated with an event. | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
libmyo_warmup_state_t libmyo_event_get_warmup_state(libmyo_event_t event); | |||
/// Possible warmup results for Myo. | |||
typedef enum { | |||
libmyo_warmup_result_unknown = 0, ///< Unknown warm up result. | |||
libmyo_warmup_result_success = 1, ///< The warm up period has completed successfully. | |||
libmyo_warmup_result_failed_timeout = 2, ///< The warm up period timed out. | |||
} libmyo_warmup_result_t; | |||
/// Retrieve the warmup result of the Myo associated with an event. | |||
/// Valid for libmyo_event_warmup_completed events only. | |||
LIBMYO_EXPORT | |||
libmyo_warmup_result_t libmyo_event_get_warmup_result(libmyo_event_t event); | |||
/// Retrieve the estimated rotation of Myo on the user's arm after a sync. | |||
/// The values specifies the rotation of the myo on the arm (0 - logo facing down, pi - logo facing up) | |||
/// Only supported by FW 1.3.x and above (older firmware will always report 0 for the rotation) | |||
/// Valid for libmyo_event_arm_synced events only. | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_rotation_on_arm(libmyo_event_t event); | |||
/// Index into orientation data, which is provided as a quaternion. | |||
/// Orientation data is returned as a unit quaternion of floats, represented as `w + x * i + y * j + z * k`. | |||
typedef enum { | |||
libmyo_orientation_x = 0, ///< First component of the quaternion's vector part | |||
libmyo_orientation_y = 1, ///< Second component of the quaternion's vector part | |||
libmyo_orientation_z = 2, ///< Third component of the quaternion's vector part | |||
libmyo_orientation_w = 3, ///< Scalar component of the quaternion. | |||
} libmyo_orientation_index; | |||
/// Retrieve orientation data associated with an event. | |||
/// Valid for libmyo_event_orientation events only. | |||
/// @see libmyo_orientation_index | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_orientation(libmyo_event_t event, libmyo_orientation_index index); | |||
/// Retrieve raw accelerometer data associated with an event in units of g. | |||
/// Valid for libmyo_event_orientation events only. | |||
/// Requires `index < 3`. | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_accelerometer(libmyo_event_t event, unsigned int index); | |||
/// Retrieve raw gyroscope data associated with an event in units of deg/s. | |||
/// Valid for libmyo_event_orientation events only. | |||
/// Requires `index < 3`. | |||
LIBMYO_EXPORT | |||
float libmyo_event_get_gyroscope(libmyo_event_t event, unsigned int index); | |||
/// Retrieve the pose associated with an event. | |||
/// Valid for libmyo_event_pose events only. | |||
LIBMYO_EXPORT | |||
libmyo_pose_t libmyo_event_get_pose(libmyo_event_t event); | |||
/// Retreive the RSSI associated with an event. | |||
/// Valid for libmyo_event_rssi events only. | |||
LIBMYO_EXPORT | |||
int8_t libmyo_event_get_rssi(libmyo_event_t event); | |||
/// Retrieve the battery level of the Myo armband associated with an event. | |||
/// Only valid for libmyo_event_battery_level event. | |||
LIBMYO_EXPORT | |||
uint8_t libmyo_event_get_battery_level(libmyo_event_t event); | |||
/// Retrieve an EMG data point associated with an event. | |||
/// Valid for libmyo_event_emg events only. | |||
/// @a sensor must be smaller than 8. | |||
LIBMYO_EXPORT | |||
int8_t libmyo_event_get_emg(libmyo_event_t event, unsigned int sensor); | |||
/// Return type for event handlers. | |||
typedef enum { | |||
libmyo_handler_continue, ///< Continue processing events | |||
libmyo_handler_stop, ///< Stop processing events | |||
} libmyo_handler_result_t; | |||
/// Callback function type to handle events as they occur from libmyo_run(). | |||
typedef libmyo_handler_result_t (*libmyo_handler_t)(void* user_data, libmyo_event_t event); | |||
/// Process events and call the provided callback as they occur. | |||
/// Runs for up to approximately \a duration_ms milliseconds or until a called handler returns libmyo_handler_stop. | |||
/// @returns libmyo_success after a successful run, otherwise | |||
/// - libmyo_error_invalid_argument if \a hub is NULL | |||
/// - libmyo_error_invalid_argument if \a handler is NULL | |||
LIBMYO_EXPORT | |||
libmyo_result_t libmyo_run(libmyo_hub_t hub, unsigned int duration_ms, libmyo_handler_t handler, void* user_data, | |||
libmyo_error_details_t* out_error); | |||
/// @} | |||
#ifdef __cplusplus | |||
} // extern "C" | |||
#endif | |||
#endif // MYO_LIBMYO_H |
@@ -0,0 +1,32 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#ifndef MYO_LIBMYO_DETAIL_VISIBILITY_H | |||
#define MYO_LIBMYO_DETAIL_VISIBILITY_H | |||
#if defined(_WIN32) || defined(__CYGWIN__) | |||
#ifdef myo_EXPORTS | |||
#ifdef __GNUC__ | |||
#define LIBMYO_EXPORT __attribute__ ((dllexport)) | |||
#else | |||
#define LIBMYO_EXPORT __declspec(dllexport) | |||
#endif | |||
#else | |||
#ifdef LIBMYO_STATIC_BUILD | |||
#define LIBMYO_EXPORT | |||
#else | |||
#ifdef __GNUC__ | |||
#define LIBMYO_EXPORT __attribute__ ((dllimport)) | |||
#else | |||
#define LIBMYO_EXPORT __declspec(dllimport) | |||
#endif | |||
#endif | |||
#endif | |||
#else | |||
#if __GNUC__ >= 4 | |||
#define LIBMYO_EXPORT __attribute__ ((visibility ("default"))) | |||
#else | |||
#define LIBMYO_EXPORT | |||
#endif | |||
#endif | |||
#endif // MYO_LIBMYO_DETAIL_VISIBILITY_H |
@@ -0,0 +1,13 @@ | |||
// Copyright (C) 2013-2014 Thalmic Labs Inc. | |||
// Distributed under the Myo SDK license agreement. See LICENSE.txt for details. | |||
#pragma once | |||
/// The namespace in which all of the %Myo C++ bindings are contained. | |||
namespace myo {} | |||
#include "cxx/DeviceListener.hpp" | |||
#include "cxx/Hub.hpp" | |||
#include "cxx/Myo.hpp" | |||
#include "cxx/Pose.hpp" | |||
#include "cxx/Quaternion.hpp" | |||
#include "cxx/Vector3.hpp" |
@@ -0,0 +1,26 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
<plist version="1.0"> | |||
<dict> | |||
<key>CFBundleDevelopmentRegion</key> | |||
<string>English</string> | |||
<key>CFBundleExecutable</key> | |||
<string>myo</string> | |||
<key>CFBundleIconFile</key> | |||
<string></string> | |||
<key>CFBundleIdentifier</key> | |||
<string></string> | |||
<key>CFBundleInfoDictionaryVersion</key> | |||
<string>6.0</string> | |||
<key>CFBundlePackageType</key> | |||
<string>FMWK</string> | |||
<key>CFBundleSignature</key> | |||
<string>????</string> | |||
<key>CFBundleVersion</key> | |||
<string></string> | |||
<key>CFBundleShortVersionString</key> | |||
<string></string> | |||
<key>CSResourcesFileMapped</key> | |||
<true/> | |||
</dict> | |||
</plist> |
@@ -0,0 +1,167 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
<plist version="1.0"> | |||
<dict> | |||
<key>files</key> | |||
<dict> | |||
<key>Resources/Info.plist</key> | |||
<data> | |||
tUgLZV94WtJ7c7dl1ZQDEnyfe2U= | |||
</data> | |||
</dict> | |||
<key>files2</key> | |||
<dict> | |||
<key>Headers/cxx/DeviceListener.hpp</key> | |||
<data> | |||
5frQIrDj5Rod49qbH8F/ODv03cg= | |||
</data> | |||
<key>Headers/cxx/Hub.hpp</key> | |||
<data> | |||
i2GwmXkJaAf8ZK1boAQLVFA9FuQ= | |||
</data> | |||
<key>Headers/cxx/Myo.hpp</key> | |||
<data> | |||
zkwa8CxGu7CxuY09ncg4cs2C0Ik= | |||
</data> | |||
<key>Headers/cxx/Pose.hpp</key> | |||
<data> | |||
bV/b65asnTpOQVVUseBE2Jks2yY= | |||
</data> | |||
<key>Headers/cxx/Quaternion.hpp</key> | |||
<data> | |||
bvsi/ZwGqVs0ZiHbWPUtsWlsK8k= | |||
</data> | |||
<key>Headers/cxx/Vector3.hpp</key> | |||
<data> | |||
OQUYhjK6FE/MwW8eyy24OtbHO4I= | |||
</data> | |||
<key>Headers/cxx/detail/ThrowOnError.hpp</key> | |||
<data> | |||
ZG7+E/cEH4UadH/3StifiGVjRxE= | |||
</data> | |||
<key>Headers/cxx/impl/Hub_impl.hpp</key> | |||
<data> | |||
jPk/hrtJnF4CumxpYjsOPpHH8PM= | |||
</data> | |||
<key>Headers/cxx/impl/Myo_impl.hpp</key> | |||
<data> | |||
1IleanLjzRkjPeQaDU5tHCnz3+k= | |||
</data> | |||
<key>Headers/cxx/impl/Pose_impl.hpp</key> | |||
<data> | |||
dimtyDcx8DWcpkDi1creWJADmRA= | |||
</data> | |||
<key>Headers/libmyo.h</key> | |||
<data> | |||
0nJ1nA0iCBjWxuXv2VZ2vRHjXnY= | |||
</data> | |||
<key>Headers/libmyo/detail/visibility.h</key> | |||
<data> | |||
dPUWLcemRGRDAJVc1Gonqqzo2K0= | |||
</data> | |||
<key>Headers/myo.hpp</key> | |||
<data> | |||
JeFdPeQ4BqtfHJyJxRiXrDHj6xw= | |||
</data> | |||
<key>Resources/Info.plist</key> | |||
<data> | |||
tUgLZV94WtJ7c7dl1ZQDEnyfe2U= | |||
</data> | |||
</dict> | |||
<key>rules</key> | |||
<dict> | |||
<key>^Resources/</key> | |||
<true/> | |||
<key>^Resources/.*\.lproj/</key> | |||
<dict> | |||
<key>optional</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>1000</real> | |||
</dict> | |||
<key>^Resources/.*\.lproj/locversion.plist$</key> | |||
<dict> | |||
<key>omit</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>1100</real> | |||
</dict> | |||
<key>^version.plist$</key> | |||
<true/> | |||
</dict> | |||
<key>rules2</key> | |||
<dict> | |||
<key>.*\.dSYM($|/)</key> | |||
<dict> | |||
<key>weight</key> | |||
<real>11</real> | |||
</dict> | |||
<key>^(.*/)?\.DS_Store$</key> | |||
<dict> | |||
<key>omit</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>2000</real> | |||
</dict> | |||
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key> | |||
<dict> | |||
<key>nested</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>10</real> | |||
</dict> | |||
<key>^.*</key> | |||
<true/> | |||
<key>^Info\.plist$</key> | |||
<dict> | |||
<key>omit</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>20</real> | |||
</dict> | |||
<key>^PkgInfo$</key> | |||
<dict> | |||
<key>omit</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>20</real> | |||
</dict> | |||
<key>^Resources/</key> | |||
<dict> | |||
<key>weight</key> | |||
<real>20</real> | |||
</dict> | |||
<key>^Resources/.*\.lproj/</key> | |||
<dict> | |||
<key>optional</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>1000</real> | |||
</dict> | |||
<key>^Resources/.*\.lproj/locversion.plist$</key> | |||
<dict> | |||
<key>omit</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>1100</real> | |||
</dict> | |||
<key>^[^/]+$</key> | |||
<dict> | |||
<key>nested</key> | |||
<true/> | |||
<key>weight</key> | |||
<real>10</real> | |||
</dict> | |||
<key>^embedded\.provisionprofile$</key> | |||
<dict> | |||
<key>weight</key> | |||
<real>20</real> | |||
</dict> | |||
<key>^version\.plist$</key> | |||
<dict> | |||
<key>weight</key> | |||
<real>20</real> | |||
</dict> | |||
</dict> | |||
</dict> | |||
</plist> |
@@ -0,0 +1,46 @@ | |||
{ | |||
"patcher" : { | |||
"fileversion" : 1, | |||
"appversion" : { | |||
"major" : 8, | |||
"minor" : 0, | |||
"revision" : 8, | |||
"architecture" : "x64", | |||
"modernui" : 1 | |||
} | |||
, | |||
"classnamespace" : "box", | |||
"rect" : [ 0.0, 0.0, 640.0, 480.0 ], | |||
"bglocked" : 0, | |||
"openinpresentation" : 0, | |||
"default_fontsize" : 12.0, | |||
"default_fontface" : 0, | |||
"default_fontname" : "Arial", | |||
"gridonopen" : 1, | |||
"gridsize" : [ 15.0, 15.0 ], | |||
"gridsnaponopen" : 1, | |||
"objectsnaponopen" : 1, | |||
"statusbarvisible" : 2, | |||
"toolbarvisible" : 1, | |||
"lefttoolbarpinned" : 0, | |||
"toptoolbarpinned" : 0, | |||
"righttoolbarpinned" : 0, | |||
"bottomtoolbarpinned" : 0, | |||
"toolbars_unpinned_last_save" : 0, | |||
"tallnewobj" : 0, | |||
"boxanimatetime" : 200, | |||
"enablehscroll" : 1, | |||
"enablevscroll" : 1, | |||
"devicewidth" : 0.0, | |||
"description" : "", | |||
"digest" : "", | |||
"tags" : "", | |||
"style" : "", | |||
"subpatcher_template" : "", | |||
"boxes" : [ ], | |||
"lines" : [ ], | |||
"dependency_cache" : [ ], | |||
"autosave" : 0 | |||
} | |||
} |