1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*      File: common.h
 *       This file is part of the program ethercatcpp-shadow
 *       Program description : EtherCAT driver library for shadow hand.
 *       Copyright (C) 2018-2022 -  Robin Passama (CNRS/LIRMM) Arnaud Meline
 * (CNRS/LIRMM) Benjamin Navarro (CNRS/LIRMM). All Right reserved.
 *
 *       This software is free software: you can redistribute it and/or modify
 *       it under the terms of the CeCILL-C license as published by
 *       the CEA CNRS INRIA, either version 1
 *       of the License, or (at your option) any later version.
 *       This software is distributed in the hope that it will be useful,
 *       but WITHOUT ANY WARRANTY without even the implied warranty of
 *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *       CeCILL-C License for more details.
 *
 *       You should have received a copy of the CeCILL-C License
 *       along with this software. If not, it can be found on the official
 * website of the CeCILL licenses family (http://www.cecill.info/index.en.html).
 */
/**
 * @file ethercatcpp/shadow/common.h
 * @author Benjamin Navarro (original author, refactoring)
 * @author Robin Passama (refactoring)
 * @brief types needed to describe a shadow hand
 * @copyright Copyright (c) 2020-2022
 * @ingroup ethercatcpp-shadow
 */
#pragma once

#include <cstdint>
#include <array>

namespace ethercatcpp::shadow {

// Number of motors in shadow hand
constexpr int NUM_MOTORS = 20;
// Number of ADC sensors in the robot.
constexpr int SENSORS_NUM_0220 = 36;
// Number of ADC positions sensors (0..25)
constexpr int POSITION_SENSOR_NUM = 26;

//! \brief Describes the hand type: right or left
//!
enum class HandType { Right, Left };

//! \brief List of known Shadow hands with their respective serial number
//!
enum class HandID {
    LirmmRight,
    LirmmLeft,
    Count //!< Keep at the end
};

//! \brief List of serial numbers corresponding to HandIDs
//!
constexpr std::array<uint32_t, static_cast<int>(HandID::Count)>
    hand_serial_numbers = {
        842, // LirmmRight
        858  // LirmmLeft
};

//! \brief List of hand types corresponding to HandIDs
//!
constexpr std::array<HandType, static_cast<int>(HandID::Count)> hand_types = {
    HandType::Right, // LirmmRight
    HandType::Left   // LirmmLeft
};

//! \brief Describes the Biotac working mode: with or without the electrodes
//!
enum class BiotacMode {
    WithElectrodes,   //!< Electrodes datas are updated
    WithoutElectrodes //!< Only presure and temperature are updated
};

//! \brief Describes the hand control mode: torque or direct PWM motor control
//!
enum class ControlMode { Torque, PWM };

//! \brief All raw pressure measurements given by a Biotac
//!
struct BiotacPressures {
    int16_t Pac0{0}; //!< First mesured dynamics presures<--- struct member 'BiotacPressures::Pac0' is never used.
    int16_t Pac1{0}; //!< Second mesured dynamics presures<--- struct member 'BiotacPressures::Pac1' is never used.
    int16_t Pdc{0};  //!< Mesured presure<--- struct member 'BiotacPressures::Pdc' is never used.
};

//! \brief All raw temperature measurements given by a Biotac
//!
struct BiotacTemperatures {
    int16_t Tac{0}; //!< Mesured dynamics temperature<--- struct member 'BiotacTemperatures::Tac' is never used.
    int16_t Tdc{0}; //!< Mesured temperature<--- struct member 'BiotacTemperatures::Tdc' is never used.
};

//! \brief All raw impedance electrodes measurements given by a Biotac
//!
struct BiotacElectrodes : public std::array<int16_t, 19> {
    BiotacElectrodes() {
        fill(0);
    }
};

//! \brief Shadow hand joint names
//!
//! Assumes a hand with Biotac sensors eliminating FFJ1, MFJ1, RFJ1, LFJ1 and
//! THJ1 joints
//!
enum class JointNames {
    FFJ4,
    FFJ3,
    FFJ2,
    MFJ4,
    MFJ3,
    MFJ2,
    RFJ4,
    RFJ3,
    RFJ2,
    LFJ5,
    LFJ4,
    LFJ3,
    LFJ2,
    THJ5,
    THJ4,
    THJ3,
    THJ2,
    WRJ2,
    WRJ1,
};

//! \brief All available joints groups on a Shadow hand
//!
enum class JointGroupsNames {
    FirstFinger,
    MiddleFinger,
    RingFinger,
    LittleFinger,
    Thumb,
    Wrist
};

constexpr std::size_t first_finger_joint_count = 3;
constexpr std::size_t middle_finger_joint_count = 3;
constexpr std::size_t ring_finger_joint_count = 3;
constexpr std::size_t little_finger_joint_count = 4;
constexpr std::size_t thumb_finger_joint_count = 4;
constexpr std::size_t wrist_joint_count = 2;
constexpr std::size_t joint_count =
    first_finger_joint_count + middle_finger_joint_count +
    ring_finger_joint_count + little_finger_joint_count +
    thumb_finger_joint_count + wrist_joint_count;
constexpr std::size_t joint_groups_count = 6;
constexpr std::size_t biotac_count = 5;

constexpr std::array<const char*, joint_count> joint_names{
    "FFJ4", "FFJ3", "FFJ2", "MFJ4", "MFJ3", "MFJ2", "RFJ4",
    "RFJ3", "RFJ2", "LFJ5", "LFJ4", "LFJ3", "LFJ2", "THJ5",
    "THJ4", "THJ3", "THJ2", "WRJ2", "WRJ1"};

constexpr std::array<const char*, joint_groups_count> joint_groups_names{
    "FirstFinger",  "MiddleFinger", "RingFinger",
    "LittleFinger", "Thumb",        "Wrist"};

constexpr std::size_t index_of(JointNames name) {
    return static_cast<std::size_t>(name);
}

constexpr std::size_t index_of(JointGroupsNames name) {
    return static_cast<std::size_t>(name);
}

constexpr std::size_t index_of(HandID id) {
    return static_cast<std::size_t>(id);
}

struct RawHandState {
    RawHandState() {
        joint_torques.fill(0);
        raw_joint_positions.fill(0);
        joint_positions.fill(0.);
        biotac_presures.fill(BiotacPressures{});
        biotac_temperatures.fill(BiotacTemperatures{});
        biotac_electrodes.fill(BiotacElectrodes{});
    }

    std::array<int16_t, joint_count> joint_torques;
    std::array<uint16_t, joint_count> raw_joint_positions;
    std::array<double, joint_count> joint_positions;
    std::array<BiotacPressures, biotac_count> biotac_presures;
    std::array<BiotacTemperatures, biotac_count> biotac_temperatures;
    std::array<BiotacElectrodes, biotac_count> biotac_electrodes;
};

struct RawHandCommand {
    explicit RawHandCommand(ControlMode mode) : control_mode{mode} {
        joint_torques.fill(0);
        joint_pwm.fill(0);
    }

    ControlMode control_mode;
    std::array<int16_t, joint_count> joint_torques;
    std::array<int16_t, joint_count> joint_pwm;
};

} // namespace ethercatcpp::shadow