# -*- python -*-

load(
    "@drake//attic:build_macros.bzl",
    drake_cc_binary = "attic_drake_cc_binary",
    drake_cc_googletest = "attic_drake_cc_googletest",
    drake_cc_library = "attic_drake_cc_library",
    drake_cc_test = "attic_drake_cc_test",
)
load(
    "@drake//tools/skylark:drake_proto.bzl",
    "drake_cc_proto_library",
)
load("//tools/skylark:test_tags.bzl", "gurobi_test_tags")
load("//tools/lint:lint.bzl", "add_lint_tests")

package(default_visibility = ["//visibility:public"])

drake_cc_library(
    name = "global_inverse_kinematics",
    srcs = [
        "global_inverse_kinematics.cc",
    ],
    hdrs = [
        "global_inverse_kinematics.h",
    ],
    deps = [
        ":rigid_body_tree",
        "//solvers:mathematical_program",
        "//solvers:mixed_integer_rotation_constraint",
        "//solvers:rotation_constraint",
    ],
)

# This library is empty unless Gurobi is available.
# TODO(jwnimmer-tri) Port this to use the MathematicalProgram API, so that this
# code can compile even in the absence of Gurobi, so we can remove select()s.
drake_cc_library(
    name = "approximate_ik",
    srcs = select({
        "//tools:with_gurobi": [
            "approximate_ik.cc",
        ],
        "//conditions:default": [],
    }),
    hdrs = [
        "ik_options.h",
        "rigid_body_ik.h",
    ],
    deps = select({
        "//tools:with_gurobi": [
            ":rigid_body_constraint",
            ":rigid_body_tree",
            "@gurobi//:gurobi_c",
        ],
        "//conditions:default": [],
    }),
)

drake_cc_library(
    name = "kinematics_cache_helper",
    srcs = [
        "kinematics_cache_helper.cc",
    ],
    hdrs = [
        "kinematics_cache_helper.h",
    ],
    deps = [
        ":rigid_body_tree",
    ],
)

drake_cc_library(
    name = "inverse_kinematics",
    srcs = [
        "constraint_wrappers.cc",
        "ik_options.cc",
        "ik_trajectory_helper.cc",
        "inverse_kinematics.cc",
        "inverse_kinematics_backend.cc",
        "inverse_kinematics_pointwise.cc",
        "inverse_kinematics_trajectory.cc",
        "inverse_kinematics_trajectory_backend.cc",
    ],
    hdrs = [
        "constraint_wrappers.h",
        "ik_options.h",
        "ik_trajectory_helper.h",
        "inverse_kinematics_backend.h",
        "rigid_body_ik.h",
    ],
    deps = [
        ":approximate_ik",
        ":kinematics_cache_helper",
        ":rigid_body_constraint",
        ":rigid_body_tree",
        "//common:unused",
        "//math:gradient",
        "//solvers:mathematical_program",
    ],
)

drake_cc_library(
    name = "resolve_center_of_pressure",
    srcs = ["resolve_center_of_pressure.cc"],
    hdrs = ["resolve_center_of_pressure.h"],
    deps = [
        "@eigen",
    ],
)

drake_cc_library(
    name = "rigid_body_constraint",
    srcs = ["rigid_body_constraint.cc"],
    hdrs = ["rigid_body_constraint.h"],
    deps = [
        ":rigid_body_tree",
    ],
)

