volksbot.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, Osnabrueck University
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * * Neither the name of the Osnabrueck University nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <ros/console.h>
31 
32 #include <algorithm>
33 #include <cmath>
34 #include <cstdio>
35 #include <limits>
36 #include <stdint.h>
37 
38 #include "comm.h"
39 #include "volksbot.h"
40 
42  Comm &comm,
43  double wheel_radius,
44  double axis_length,
45  double turning_adaptation,
46  int gear_ratio,
47  int max_vel_l,
48  int max_vel_r,
49  int max_acc_l,
50  int max_acc_r,
51  bool drive_backwards) :
52  epos2_left_(drive_backwards ? 0x01 : 0x02),
53  epos2_right_(drive_backwards ? 0x02 : 0x01),
54  comm_(comm),
55  wheel_radius_(wheel_radius),
56  axis_length_(axis_length),
57  turning_adaptation_(turning_adaptation),
58  gear_ratio_(gear_ratio),
59  max_vel_l_(max_vel_l),
60  max_vel_r_(max_vel_r),
61  max_acc_l_(max_acc_l),
62  max_acc_r_(max_acc_r)
63 {
64  epos2_left_.init();
65  epos2_right_.init();
66 
67  epos2_left_.enableController();
68  epos2_right_.enableController();
69 
70  epos2_left_.enableMotor(epos2_left_.VELOCITY);
71  epos2_right_.enableMotor(epos2_right_.VELOCITY);
72 
73  epos2_left_.setProfileData(
74  0, // Velocity
75  max_vel_l_, // Max Velocity
76  0, // Acceleration
77  0, // Deceleration
78  0, // QS Decel
79  max_acc_l_, // Max acc
80  0 // Type: Trapecoidal
81  );
82 
83  epos2_right_.setProfileData(
84  0, // Velocity
85  max_vel_r_, // Max Velocity
86  0, // Acceleration
87  0, // Deceleration
88  0, // QS Decel
89  max_acc_r_, // Max acc
90  0 // Type: Trapecoidal
91  );
92 
93  epos2_left_.setOperationMode(epos2_left_.VELOCITY);
94  epos2_right_.setOperationMode(epos2_right_.VELOCITY);
95 }
96 
98 {
99  epos2_left_.setTargetVelocity(0.0);
100  epos2_right_.setTargetVelocity(0.0);
101  epos2_left_.close();
102  epos2_right_.close();
103 }
104 
106  return (max_vel_r_ + max_vel_l_) * M_PI * wheel_radius_ / (60.0 * gear_ratio_);
107 }
108 
109 void Volksbot::set_wheel_speed(double _v_l_soll, double _v_r_soll)
110 {
111  epos2_left_.setTargetVelocity(_v_l_soll / ( 2.0 * M_PI * wheel_radius_) * 60.0 * gear_ratio_);
112  epos2_right_.setTargetVelocity(-1.0 * _v_r_soll / ( 2.0 * M_PI * wheel_radius_) * 60.0 * gear_ratio_);
113 }
114 
116 {
117  static double x = 0.0;
118  static double y = 0.0;
119  static double theta = 0.0;
120  static long enc_left_last = epos2_left_.readEncoderCounter();
121  static long enc_right_last = epos2_right_.readEncoderCounter();
122  static long enc_per_turn_left = 4 * epos2_left_.getEncoderPulseNumber() * gear_ratio_;
123  static long enc_per_turn_right = 4 * epos2_right_.getEncoderPulseNumber() * gear_ratio_;
124 
125  long enc_left = epos2_left_.readEncoderCounter();
126  long enc_right = epos2_right_.readEncoderCounter();
127  long wheel_l = enc_left - enc_left_last;
128  long wheel_r = enc_right - enc_right_last;
129 
130  // handle overflow (> 10000 required to ensure we don't do this on zero crossings)
131  if((abs(enc_left) > 10000) && (std::signbit(enc_left) != std::signbit(enc_left_last)))
132  {
133  if(std::signbit(enc_left))
134  wheel_l = std::numeric_limits<int32_t>::max() - enc_left_last - std::numeric_limits<int32_t>::min() + enc_left;
135  else
136  wheel_l = std::numeric_limits<int32_t>::max() - enc_left - std::numeric_limits<int32_t>::min() + enc_left_last;
137  }
138 
139  if((abs(enc_right) > 10000) && (std::signbit(enc_right) != std::signbit(enc_right_last)))
140  {
141  if(std::signbit(enc_right))
142  wheel_r = std::numeric_limits<int32_t>::max() - enc_right_last - std::numeric_limits<int32_t>::min() + enc_right;
143  else
144  wheel_r = std::numeric_limits<int32_t>::max() - enc_right - std::numeric_limits<int32_t>::min() + enc_right_last;
145  }
146 
147  enc_left_last = enc_left;
148  enc_right_last = enc_right;
149 
150  double wheel_L = 2.0 * M_PI * wheel_radius_ * wheel_l / enc_per_turn_left;
151  double wheel_R = -2.0 * M_PI * wheel_radius_ * wheel_r / enc_per_turn_right;
152 
153  double dtheta = (wheel_R - wheel_L) / axis_length_ * turning_adaptation_;
154  double hypothenuse = 0.5 * (wheel_L + wheel_R);
155 
156  x += hypothenuse * cos(theta + dtheta * 0.5);
157  y += hypothenuse * sin(theta + dtheta * 0.5);
158  theta += dtheta;
159 
160  if (theta > M_PI)
161  theta -= 2.0 * M_PI;
162  if (theta < -M_PI)
163  theta += 2.0 * M_PI;
164 
165  double v_left = epos2_left_.readVelocity() / 60.0 / gear_ratio_ * 2.0 * M_PI * wheel_radius_;
166  double v_right = -epos2_right_.readVelocity() / 60.0 / gear_ratio_ * 2.0 * M_PI * wheel_radius_;
167  double v_x = (v_left + v_right) * 0.5;
168  double v_theta = (v_right - v_left) / axis_length_ * turning_adaptation_;
169 
170  double wheelpos_l = 2.0 * M_PI * (enc_left % enc_per_turn_left) / enc_per_turn_left;
171  if (wheelpos_l > M_PI)
172  wheelpos_l -= 2.0 * M_PI;
173  if (wheelpos_l < -M_PI)
174  wheelpos_l += 2.0 * M_PI;
175 
176  double wheelpos_r = 2.0 * M_PI * (enc_right % enc_per_turn_right) / enc_per_turn_right;
177  if (wheelpos_r > M_PI)
178  wheelpos_r -= 2.0 * M_PI;
179  if (wheelpos_r < -M_PI)
180  wheelpos_r += 2.0 * M_PI;
181 
182  comm_.send_odometry(x, y, theta, v_x, v_theta, wheelpos_l, wheelpos_r);
183 }
int max_vel_l_
Definition: volksbot.h:64
Definition: comm.h:33
int max_acc_l_
Definition: volksbot.h:66
CEpos2 epos2_right_
Definition: volksbot.h:58
TFSIMD_FORCE_INLINE const tfScalar & y() const
double axis_length_
Definition: volksbot.h:61
int max_vel_r_
Definition: volksbot.h:65
~Volksbot()
Definition: volksbot.cpp:97
virtual void send_odometry(double x, double y, double theta, double v_x, double v_theta, double wheelpos_l, double wheelpos_r)=0
double wheel_radius_
Definition: volksbot.h:60
Comm & comm_
Definition: volksbot.h:59
void odometry()
Definition: volksbot.cpp:115
TFSIMD_FORCE_INLINE const tfScalar & x() const
int gear_ratio_
Definition: volksbot.h:63
CEpos2 epos2_left_
Definition: volksbot.h:57
int max_acc_r_
Definition: volksbot.h:67
double turning_adaptation_
Definition: volksbot.h:62
Volksbot(Comm &comm, double wheel_radius, double axis_length, double turning_adaptation, int gear_ratio, int max_vel_l, int max_vel_r, int max_acc_l, int max_acc_r, bool drive_backwards)
Definition: volksbot.cpp:41
double get_max_vel()
Definition: volksbot.cpp:105
void set_wheel_speed(double _v_l_soll, double _v_r_soll)
Definition: volksbot.cpp:109


volksbot_driver
Author(s): Jochen Sprickerhof
autogenerated on Sun Jul 21 2019 04:00:45