drake_cc_library(
    name = "kinematics_cache",
    srcs = ["kinematics_cache.cc"],
    hdrs = [
        "kinematics_cache.h",
        "kinematics_cache-inl.h",
    ],
    deps = [
        ":rigid_body_tree_datatypes",
        "//attic/multibody/joints",
        "//common:autodiff",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "rigid_body",
    srcs = ["rigid_body.cc"],
    hdrs = ["rigid_body.h"],
    deps = [
        "//attic/multibody/collision",
        "//attic/multibody/joints",
        "//common:autodiff",
        "//common:essential",
        "//util",
    ],
)

drake_cc_library(
    name = "rigid_body_actuator",
    srcs = ["rigid_body_actuator.cc"],
    hdrs = ["rigid_body_actuator.h"],
    deps = [
        ":rigid_body",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "rigid_body_frame",
    srcs = ["rigid_body_frame.cc"],
    hdrs = ["rigid_body_frame.h"],
    deps = [
        ":rigid_body",
        "//common:autodiff",
        "//common:essential",
        "//math:geometric_transform",
    ],
)

drake_cc_library(
    name = "rigid_body_loop",
    srcs = ["rigid_body_loop.cc"],
    hdrs = ["rigid_body_loop.h"],
    deps = [
        ":rigid_body_frame",
        "//common:autodiff",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "rigid_body_distance_constraint",
    srcs = ["rigid_body_distance_constraint.cc"],
    hdrs = ["rigid_body_distance_constraint.h"],
    deps = [
        "//common:essential",
    ],
)

drake_cc_library(
    name = "rigid_body_tree_datatypes",
    srcs = [],
    hdrs = [
        "force_torque_measurement.h",
        "kinematic_path.h",
        "material_map.h",
        "pose_map.h",
    ],
    visibility = [],
    deps = [
        "//common:essential",
    ],
)

# We compile rigid_body_tree.cc in shards (only a portion of the source code in
# the file is compiled at a time).  See comments in the .cc file for details.
_RBT_SHARD_COUNT = 2

# Define a library for each shard.
[
    drake_cc_library(
        name = "rigid_body_tree_cc_{}".format(i),
        srcs = ["rigid_body_tree.cc".format(i)],
        hdrs = ["rigid_body_tree.h"],
        copts = ["-DDRAKE_RBT_SHARD={}".format(i)],
        visibility = [],
        deps = [
            ":kinematics_cache",
            ":resolve_center_of_pressure",
            ":rigid_body",
            ":rigid_body_actuator",
            ":rigid_body_distance_constraint",
            ":rigid_body_frame",
            ":rigid_body_loop",
            ":rigid_body_tree_datatypes",
            "//attic/multibody/collision",
            "//attic/multibody/joints",
            "//attic/multibody/shapes",
            "//common:autodiff",
            "//common:essential",
            "//math:geometric_transform",
            "//math:gradient",
            "//util",
        ],
    )
    for i in range(_RBT_SHARD_COUNT)
]

# The rigid_body_tree.h implementation is in two files: rigid_body_tree.cc and
# rigid_body_tree_contact.cc.  This is the rule for the first file.
drake_cc_library(
    name = "rigid_body_tree_cc",
    visibility = [],
    deps = [
        ":rigid_body_tree_cc_{}".format(i)  # N.B. Defined immediately above.
        for i in range(_RBT_SHARD_COUNT)
    ],
)

# The rigid_body_tree.h implementation is in two files: rigid_body_tree.cc and
# rigid_body_tree_contact.cc.  This is the rule for the second file.
drake_cc_library(
    name = "rigid_body_tree_contact",
    srcs = ["rigid_body_tree_contact.cc"],
    hdrs = ["rigid_body_tree.h"],
    visibility = [],
    deps = [
        ":kinematics_cache",
        ":rigid_body",
        ":rigid_body_actuator",
        ":rigid_body_distance_constraint",
        ":rigid_body_frame",
        ":rigid_body_loop",
        ":rigid_body_tree_datatypes",
        "//attic/multibody/collision",
        "//attic/multibody/joints",
        "//attic/multibody/shapes",
        "//common:autodiff",
        "//common:essential",
        "//math:geometric_transform",
    ],
)

# This provides a public label for the whole RigidBodyTree.
drake_cc_library(
    name = "rigid_body_tree",
    deps = [
        ":rigid_body_tree_cc",
        ":rigid_body_tree_contact",
    ],
)

drake_cc_library(
    name = "rigid_body_tree_construction",
    srcs = ["rigid_body_tree_construction.cc"],
    hdrs = ["rigid_body_tree_construction.h"],
    deps = [
        ":rigid_body_tree",
    ],
)

drake_cc_library(
    name = "rigid_body_compare_to_clone",
    testonly = 1,
    srcs = ["test/rigid_body_compare_to_clone.cc"],
    hdrs = ["test/rigid_body_compare_to_clone.h"],
    deps = [
        ":rigid_body_tree",
    ],
)

drake_cc_library(
    name = "rigid_body_frame_compare_to_clone",
    testonly = 1,
    srcs = ["test/rigid_body_frame_compare_to_clone.cc"],
    hdrs = ["test/rigid_body_frame_compare_to_clone.h"],
    deps = [
        ":rigid_body_tree",
    ],
)

drake_cc_library(
    name = "rigid_body_tree_compare_to_clone",
    testonly = 1,
    srcs = ["test/rigid_body_tree/rigid_body_tree_compare_to_clone.cc"],
    hdrs = ["test/rigid_body_tree/rigid_body_tree_compare_to_clone.h"],
    deps = [
        ":rigid_body_actuator_compare_to_clone",
        ":rigid_body_compare_to_clone",
        ":rigid_body_frame_compare_to_clone",
        ":rigid_body_loop_compare_to_clone",
        ":rigid_body_tree",
    ],
)

drake_cc_library(
    name = "rigid_body_actuator_compare_to_clone",
    testonly = 1,
    srcs = ["test/rigid_body_actuator_compare_to_clone.cc"],
    hdrs = ["test/rigid_body_actuator_compare_to_clone.h"],
    deps = [
        ":rigid_body_compare_to_clone",
        ":rigid_body_tree",
    ],
)

drake_cc_proto_library(
    name = "rigid_body_tree_alias_groups_proto",
    srcs = [
        "alias_groups.proto",
    ],
    visibility = ["//visibility:private"],
)

drake_cc_library(
    name = "rigid_body_tree_alias_groups",
    srcs = ["rigid_body_tree_alias_groups.cc"],
    hdrs = ["rigid_body_tree_alias_groups.h"],
    deps = [
        ":rigid_body_tree",
        ":rigid_body_tree_alias_groups_proto",
        "//common:essential",
        "//common/proto:protobuf",
    ],
)

drake_cc_library(
    name = "rigid_body_loop_compare_to_clone",
    testonly = 1,
    srcs = ["test/rigid_body_loop_compare_to_clone.cc"],
    hdrs = ["test/rigid_body_loop_compare_to_clone.h"],
    deps = [
        ":rigid_body_frame_compare_to_clone",
        ":rigid_body_tree",
    ],
)

# TODO(jwnimmer-tri) This is just some random program.  Do we want to keep it?
drake_cc_binary(
    name = "benchmark_rigid_body_tree",
    testonly = 1,
    srcs = ["test/benchmark_rigid_body_tree.cc"],
    data = ["//examples/atlas:models"],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:measure_execution",
    ],
)

# TODO(jwnimmer-tri) This is just some random program.  Do we want to keep it?
drake_cc_binary(
    name = "debug_manipulator_dynamics",
    testonly = 1,
    srcs = ["test/debug_manipulator_dynamics.cc"],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
    ],
)

drake_cc_googletest(
    name = "anchored_geometry_test",
    srcs = ["test/rigid_body_tree/anchored_geometry_test.cc"],
    data = [":test_models"],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
    ],
)

drake_cc_googletest(
    name = "ball_joint_test",
    srcs = ["test/rigid_body_tree/ball_joint_test.cc"],
    data = glob(["test/rigid_body_tree/two_link_ball_joint_robot.urdf"]),
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "contact_points_generation_test",
    srcs = ["test/rigid_body_tree/contact_points_generation_test.cc"],
    data = [":test_models"],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
    ],
)

drake_cc_googletest(
    name = "point_collision_detection_test",
    srcs = ["test/rigid_body_tree/point_collision_detection_test.cc"],
    data = [":test_models"],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "rbt_collisions_test",
    srcs = ["test/rigid_body_tree/rbt_collisions_test.cc"],
    data = [":test_models"],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
    ],
)

drake_cc_googletest(
    name = "rigid_body_collision_clique_test",
    srcs = ["test/rigid_body_tree/rigid_body_collision_clique_test.cc"],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
    ],
)

drake_cc_googletest(
    name = "rigid_body_tree_constraint_test",
    srcs = ["test/rigid_body_tree/rigid_body_tree_constraint_test.cc"],
    data = [":test_models"],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "rigid_body_tree_spring_test",
    srcs = ["test/rigid_body_tree/rigid_body_tree_spring_test.cc"],
    data = [":test_models"],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "rigid_body_distance_constraint_test",
    deps = [
        ":rigid_body_distance_constraint",
    ],
)

drake_cc_googletest(
    name = "rigid_body_constraint_test",
    srcs = ["test/rigid_body_constraint_test.cc"],
    data = ["//examples/atlas:models"],
    deps = [
        ":rigid_body_constraint",
        "//attic/multibody/parsers",
        "//common:find_resource",
    ],
)

drake_cc_googletest(
    name = "rigid_body_tree_kinematics_test",
    srcs = ["test/rigid_body_tree/rigid_body_tree_kinematics_test.cc"],
    data = [
        "test/rigid_body_tree/two_dof_robot.urdf",
        "//multibody/benchmarks/acrobot:models",
    ],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
        "//multibody/benchmarks/acrobot:analytical_acrobot",
    ],
)

drake_cc_googletest(
    name = "rigid_body_tree_dynamics_test",
    srcs = ["test/rigid_body_tree/rigid_body_tree_dynamics_test.cc"],
    data = ["//examples/atlas:models"],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
        "//math:jacobian",
    ],
)

drake_cc_googletest(
    name = "rigid_body_tree_clone_test",
    srcs = ["test/rigid_body_tree/rigid_body_tree_clone_test.cc"],
    data = [
        ":test_models",
        "//automotive/models",
        "//examples/atlas:models",
        "//examples/pendulum:models",
        "//examples/valkyrie:models",
    ],
    deps = [
        ":rigid_body_tree_compare_to_clone",
        "//attic/multibody/parsers",
        "//attic/multibody/rigid_body_plant",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
        "//systems/analysis",
        "//systems/primitives:constant_vector_source",
        "//systems/primitives:signal_logger",
    ],
)

drake_cc_googletest(
    name = "rigid_body_tree_completeness_test",
    srcs = ["test/rigid_body_tree/rigid_body_tree_completeness_test.cc"],
    deps = [
        ":rigid_body_tree",
    ],
)

drake_cc_googletest(
    name = "rigid_body_tree_creation_test",
    srcs = ["test/rigid_body_tree/rigid_body_tree_creation_test.cc"],
    data = glob(["test/rigid_body_tree/*.urdf"]),
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities",
    ],
)

drake_cc_googletest(
    name = "rigid_body_tree_face_extraction_test",
    srcs = ["test/rigid_body_tree/rigid_body_tree_face_extraction_test.cc"],
    data = [
        "test/rigid_body_tree/small_sphere_on_large_box.sdf",
    ],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
    ],
)

drake_cc_googletest(
    name = "test_kinematics_cache_checks",
    data = ["//examples/atlas:models"],
    deps = [
        ":rigid_body_tree",
        "//attic/multibody/parsers",
        "//common:find_resource",
    ],
)

drake_cc_googletest(
    name = "test_ik",
    data = [
        "//examples/atlas:models",
        "//manipulation/models/iiwa_description:models",
    ],
    deps = [
        ":inverse_kinematics",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "test_ik_pointwise",
    data = ["//examples/atlas:models"],
    deps = [
        ":inverse_kinematics",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "test_ik_more_constraints",
    data = ["//examples/atlas:models"],
    tags = ["snopt"],
    deps = [
        ":inverse_kinematics",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "test_ik_traj",
    # Test timeout increased to not timeout when run with Valgrind.
    timeout = "moderate",
    data = ["//examples/atlas:models"],
    tags = ["snopt"],
    deps = [
        ":inverse_kinematics",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "rigid_body_test",
    deps = [
        ":rigid_body_compare_to_clone",
        ":rigid_body_tree",
    ],
)

drake_cc_googletest(
    name = "rigid_body_tree_alias_groups_test",
    srcs = ["test/rigid_body_tree_alias_groups_test.cc"],
    data = [
        "test/rigid_body_tree/two_dof_robot.urdf",
        "test/test.alias_groups",
        "//multibody:test_models",
    ],
    deps = [
        ":rigid_body_tree_alias_groups",
        "//attic/multibody/parsers",
        "//common:find_resource",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

# This test is empty unless Gurobi is enabled.
# TODO(jwnimmer-tri) Port this to use the MathematicalProgram API, so that this
# code can compile even in the absence of Gurobi, so we can remove select()s.
drake_cc_googletest(
    name = "test_approximate_ik",
    srcs = select({
        "//tools:with_gurobi": [
            "test/test_approximate_ik.cc",
        ],
        "//conditions:default": [],
    }),
    data = ["//examples/atlas:models"],
    tags = gurobi_test_tags(),
    deps = select({
        "//tools:with_gurobi": [
            ":inverse_kinematics",
            "//common:find_resource",
            "//attic/multibody/parsers",
        ],
        "//conditions:default": [],
    }),
)

filegroup(
    name = "test_models",
    testonly = 1,
    srcs = glob([
        "test/**/*.obj",
        "test/**/*.sdf",
        "test/**/*.urdf",
        "test/**/*.xml",
    ]),
)

# The extra_srcs are required here because add_lint_tests() doesn't understand
# how to extract labels from select() functions yet.
add_lint_tests(
    cpplint_data = ["//attic:CPPLINT.cfg"],
    cpplint_extra_srcs = [
        "approximate_ik.cc",
        "test/test_approximate_ik.cc",
    ],
)
